Skip to content

Commit 9011e13

Browse files
author
Robert Marsh
committed
C++: handle conversions in IR to AST translation
1 parent cc97cf9 commit 9011e13

File tree

7 files changed

+65
-29
lines changed

7 files changed

+65
-29
lines changed

cpp/ql/src/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import semmle.code.cpp.ir.IR
77
*/
88
class GuardCondition extends Expr {
99
GuardCondition() {
10-
exists(IRGuardCondition ir | this = remove_conversions(ir.getAST()))
10+
exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression())
1111
or
1212
// no binary operators in the IR
1313
exists(Instruction ir |
@@ -157,7 +157,7 @@ private class GuardConditionFromIR extends GuardCondition {
157157
IRGuardCondition ir;
158158

159159
GuardConditionFromIR() {
160-
this = remove_conversions(ir.getAST())
160+
this = ir.getUnconvertedResultExpression()
161161
}
162162
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
163163
/* This condition must determine the flow of control; that is, this
@@ -168,8 +168,8 @@ private class GuardConditionFromIR extends GuardCondition {
168168
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
169169
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
170170
exists(Instruction li, Instruction ri |
171-
remove_conversions(li.getAST()) = left and
172-
remove_conversions(ri.getAST()) = right and
171+
li.getUnconvertedResultExpression() = left and
172+
ri.getUnconvertedResultExpression() = right and
173173
ir.comparesLt(li, ri, k, isLessThan, testIsTrue)
174174
)
175175
}
@@ -178,8 +178,8 @@ private class GuardConditionFromIR extends GuardCondition {
178178
If `isLessThan = false` then this implies `left >= right + k`. */
179179
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
180180
exists(Instruction li, Instruction ri, boolean testIsTrue |
181-
remove_conversions(li.getAST()) = left and
182-
remove_conversions(ri.getAST()) = right and
181+
li.getUnconvertedResultExpression() = left and
182+
ri.getUnconvertedResultExpression() = right and
183183
ir.comparesLt(li, ri, k, isLessThan, testIsTrue) and
184184
this.controls(block, testIsTrue)
185185
)
@@ -188,8 +188,8 @@ private class GuardConditionFromIR extends GuardCondition {
188188
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
189189
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
190190
exists(Instruction li, Instruction ri |
191-
remove_conversions(li.getAST()) = left and
192-
remove_conversions(ri.getAST()) = right and
191+
li.getUnconvertedResultExpression() = left and
192+
ri.getUnconvertedResultExpression() = right and
193193
ir.comparesEq(li, ri, k, areEqual, testIsTrue)
194194
)
195195
}
@@ -198,8 +198,8 @@ private class GuardConditionFromIR extends GuardCondition {
198198
If `areEqual = false` then this implies `left != right + k`. */
199199
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
200200
exists(Instruction li, Instruction ri, boolean testIsTrue |
201-
remove_conversions(li.getAST()) = left and
202-
remove_conversions(ri.getAST()) = right and
201+
li.getUnconvertedResultExpression() = left and
202+
ri.getUnconvertedResultExpression() = right and
203203
ir.comparesEq(li, ri, k, areEqual, testIsTrue)
204204
and this.controls(block, testIsTrue)
205205
)
@@ -482,11 +482,3 @@ private predicate add_eq(CompareInstruction cmp, Instruction left, Instruction r
482482
private int int_value(Instruction i) {
483483
result = i.(IntegerConstantInstruction).getValue().toInt()
484484
}
485-
486-
/** Gets the underlying expression of `e`. */
487-
private Expr remove_conversions(Expr e) {
488-
if e instanceof Conversion
489-
then result = e.(Conversion).getExpr+() and
490-
not result instanceof Conversion
491-
else result = e
492-
}

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,17 @@ class Instruction extends Construction::TInstruction {
312312
/**
313313
* Gets the `Expr` whose results is computed by this instruction, if any.
314314
*/
315-
final Expr getResultExpression() {
316-
result = Construction::getInstructionResultExpression(this)
315+
final Expr getConvertedResultExpression() {
316+
result = Construction::getInstructionConvertedResultExpression(this)
317317
}
318+
319+
/**
320+
* Gets the `Expr` whose results is computed by this instruction, if any.
321+
*/
322+
final Expr getUnconvertedResultExpression() {
323+
result = Construction::getInstructionUnconvertedResultExpression(this)
324+
}
325+
318326

319327
/**
320328
* Gets the type of the result produced by this instruction. If the

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,12 @@ cached private module Cached {
197197
)
198198
}
199199

200-
cached Expr getInstructionResultExpression(Instruction instruction) {
201-
result = getOldInstruction(instruction).getResultExpression()
200+
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
201+
result = getOldInstruction(instruction).getConvertedResultExpression()
202+
}
203+
204+
cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
205+
result = getOldInstruction(instruction).getUnconvertedResultExpression()
202206
}
203207

204208
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,17 @@ class Instruction extends Construction::TInstruction {
312312
/**
313313
* Gets the `Expr` whose results is computed by this instruction, if any.
314314
*/
315-
final Expr getResultExpression() {
316-
result = Construction::getInstructionResultExpression(this)
315+
final Expr getConvertedResultExpression() {
316+
result = Construction::getInstructionConvertedResultExpression(this)
317317
}
318+
319+
/**
320+
* Gets the `Expr` whose results is computed by this instruction, if any.
321+
*/
322+
final Expr getUnconvertedResultExpression() {
323+
result = Construction::getInstructionUnconvertedResultExpression(this)
324+
}
325+
318326

319327
/**
320328
* Gets the type of the result produced by this instruction. If the

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,25 @@ cached private module Cached {
7474
none()
7575
}
7676

77-
cached Expr getInstructionResultExpression(Instruction instruction) {
77+
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
7878
exists(TranslatedExpr translatedExpr |
7979
translatedExpr = getTranslatedExpr(result) and
8080
instruction = translatedExpr.getResult()
8181
)
8282
}
8383

84+
cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
85+
exists(Expr converted, TranslatedExpr translatedExpr |
86+
result = converted.(Conversion).getExpr+()
87+
or
88+
result = converted
89+
|
90+
not result instanceof Conversion and
91+
translatedExpr = getTranslatedExpr(converted) and
92+
instruction = translatedExpr.getResult()
93+
)
94+
}
95+
8496
cached Instruction getInstructionOperand(Instruction instruction, OperandTag tag) {
8597
result = getInstructionTranslatedElement(instruction).getInstructionOperand(
8698
instruction.getTag(), tag)

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,17 @@ class Instruction extends Construction::TInstruction {
312312
/**
313313
* Gets the `Expr` whose results is computed by this instruction, if any.
314314
*/
315-
final Expr getResultExpression() {
316-
result = Construction::getInstructionResultExpression(this)
315+
final Expr getConvertedResultExpression() {
316+
result = Construction::getInstructionConvertedResultExpression(this)
317317
}
318+
319+
/**
320+
* Gets the `Expr` whose results is computed by this instruction, if any.
321+
*/
322+
final Expr getUnconvertedResultExpression() {
323+
result = Construction::getInstructionUnconvertedResultExpression(this)
324+
}
325+
318326

319327
/**
320328
* Gets the type of the result produced by this instruction. If the

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,12 @@ cached private module Cached {
197197
)
198198
}
199199

200-
cached Expr getInstructionResultExpression(Instruction instruction) {
201-
result = getOldInstruction(instruction).getResultExpression()
200+
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
201+
result = getOldInstruction(instruction).getConvertedResultExpression()
202+
}
203+
204+
cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
205+
result = getOldInstruction(instruction).getUnconvertedResultExpression()
202206
}
203207

204208
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {

0 commit comments

Comments
 (0)