Skip to content

Commit 6564351

Browse files
committed
C++: inexact memory operands as SSA variables
This makes inexact memory operands into their own SSA variables in the Semantic interface, which resolves an issue with phi nodes losing inexact operands (e.g. the unknown-size variable for parameter indirections).
1 parent 3bbd333 commit 6564351

File tree

1 file changed

+70
-21
lines changed

1 file changed

+70
-21
lines changed

cpp/ql/lib/experimental/semmle/code/cpp/semantic/SemanticExprSpecific.qll

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -119,27 +119,67 @@ module SemanticExprConfig {
119119
result = block.getDisplayIndex()
120120
}
121121

122-
class SsaVariable instanceof IR::Instruction {
123-
SsaVariable() { super.hasMemoryResult() }
122+
newtype TSsaVariable =
123+
TSsaInstruction(IR::Instruction instr) { instr.hasMemoryResult() } or
124+
TSsaOperand(IR::Operand op) { op.isDefinitionInexact() }
124125

125-
final string toString() { result = super.toString() }
126+
class SsaVariable extends TSsaVariable {
127+
string toString() { none() }
126128

127-
final Location getLocation() { result = super.getLocation() }
129+
Location getLocation() { none() }
130+
131+
IR::Instruction asInstruction() { none() }
132+
133+
IR::Operand asOperand() { none() }
134+
}
135+
136+
class SsaInstructionVariable extends SsaVariable, TSsaInstruction {
137+
IR::Instruction instr;
138+
139+
SsaInstructionVariable() { this = TSsaInstruction(instr) }
140+
141+
final override string toString() { result = instr.toString() }
142+
143+
final override Location getLocation() { result = instr.getLocation() }
144+
145+
final override IR::Instruction asInstruction() { result = instr }
146+
}
147+
148+
class SsaOperand extends SsaVariable, TSsaOperand {
149+
IR::Operand op;
150+
151+
SsaOperand() { this = TSsaOperand(op) }
152+
153+
final override string toString() { result = op.toString() }
154+
155+
final override Location getLocation() { result = op.getLocation() }
156+
157+
final override IR::Operand asOperand() { result = op }
128158
}
129159

130-
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v = sourceExpr }
160+
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr }
131161

132-
predicate phi(SsaVariable v) { v instanceof IR::PhiInstruction }
162+
predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction }
133163

134-
SsaVariable getAPhiInput(SsaVariable v) { result = v.(IR::PhiInstruction).getAnInput() }
164+
SsaVariable getAPhiInput(SsaVariable v) {
165+
exists(IR::PhiInstruction instr |
166+
result.asInstruction() = instr.getAnInput()
167+
or
168+
result.asOperand() = instr.getAnInputOperand()
169+
)
170+
}
135171

136-
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v }
172+
Expr getAUse(SsaVariable v) { result.(IR::LoadInstruction).getSourceValue() = v.asInstruction() }
137173

138174
SemType getSsaVariableType(SsaVariable v) {
139-
result = getSemanticType(v.(IR::Instruction).getResultIRType())
175+
result = getSemanticType(v.asInstruction().getResultIRType())
140176
}
141177

142-
BasicBlock getSsaVariableBasicBlock(SsaVariable v) { result = v.(IR::Instruction).getBlock() }
178+
BasicBlock getSsaVariableBasicBlock(SsaVariable v) {
179+
result = v.asInstruction().getBlock()
180+
or
181+
result = v.asOperand().getUse().getBlock()
182+
}
143183

144184
private newtype TReadPosition =
145185
TReadPositionBlock(IR::IRBlock block) or
@@ -169,7 +209,7 @@ module SemanticExprConfig {
169209

170210
final override predicate hasRead(SsaVariable v) {
171211
exists(IR::Operand operand |
172-
operand.getDef() = v and
212+
operand.getDef() = v.asInstruction() and
173213
not operand instanceof IR::PhiInputOperand and
174214
operand.getUse().getBlock() = block
175215
)
@@ -188,7 +228,7 @@ module SemanticExprConfig {
188228

189229
final override predicate hasRead(SsaVariable v) {
190230
exists(IR::PhiInputOperand operand |
191-
operand.getDef() = v and
231+
operand.getDef() = v.asInstruction() and
192232
operand.getPredecessorBlock() = pred and
193233
operand.getUse().getBlock() = succ
194234
)
@@ -207,7 +247,12 @@ module SemanticExprConfig {
207247
exists(IR::PhiInputOperand operand |
208248
pos = TReadPositionPhiInputEdge(operand.getPredecessorBlock(), operand.getUse().getBlock())
209249
|
210-
phi = operand.getUse() and input = operand.getDef()
250+
phi.asInstruction() = operand.getUse() and
251+
(
252+
input.asInstruction() = operand.getDef()
253+
or
254+
input.asOperand() = operand
255+
)
211256
)
212257
}
213258

@@ -224,21 +269,21 @@ module SemanticExprConfig {
224269

225270
override string toString() {
226271
result =
227-
min(SsaVariable instr |
228-
instr = bound.getValueNumber().getAnInstruction()
272+
min(SsaVariable v |
273+
v.asInstruction() = bound.getValueNumber().getAnInstruction()
229274
|
230-
instr
275+
v
231276
order by
232-
instr.(IR::Instruction).getBlock().getDisplayIndex(),
233-
instr.(IR::Instruction).getDisplayIndexInBlock()
277+
v.asInstruction().getBlock().getDisplayIndex(),
278+
v.asInstruction().getDisplayIndexInBlock()
234279
).toString()
235280
}
236281
}
237282

238283
predicate zeroBound(Bound bound) { bound instanceof IRBound::ZeroBound }
239284

240285
predicate ssaBound(Bound bound, SsaVariable v) {
241-
v = bound.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction()
286+
v.asInstruction() = bound.(IRBound::ValueNumberBound).getValueNumber().getAnInstruction()
242287
}
243288

244289
Expr getBoundExpr(Bound bound, int delta) {
@@ -280,9 +325,13 @@ SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block }
280325

281326
IR::IRBlock getCppBasicBlock(SemBasicBlock block) { block = result }
282327

283-
SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) { result = instr }
328+
SemSsaVariable getSemanticSsaVariable(IR::Instruction instr) {
329+
result.(SemanticExprConfig::SsaVariable).asInstruction() = instr
330+
}
284331

285-
IR::Instruction getCppSsaVariableInstruction(SemSsaVariable v) { v = result }
332+
IR::Instruction getCppSsaVariableInstruction(SemSsaVariable var) {
333+
var.(SemanticExprConfig::SsaVariable).asInstruction() = result
334+
}
286335

287336
SemBound getSemanticBound(IRBound::Bound bound) { result = bound }
288337

0 commit comments

Comments
 (0)