mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
C++: handle conversions in IR to AST translation
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user