C++: Add IR support for ConditionalDeclExpr

Also fixes several places in the library that weren't handling `ConditionalDeclExpr`  correctly.
This commit is contained in:
Dave Bartolomeo
2018-11-21 00:14:44 -08:00
parent 07f9fe6ee4
commit 3715215b3f
11 changed files with 670 additions and 2 deletions

View File

@@ -291,7 +291,8 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
override Type getType() { localvariables(underlyingElement(this),unresolveElement(result),_) }
override Function getFunction() {
exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result)
exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result) or
exists(ConditionDeclExpr e | e.getVariable() = this and e.getEnclosingFunction() = result)
}
}

View File

@@ -28,7 +28,8 @@ class Expr extends StmtParent, @expr {
result = this.getParent().(Expr).getEnclosingStmt() or
result = this.getParent().(Stmt) or
exists(Expr other | result = other.getEnclosingStmt() and other.getConversion() = this) or
exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d)
exists(DeclStmt d, LocalVariable v | d.getADeclaration() = v and v.getInitializer().getExpr() = this and result = d) or
exists(ConditionDeclExpr cde, LocalVariable v | cde.getVariable() = v and v.getInitializer().getExpr() = this and result = cde.getEnclosingStmt())
}
/** Gets the enclosing variable of this expression, if any. */

View File

@@ -186,3 +186,39 @@ class TranslatedVariableDeclarationEntry extends TranslatedVariableDeclaration,
result = var
}
}
TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) {
result.getAST() = expr
}
/**
* Represents the IR translation of the declaration portion of a `ConditionDeclExpr`, which
* represents the variable declared in code such as:
* ```
* if (int* p = &x) {
* }
* ```
*/
class TranslatedConditionDecl extends TranslatedVariableDeclaration, TTranslatedConditionDecl {
ConditionDeclExpr conditionDeclExpr;
TranslatedConditionDecl() {
this = TTranslatedConditionDecl(conditionDeclExpr)
}
override string toString() {
result = "decl: " + conditionDeclExpr.toString()
}
override Locatable getAST() {
result = conditionDeclExpr
}
override Function getFunction() {
result = conditionDeclExpr.getEnclosingFunction()
}
override LocalVariable getVariable() {
result = conditionDeclExpr.getVariable()
}
}

View File

@@ -319,6 +319,10 @@ newtype TTranslatedElement =
// An allocation size for a `new` or `new[]` expression
TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) {
not ignoreExpr(newExpr)
} or
// The declaration/initialization part of a `ConditionDeclExpr`
TTranslatedConditionDecl(ConditionDeclExpr expr) {
not ignoreExpr(expr)
}
/**

View File

@@ -4,6 +4,7 @@ private import semmle.code.cpp.ir.internal.OperandTag
private import semmle.code.cpp.ir.internal.TempVariableTag
private import InstructionTag
private import TranslatedCondition
private import TranslatedDeclarationEntry
private import TranslatedElement
private import TranslatedFunction
private import TranslatedInitialization
@@ -2914,3 +2915,57 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr {
none()
}
}
/**
* The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable
* after conversion to `bool` in code such as:
* ```
* if (int* p = &x) {
* }
* ```
*/
class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
ConditionDeclExpr condDeclExpr;
TranslatedConditionDeclExpr() {
condDeclExpr = expr
}
override final Instruction getFirstInstruction() {
result = getDecl().getFirstInstruction()
}
override final TranslatedElement getChild(int id) {
id = 0 and result = getDecl() or
id = 1 and result = getConditionExpr()
}
override Instruction getResult() {
result = getConditionExpr().getResult()
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
none()
}
override Instruction getChildSuccessor(TranslatedElement child) {
(
child = getDecl() and
result = getConditionExpr().getFirstInstruction()
) or
child = getConditionExpr() and result = getParent().getChildSuccessor(this)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Type resultType,
boolean isGLValue) {
none()
}
private TranslatedConditionDecl getDecl() {
result = getTranslatedConditionDecl(condDeclExpr)
}
private TranslatedExpr getConditionExpr() {
result = getTranslatedExpr(condDeclExpr.getExpr().getFullyConverted())
}
}