C++: handle conversions in IR to AST translation

This commit is contained in:
Robert Marsh
2018-09-20 12:56:43 -07:00
parent cc97cf9297
commit 9011e1381b
7 changed files with 65 additions and 29 deletions

View File

@@ -7,7 +7,7 @@ import semmle.code.cpp.ir.IR
*/
class GuardCondition extends Expr {
GuardCondition() {
exists(IRGuardCondition ir | this = remove_conversions(ir.getAST()))
exists(IRGuardCondition ir | this = ir.getUnconvertedResultExpression())
or
// no binary operators in the IR
exists(Instruction ir |
@@ -157,7 +157,7 @@ private class GuardConditionFromIR extends GuardCondition {
IRGuardCondition ir;
GuardConditionFromIR() {
this = remove_conversions(ir.getAST())
this = ir.getUnconvertedResultExpression()
}
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
/* This condition must determine the flow of control; that is, this
@@ -168,8 +168,8 @@ private class GuardConditionFromIR extends GuardCondition {
/** Holds if (determined by this guard) `left < right + k` evaluates to `isLessThan` if this expression evaluates to `testIsTrue`. */
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
exists(Instruction li, Instruction ri |
remove_conversions(li.getAST()) = left and
remove_conversions(ri.getAST()) = right and
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesLt(li, ri, k, isLessThan, testIsTrue)
)
}
@@ -178,8 +178,8 @@ private class GuardConditionFromIR extends GuardCondition {
If `isLessThan = false` then this implies `left >= right + k`. */
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
exists(Instruction li, Instruction ri, boolean testIsTrue |
remove_conversions(li.getAST()) = left and
remove_conversions(ri.getAST()) = right and
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesLt(li, ri, k, isLessThan, testIsTrue) and
this.controls(block, testIsTrue)
)
@@ -188,8 +188,8 @@ private class GuardConditionFromIR extends GuardCondition {
/** Holds if (determined by this guard) `left == right + k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
exists(Instruction li, Instruction ri |
remove_conversions(li.getAST()) = left and
remove_conversions(ri.getAST()) = right and
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesEq(li, ri, k, areEqual, testIsTrue)
)
}
@@ -198,8 +198,8 @@ private class GuardConditionFromIR extends GuardCondition {
If `areEqual = false` then this implies `left != right + k`. */
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
exists(Instruction li, Instruction ri, boolean testIsTrue |
remove_conversions(li.getAST()) = left and
remove_conversions(ri.getAST()) = right and
li.getUnconvertedResultExpression() = left and
ri.getUnconvertedResultExpression() = right and
ir.comparesEq(li, ri, k, areEqual, testIsTrue)
and this.controls(block, testIsTrue)
)
@@ -482,11 +482,3 @@ private predicate add_eq(CompareInstruction cmp, Instruction left, Instruction r
private int int_value(Instruction i) {
result = i.(IntegerConstantInstruction).getValue().toInt()
}
/** Gets the underlying expression of `e`. */
private Expr remove_conversions(Expr e) {
if e instanceof Conversion
then result = e.(Conversion).getExpr+() and
not result instanceof Conversion
else result = e
}

View File

@@ -312,9 +312,17 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the `Expr` whose results is computed by this instruction, if any.
*/
final Expr getResultExpression() {
result = Construction::getInstructionResultExpression(this)
final Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the `Expr` whose results is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
/**
* Gets the type of the result produced by this instruction. If the

View File

@@ -197,8 +197,12 @@ cached private module Cached {
)
}
cached Expr getInstructionResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getResultExpression()
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getConvertedResultExpression()
}
cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getUnconvertedResultExpression()
}
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {

View File

@@ -312,9 +312,17 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the `Expr` whose results is computed by this instruction, if any.
*/
final Expr getResultExpression() {
result = Construction::getInstructionResultExpression(this)
final Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the `Expr` whose results is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
/**
* Gets the type of the result produced by this instruction. If the

View File

@@ -74,13 +74,25 @@ cached private module Cached {
none()
}
cached Expr getInstructionResultExpression(Instruction instruction) {
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
exists(TranslatedExpr translatedExpr |
translatedExpr = getTranslatedExpr(result) and
instruction = translatedExpr.getResult()
)
}
cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
exists(Expr converted, TranslatedExpr translatedExpr |
result = converted.(Conversion).getExpr+()
or
result = converted
|
not result instanceof Conversion and
translatedExpr = getTranslatedExpr(converted) and
instruction = translatedExpr.getResult()
)
}
cached Instruction getInstructionOperand(Instruction instruction, OperandTag tag) {
result = getInstructionTranslatedElement(instruction).getInstructionOperand(
instruction.getTag(), tag)

View File

@@ -312,9 +312,17 @@ class Instruction extends Construction::TInstruction {
/**
* Gets the `Expr` whose results is computed by this instruction, if any.
*/
final Expr getResultExpression() {
result = Construction::getInstructionResultExpression(this)
final Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the `Expr` whose results is computed by this instruction, if any.
*/
final Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)
}
/**
* Gets the type of the result produced by this instruction. If the

View File

@@ -197,8 +197,12 @@ cached private module Cached {
)
}
cached Expr getInstructionResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getResultExpression()
cached Expr getInstructionConvertedResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getConvertedResultExpression()
}
cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) {
result = getOldInstruction(instruction).getUnconvertedResultExpression()
}
cached Instruction getInstructionSuccessor(Instruction instruction, EdgeKind kind) {