Skip to content

Commit 4cc3bfa

Browse files
committed
C++: Fix places that assumed that 'Expr' was always 'Instruction'.
1 parent 08e8604 commit 4cc3bfa

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

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

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ module SemanticExprConfig {
105105
SemBasicBlock getExprBasicBlock(Expr e) { result = getSemanticBasicBlock(e.getBlock()) }
106106

107107
private predicate anyConstantExpr(Expr expr, SemType type, string value) {
108-
exists(IR::ConstantInstruction instr | instr = expr |
108+
exists(IR::ConstantInstruction instr | getSemanticExpr(instr) = expr |
109109
type = getSemanticType(instr.getResultIRType()) and
110110
value = instr.getValue()
111111
)
@@ -146,41 +146,46 @@ module SemanticExprConfig {
146146
predicate nullLiteral(Expr expr, SemAddressType type) { anyConstantExpr(expr, type, _) }
147147

148148
predicate stringLiteral(Expr expr, SemType type, string value) {
149-
anyConstantExpr(expr, type, value) and expr instanceof IR::StringConstantInstruction
149+
anyConstantExpr(expr, type, value) and
150+
expr.getUnconverted() instanceof IR::StringConstantInstruction
150151
}
151152

152153
predicate binaryExpr(Expr expr, Opcode opcode, SemType type, Expr leftOperand, Expr rightOperand) {
153-
exists(IR::BinaryInstruction instr | instr = expr |
154+
exists(IR::BinaryInstruction instr |
155+
instr = expr.getUnconverted() and
154156
type = getSemanticType(instr.getResultIRType()) and
155-
leftOperand = instr.getLeft() and
156-
rightOperand = instr.getRight() and
157+
leftOperand = getSemanticExpr(instr.getLeft()) and
158+
rightOperand = getSemanticExpr(instr.getRight()) and
157159
// REVIEW: Merge the two `Opcode` types.
158160
opcode.toString() = instr.getOpcode().toString()
159161
)
160162
}
161163

162164
predicate unaryExpr(Expr expr, Opcode opcode, SemType type, Expr operand) {
163-
type = getSemanticType(expr.getResultIRType()) and
164-
(
165-
exists(IR::UnaryInstruction instr | instr = expr |
166-
operand = instr.getUnary() and
167-
// REVIEW: Merge the two operand types.
168-
opcode.toString() = instr.getOpcode().toString()
169-
)
170-
or
171-
exists(IR::StoreInstruction instr | instr = expr |
172-
operand = instr.getSourceValue() and
173-
opcode instanceof Opcode::Store
174-
)
165+
exists(IR::UnaryInstruction instr | instr = expr.getUnconverted() |
166+
type = getSemanticType(instr.getResultIRType()) and
167+
operand = getSemanticExpr(instr.getUnary()) and
168+
// REVIEW: Merge the two operand types.
169+
opcode.toString() = instr.getOpcode().toString()
170+
)
171+
or
172+
exists(IR::StoreInstruction instr | instr = expr.getUnconverted() |
173+
type = getSemanticType(instr.getResultIRType()) and
174+
operand = getSemanticExpr(instr.getSourceValue()) and
175+
opcode instanceof Opcode::Store
175176
)
176177
}
177178

178179
predicate nullaryExpr(Expr expr, Opcode opcode, SemType type) {
179-
type = getSemanticType(expr.getResultIRType()) and
180-
(
181-
expr instanceof IR::LoadInstruction and opcode instanceof Opcode::Load
182-
or
183-
expr instanceof IR::InitializeParameterInstruction and
180+
exists(IR::LoadInstruction load |
181+
load = expr.getUnconverted() and
182+
type = getSemanticType(load.getResultIRType()) and
183+
opcode instanceof Opcode::Load
184+
)
185+
or
186+
exists(IR::InitializeParameterInstruction init |
187+
init = expr.getUnconverted() and
188+
type = getSemanticType(init.getResultIRType()) and
184189
opcode instanceof Opcode::InitializeParameter
185190
)
186191
}
@@ -267,7 +272,9 @@ module SemanticExprConfig {
267272
final override IR::Operand asOperand() { result = op }
268273
}
269274

270-
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) { v.asInstruction() = sourceExpr }
275+
predicate explicitUpdate(SsaVariable v, Expr sourceExpr) {
276+
getSemanticExpr(v.asInstruction()) = sourceExpr
277+
}
271278

272279
predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction }
273280

@@ -280,9 +287,9 @@ module SemanticExprConfig {
280287
}
281288

282289
Expr getAUse(SsaVariable v) {
283-
result.(IR::LoadInstruction).getSourceValue() = v.asInstruction()
290+
result.getUnconverted().(IR::LoadInstruction).getSourceValue() = v.asInstruction()
284291
or
285-
result = valueNumber(v.asPointerArithGuard()).getAnInstruction()
292+
result.getUnconverted() = valueNumber(v.asPointerArithGuard()).getAnInstruction()
286293
}
287294

288295
SemType getSsaVariableType(SsaVariable v) {
@@ -391,17 +398,21 @@ module SemanticExprConfig {
391398
}
392399

393400
Expr getBoundExpr(Bound bound, int delta) {
394-
result = bound.(IRBound::Bound).getInstruction(delta)
401+
result = getSemanticExpr(bound.(IRBound::Bound).getInstruction(delta))
395402
}
396403

397404
class Guard = IRGuards::IRGuardCondition;
398405

399406
predicate guard(Guard guard, BasicBlock block) { block = guard.getBlock() }
400407

401-
Expr getGuardAsExpr(Guard guard) { result = guard }
408+
Expr getGuardAsExpr(Guard guard) { result = getSemanticExpr(guard) }
402409

403410
predicate equalityGuard(Guard guard, Expr e1, Expr e2, boolean polarity) {
404-
guard.comparesEq(e1.getAUse(), e2.getAUse(), 0, true, polarity)
411+
exists(IR::Instruction left, IR::Instruction right |
412+
getSemanticExpr(left) = e1 and
413+
getSemanticExpr(right) = e2 and
414+
guard.comparesEq(left.getAUse(), right.getAUse(), 0, true, polarity)
415+
)
405416
}
406417

407418
predicate guardDirectlyControlsBlock(Guard guard, BasicBlock controlled, boolean branch) {
@@ -412,16 +423,17 @@ module SemanticExprConfig {
412423
guard.controlsEdge(bb1, bb2, branch)
413424
}
414425

415-
Guard comparisonGuard(Expr e) { result = e }
426+
Guard comparisonGuard(Expr e) { getSemanticExpr(result) = e }
416427

417428
predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) {
418429
none() // TODO
419430
}
420-
}
421431

422-
SemExpr getSemanticExpr(IR::Instruction instr) { result = instr }
432+
/** Gets the expression associated with `instr`. */
433+
SemExpr getSemanticExpr(IR::Instruction instr) { result = Equiv::getEquivalenceClass(instr) }
434+
}
423435

424-
IR::Instruction getCppInstruction(SemExpr e) { e = result }
436+
predicate getSemanticExpr = SemanticExprConfig::getSemanticExpr/1;
425437

426438
SemBasicBlock getSemanticBasicBlock(IR::IRBlock block) { result = block }
427439

cpp/ql/test/library-tests/ir/range-analysis/RangeAnalysis.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class RangeAnalysisTest extends InlineExpectationsTest {
1212

1313
override predicate hasActualResult(Location location, string element, string tag, string value) {
1414
exists(SemExpr e, IR::CallInstruction call |
15-
call.getArgument(0) = e and
15+
getSemanticExpr(call.getArgument(0)) = e and
1616
call.getStaticCallTarget().hasName("range") and
1717
tag = "range" and
1818
element = e.toString() and

cpp/ql/test/library-tests/ir/sign-analysis/SignAnalysis.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import experimental.semmle.code.cpp.semantic.Semantic
44
import experimental.semmle.code.cpp.semantic.analysis.RangeUtils
55
import experimental.semmle.code.cpp.semantic.analysis.FloatDelta
66
import experimental.semmle.code.cpp.semantic.analysis.RangeAnalysisSpecific
7+
import experimental.semmle.code.cpp.semantic.SemanticExprSpecific
78
import semmle.code.cpp.ir.IR as IR
89
import TestUtilities.InlineExpectationsTest
910

@@ -16,7 +17,7 @@ class SignAnalysisTest extends InlineExpectationsTest {
1617

1718
override predicate hasActualResult(Location location, string element, string tag, string value) {
1819
exists(SemExpr e, IR::CallInstruction call |
19-
call.getArgument(0) = e and
20+
getSemanticExpr(call.getArgument(0)) = e and
2021
call.getStaticCallTarget().hasName("sign") and
2122
tag = "sign" and
2223
element = e.toString() and

0 commit comments

Comments
 (0)