Merge pull request #15461 from MathiasVP/propagate-edge-kinds

C++: Support function calls throwing exceptions in the IR
This commit is contained in:
Mathias Vorreiter Pedersen
2024-01-31 09:25:46 +00:00
committed by GitHub
19 changed files with 1015 additions and 610 deletions

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a new `ThrowingFunction` abstract class that can be used to model an external function that may throw an exception.

View File

@@ -285,7 +285,7 @@ private predicate backEdgeCandidate(
// is a back edge. This includes edges from `continue` and the fall-through // is a back edge. This includes edges from `continue` and the fall-through
// edge(s) after the last instruction(s) in the body. // edge(s) after the last instruction(s) in the body.
exists(TranslatedWhileStmt s | exists(TranslatedWhileStmt s |
targetInstruction = s.getFirstConditionInstruction() and targetInstruction = s.getFirstConditionInstruction(_) and
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
requiredAncestor = s.getBody() requiredAncestor = s.getBody()
) )
@@ -296,7 +296,7 @@ private predicate backEdgeCandidate(
// { ... } while (0)` statement. Note that all `continue` statements in a // { ... } while (0)` statement. Note that all `continue` statements in a
// do-while loop produce forward edges. // do-while loop produce forward edges.
exists(TranslatedDoStmt s | exists(TranslatedDoStmt s |
targetInstruction = s.getBody().getFirstInstruction() and targetInstruction = s.getBody().getFirstInstruction(_) and
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
requiredAncestor = s.getCondition() requiredAncestor = s.getCondition()
) )
@@ -308,7 +308,7 @@ private predicate backEdgeCandidate(
// last instruction(s) in the body. A for loop may not have a condition, in // last instruction(s) in the body. A for loop may not have a condition, in
// which case `getFirstConditionInstruction` returns the body instead. // which case `getFirstConditionInstruction` returns the body instead.
exists(TranslatedForStmt s | exists(TranslatedForStmt s |
targetInstruction = s.getFirstConditionInstruction() and targetInstruction = s.getFirstConditionInstruction(_) and
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
( (
requiredAncestor = s.getUpdate() requiredAncestor = s.getUpdate()
@@ -322,7 +322,7 @@ private predicate backEdgeCandidate(
// Any edge from within the update of the loop to the condition of // Any edge from within the update of the loop to the condition of
// the loop is a back edge. // the loop is a back edge.
exists(TranslatedRangeBasedForStmt s | exists(TranslatedRangeBasedForStmt s |
targetInstruction = s.getCondition().getFirstInstruction() and targetInstruction = s.getCondition().getFirstInstruction(_) and
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
requiredAncestor = s.getUpdate() requiredAncestor = s.getUpdate()
) )

View File

@@ -3,6 +3,7 @@ private import semmle.code.cpp.ir.implementation.Opcode
private import semmle.code.cpp.ir.implementation.internal.OperandTag private import semmle.code.cpp.ir.implementation.internal.OperandTag
private import semmle.code.cpp.ir.internal.CppType private import semmle.code.cpp.ir.internal.CppType
private import semmle.code.cpp.models.interfaces.SideEffect private import semmle.code.cpp.models.interfaces.SideEffect
private import semmle.code.cpp.models.interfaces.Throwing
private import InstructionTag private import InstructionTag
private import SideEffects private import SideEffects
private import TranslatedElement private import TranslatedElement
@@ -40,10 +41,10 @@ abstract class TranslatedCall extends TranslatedExpr {
id = this.getNumberOfArguments() and result = this.getSideEffects() id = this.getNumberOfArguments() and result = this.getSideEffects()
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
if exists(this.getQualifier()) if exists(this.getQualifier())
then result = this.getQualifier().getFirstInstruction() then result = this.getQualifier().getFirstInstruction(kind)
else result = this.getFirstCallTargetInstruction() else result = this.getFirstCallTargetInstruction(kind)
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -52,34 +53,43 @@ abstract class TranslatedCall extends TranslatedExpr {
resultType = getTypeForPRValue(this.getCallResultType()) resultType = getTypeForPRValue(this.getCallResultType())
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getQualifier() and child = this.getQualifier() and
result = this.getFirstCallTargetInstruction() result = this.getFirstCallTargetInstruction(kind)
or or
child = this.getCallTarget() and child = this.getCallTarget() and
result = this.getFirstArgumentOrCallInstruction() result = this.getFirstArgumentOrCallInstruction(kind)
or or
exists(int argIndex | exists(int argIndex |
child = this.getArgument(argIndex) and child = this.getArgument(argIndex) and
if exists(this.getArgument(argIndex + 1)) if exists(this.getArgument(argIndex + 1))
then result = this.getArgument(argIndex + 1).getFirstInstruction() then result = this.getArgument(argIndex + 1).getFirstInstruction(kind)
else result = this.getInstruction(CallTag()) else (
result = this.getInstruction(CallTag()) and kind instanceof GotoEdge
)
) )
or or
child = this.getSideEffects() and child = this.getSideEffects() and
if this.isNoReturn() if this.isNoReturn()
then then
kind instanceof GotoEdge and
result = result =
any(UnreachedInstruction instr | any(UnreachedInstruction instr |
this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction() this.getEnclosingFunction().getFunction() = instr.getEnclosingFunction()
) )
else result = this.getParent().getChildSuccessor(this) else (
not this.mustThrowException() and
result = this.getParent().getChildSuccessor(this, kind)
or
this.mayThrowException() and
kind instanceof ExceptionEdge and
result = this.getParent().getExceptionSuccessorInstruction(any(GotoEdge edge))
)
} }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and
tag = CallTag() and tag = CallTag() and
result = this.getSideEffects().getFirstInstruction() result = this.getSideEffects().getFirstInstruction(kind)
} }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -100,6 +110,16 @@ abstract class TranslatedCall extends TranslatedExpr {
final override Instruction getResult() { result = this.getInstruction(CallTag()) } final override Instruction getResult() { result = this.getInstruction(CallTag()) }
/**
* Holds if the evaluation of this call may throw an exception.
*/
abstract predicate mayThrowException();
/**
* Holds if the evaluation of this call always throws an exception.
*/
abstract predicate mustThrowException();
/** /**
* Gets the result type of the call. * Gets the result type of the call.
*/ */
@@ -121,8 +141,8 @@ abstract class TranslatedCall extends TranslatedExpr {
* it can be overridden by a subclass for cases where there is a call target * it can be overridden by a subclass for cases where there is a call target
* that is not computed from an expression (e.g. a direct call). * that is not computed from an expression (e.g. a direct call).
*/ */
Instruction getFirstCallTargetInstruction() { Instruction getFirstCallTargetInstruction(EdgeKind kind) {
result = this.getCallTarget().getFirstInstruction() result = this.getCallTarget().getFirstInstruction(kind)
} }
/** /**
@@ -159,10 +179,12 @@ abstract class TranslatedCall extends TranslatedExpr {
* If there are any arguments, gets the first instruction of the first * If there are any arguments, gets the first instruction of the first
* argument. Otherwise, returns the call instruction. * argument. Otherwise, returns the call instruction.
*/ */
final Instruction getFirstArgumentOrCallInstruction() { final Instruction getFirstArgumentOrCallInstruction(EdgeKind kind) {
if this.hasArguments() if this.hasArguments()
then result = this.getArgument(0).getFirstInstruction() then result = this.getArgument(0).getFirstInstruction(kind)
else result = this.getInstruction(CallTag()) else (
kind instanceof GotoEdge and result = this.getInstruction(CallTag())
)
} }
/** /**
@@ -203,12 +225,12 @@ abstract class TranslatedSideEffects extends TranslatedElement {
) )
} }
final override Instruction getChildSuccessor(TranslatedElement te) { final override Instruction getChildSuccessor(TranslatedElement te, EdgeKind kind) {
exists(int i | exists(int i |
this.getChild(i) = te and this.getChild(i) = te and
if exists(this.getChild(i + 1)) if exists(this.getChild(i + 1))
then result = this.getChild(i + 1).getFirstInstruction() then result = this.getChild(i + 1).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
) )
} }
@@ -216,11 +238,12 @@ abstract class TranslatedSideEffects extends TranslatedElement {
none() none()
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getChild(0).getFirstInstruction() result = this.getChild(0).getFirstInstruction(kind)
or or
// Some functions, like `std::move()`, have no side effects whatsoever. // Some functions, like `std::move()`, have no side effects whatsoever.
not exists(this.getChild(0)) and result = this.getParent().getChildSuccessor(this) not exists(this.getChild(0)) and
result = this.getParent().getChildSuccessor(this, kind)
} }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
@@ -235,8 +258,9 @@ abstract class TranslatedSideEffects extends TranslatedElement {
* (`TranslatedAllocatorCall`). * (`TranslatedAllocatorCall`).
*/ */
abstract class TranslatedDirectCall extends TranslatedCall { abstract class TranslatedDirectCall extends TranslatedCall {
final override Instruction getFirstCallTargetInstruction() { final override Instruction getFirstCallTargetInstruction(EdgeKind kind) {
result = this.getInstruction(CallTargetTag()) result = this.getInstruction(CallTargetTag()) and
kind instanceof GotoEdge
} }
final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) } final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
@@ -253,8 +277,7 @@ abstract class TranslatedDirectCall extends TranslatedCall {
result = TranslatedCall.super.getInstructionSuccessor(tag, kind) result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
or or
tag = CallTargetTag() and tag = CallTargetTag() and
kind instanceof GotoEdge and result = this.getFirstArgumentOrCallInstruction(kind)
result = this.getFirstArgumentOrCallInstruction()
} }
} }
@@ -290,6 +313,15 @@ class TranslatedExprCall extends TranslatedCallExpr {
override TranslatedExpr getCallTarget() { override TranslatedExpr getCallTarget() {
result = getTranslatedExpr(expr.getExpr().getFullyConverted()) result = getTranslatedExpr(expr.getExpr().getFullyConverted())
} }
final override predicate mayThrowException() {
// We assume that a call to a function pointer will not throw an exception.
// This is not sound in general, but this will greatly reduce the number of
// exceptional edges.
none()
}
final override predicate mustThrowException() { none() }
} }
/** /**
@@ -311,6 +343,14 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall {
exists(this.getQualifier()) and exists(this.getQualifier()) and
not exists(MemberFunction func | expr.getTarget() = func and func.isStatic()) not exists(MemberFunction func | expr.getTarget() = func and func.isStatic())
} }
final override predicate mayThrowException() {
expr.getTarget().(ThrowingFunction).mayThrowException(_)
}
final override predicate mustThrowException() {
expr.getTarget().(ThrowingFunction).mayThrowException(true)
}
} }
/** /**
@@ -376,10 +416,11 @@ private int initializeAllocationGroup() { result = 3 }
abstract class TranslatedSideEffect extends TranslatedElement { abstract class TranslatedSideEffect extends TranslatedElement {
final override TranslatedElement getChild(int n) { none() } final override TranslatedElement getChild(int n) { none() }
final override Instruction getChildSuccessor(TranslatedElement child) { none() } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
} }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
@@ -388,9 +429,8 @@ abstract class TranslatedSideEffect extends TranslatedElement {
} }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
result = this.getParent().getChildSuccessor(this) and result = this.getParent().getChildSuccessor(this, kind) and
tag = OnlyInstructionTag() and tag = OnlyInstructionTag()
kind instanceof GotoEdge
} }
final override Declaration getFunction() { result = this.getParent().getFunction() } final override Declaration getFunction() { result = this.getParent().getFunction() }

View File

@@ -7,9 +7,17 @@ private import TranslatedElement
private import TranslatedExpr private import TranslatedExpr
abstract class ConditionContext extends TranslatedElement { abstract class ConditionContext extends TranslatedElement {
abstract Instruction getChildTrueSuccessor(TranslatedCondition child); /**
* Gets the instruction to be executed when `child` evaluates to `true`. The
* successor edge kind is specified by `kind`.
*/
abstract Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind);
abstract Instruction getChildFalseSuccessor(TranslatedCondition child); /**
* Gets the instruction to be executed when `child` evaluates to `false`. The
* successor edge kind is specified by `kind`.
*/
abstract Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind);
} }
TranslatedCondition getTranslatedCondition(Expr expr) { result.getExpr() = expr } TranslatedCondition getTranslatedCondition(Expr expr) { result.getExpr() = expr }
@@ -44,8 +52,8 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getOperand().getFirstInstruction() result = this.getOperand().getFirstInstruction(kind)
} }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -54,7 +62,7 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getChildSuccessor(TranslatedElement child) { none() } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
abstract TranslatedCondition getOperand(); abstract TranslatedCondition getOperand();
} }
@@ -62,14 +70,14 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
class TranslatedParenthesisCondition extends TranslatedFlexibleCondition { class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
override ParenthesisExpr expr; override ParenthesisExpr expr;
final override Instruction getChildTrueSuccessor(TranslatedCondition child) { final override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getOperand() and child = this.getOperand() and
result = this.getConditionContext().getChildTrueSuccessor(this) result = this.getConditionContext().getChildTrueSuccessor(this, kind)
} }
final override Instruction getChildFalseSuccessor(TranslatedCondition child) { final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getOperand() and child = this.getOperand() and
result = this.getConditionContext().getChildFalseSuccessor(this) result = this.getConditionContext().getChildFalseSuccessor(this, kind)
} }
final override TranslatedCondition getOperand() { final override TranslatedCondition getOperand() {
@@ -80,7 +88,7 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition { abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition {
TranslatedNativeCondition() { this = TTranslatedNativeCondition(expr) } TranslatedNativeCondition() { this = TTranslatedNativeCondition(expr) }
final override Instruction getChildSuccessor(TranslatedElement child) { none() } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
} }
abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeCondition, ConditionContext { abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeCondition, ConditionContext {
@@ -92,8 +100,8 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
id = 1 and result = this.getRightOperand() id = 1 and result = this.getRightOperand()
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getLeftOperand().getFirstInstruction() result = this.getLeftOperand().getFirstInstruction(kind)
} }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -114,34 +122,34 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
class TranslatedLogicalAndExpr extends TranslatedBinaryLogicalOperation { class TranslatedLogicalAndExpr extends TranslatedBinaryLogicalOperation {
TranslatedLogicalAndExpr() { expr instanceof LogicalAndExpr } TranslatedLogicalAndExpr() { expr instanceof LogicalAndExpr }
override Instruction getChildTrueSuccessor(TranslatedCondition child) { override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getLeftOperand() and child = this.getLeftOperand() and
result = this.getRightOperand().getFirstInstruction() result = this.getRightOperand().getFirstInstruction(kind)
or or
child = this.getRightOperand() and child = this.getRightOperand() and
result = this.getConditionContext().getChildTrueSuccessor(this) result = this.getConditionContext().getChildTrueSuccessor(this, kind)
} }
override Instruction getChildFalseSuccessor(TranslatedCondition child) { override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
(child = this.getLeftOperand() or child = this.getRightOperand()) and (child = this.getLeftOperand() or child = this.getRightOperand()) and
result = this.getConditionContext().getChildFalseSuccessor(this) result = this.getConditionContext().getChildFalseSuccessor(this, kind)
} }
} }
class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation { class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation {
override LogicalOrExpr expr; override LogicalOrExpr expr;
override Instruction getChildTrueSuccessor(TranslatedCondition child) { override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
(child = this.getLeftOperand() or child = this.getRightOperand()) and (child = this.getLeftOperand() or child = this.getRightOperand()) and
result = this.getConditionContext().getChildTrueSuccessor(this) result = this.getConditionContext().getChildTrueSuccessor(this, kind)
} }
override Instruction getChildFalseSuccessor(TranslatedCondition child) { override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getLeftOperand() and child = this.getLeftOperand() and
result = this.getRightOperand().getFirstInstruction() result = this.getRightOperand().getFirstInstruction(kind)
or or
child = this.getRightOperand() and child = this.getRightOperand() and
result = this.getConditionContext().getChildFalseSuccessor(this) result = this.getConditionContext().getChildFalseSuccessor(this, kind)
} }
} }
@@ -150,7 +158,9 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
override TranslatedElement getChild(int id) { id = 0 and result = this.getValueExpr() } override TranslatedElement getChild(int id) { id = 0 and result = this.getValueExpr() }
override Instruction getFirstInstruction() { result = this.getValueExpr().getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getValueExpr().getFirstInstruction(kind)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = ValueConditionConditionalBranchTag() and tag = ValueConditionConditionalBranchTag() and
@@ -158,19 +168,20 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
resultType = getVoidType() resultType = getVoidType()
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getValueExpr() and child = this.getValueExpr() and
result = this.getInstruction(ValueConditionConditionalBranchTag()) result = this.getInstruction(ValueConditionConditionalBranchTag()) and
kind instanceof GotoEdge
} }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = ValueConditionConditionalBranchTag() and tag = ValueConditionConditionalBranchTag() and
( (
kind instanceof TrueEdge and kind instanceof TrueEdge and
result = this.getConditionContext().getChildTrueSuccessor(this) result = this.getConditionContext().getChildTrueSuccessor(this, any(GotoEdge edge))
or or
kind instanceof FalseEdge and kind instanceof FalseEdge and
result = this.getConditionContext().getChildFalseSuccessor(this) result = this.getConditionContext().getChildFalseSuccessor(this, any(GotoEdge edge))
) )
} }

View File

@@ -67,8 +67,8 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
getTranslatedInitialization(this.getVariable().getInitializer().getExpr().getFullyConverted()) getTranslatedInitialization(this.getVariable().getInitializer().getExpr().getFullyConverted())
} }
final override Instruction getInitializationSuccessor() { final override Instruction getInitializationSuccessor(EdgeKind kind) {
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
final override IRVariable getIRVariable() { final override IRVariable getIRVariable() {
@@ -147,8 +147,9 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
type = getBoolType() type = getBoolType()
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(DynamicInitializationFlagAddressTag()) result = this.getInstruction(DynamicInitializationFlagAddressTag()) and
kind instanceof GotoEdge
} }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -163,10 +164,10 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
tag = DynamicInitializationConditionalBranchTag() and tag = DynamicInitializationConditionalBranchTag() and
( (
kind instanceof TrueEdge and kind instanceof TrueEdge and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
or or
kind instanceof FalseEdge and kind instanceof FalseEdge and
result = this.getInitialization().getFirstInstruction() result = this.getInitialization().getFirstInstruction(any(GotoEdge edge))
) )
or or
tag = DynamicInitializationFlagConstantTag() and tag = DynamicInitializationFlagConstantTag() and
@@ -174,13 +175,13 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
result = this.getInstruction(DynamicInitializationFlagStoreTag()) result = this.getInstruction(DynamicInitializationFlagStoreTag())
or or
tag = DynamicInitializationFlagStoreTag() and tag = DynamicInitializationFlagStoreTag() and
kind instanceof GotoEdge and result = this.getParent().getChildSuccessor(this, kind)
result = this.getParent().getChildSuccessor(this)
} }
final override Instruction getChildSuccessor(TranslatedElement child) { final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and child = this.getInitialization() and
result = this.getInstruction(DynamicInitializationFlagConstantTag()) result = this.getInstruction(DynamicInitializationFlagConstantTag()) and
kind instanceof GotoEdge
} }
final override IRDynamicInitializationFlag getInstructionVariable(InstructionTag tag) { final override IRDynamicInitializationFlag getInstructionVariable(InstructionTag tag) {

View File

@@ -827,9 +827,10 @@ abstract class TranslatedElement extends TTranslatedElement {
Location getLocation() { result = this.getAst().getLocation() } Location getLocation() { result = this.getAst().getLocation() }
/** /**
* Get the first instruction to be executed in the evaluation of this element. * Get the first instruction to be executed in the evaluation of this
* element when the edge kind is `kind`.
*/ */
abstract Instruction getFirstInstruction(); abstract Instruction getFirstInstruction(EdgeKind kind);
/** /**
* Get the immediate child elements of this element. * Get the immediate child elements of this element.
@@ -904,18 +905,19 @@ abstract class TranslatedElement extends TTranslatedElement {
/** /**
* Gets the successor instruction to which control should flow after the * Gets the successor instruction to which control should flow after the
* child element specified by `child` has finished execution. * child element specified by `child` has finished execution. The successor
* edge kind is specified by `kind`.
*/ */
abstract Instruction getChildSuccessor(TranslatedElement child); abstract Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind);
/** /**
* Gets the instruction to which control should flow if an exception is thrown * Gets the instruction to which control should flow if an exception is thrown
* within this element. This will generally return first `catch` block of the * within this element. This will generally return first `catch` block of the
* nearest enclosing `try`, or the `Unwind` instruction for the function if * nearest enclosing `try`, or the `Unwind` instruction for the function if
* there is no enclosing `try`. * there is no enclosing `try`. The successor edge kind is specified by `kind`.
*/ */
Instruction getExceptionSuccessorInstruction() { Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
result = this.getParent().getExceptionSuccessorInstruction() result = this.getParent().getExceptionSuccessorInstruction(kind)
} }
/** /**

View File

@@ -109,8 +109,9 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
result = getTranslatedEllipsisParameter(func) result = getTranslatedEllipsisParameter(func)
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(EnterFunctionTag()) result = this.getInstruction(EnterFunctionTag()) and
kind instanceof GotoEdge
} }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -121,17 +122,20 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
or or
tag = AliasedDefinitionTag() and tag = AliasedDefinitionTag() and
result = this.getInstruction(InitializeNonLocalTag()) result = this.getInstruction(InitializeNonLocalTag())
)
or or
( (
tag = InitializeNonLocalTag() and tag = InitializeNonLocalTag() and
if exists(this.getThisType()) if exists(this.getThisType())
then result = this.getParameter(-1).getFirstInstruction() then result = this.getParameter(-1).getFirstInstruction(kind)
else else
if exists(this.getParameter(0)) if exists(this.getParameter(0))
then result = this.getParameter(0).getFirstInstruction() then result = this.getParameter(0).getFirstInstruction(kind)
else result = this.getBody().getFirstInstruction() else result = this.getBody().getFirstInstruction(kind)
) )
or or
kind instanceof GotoEdge and
(
tag = ReturnValueAddressTag() and tag = ReturnValueAddressTag() and
result = this.getInstruction(ReturnTag()) result = this.getInstruction(ReturnTag())
or or
@@ -146,25 +150,25 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
) )
} }
final override Instruction getChildSuccessor(TranslatedElement child) { final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int paramIndex | exists(int paramIndex | child = this.getParameter(paramIndex) |
child = this.getParameter(paramIndex) and
if if
exists(func.getParameter(paramIndex + 1)) or exists(func.getParameter(paramIndex + 1)) or
getEllipsisParameterIndexForFunction(func) = paramIndex + 1 getEllipsisParameterIndexForFunction(func) = paramIndex + 1
then result = this.getParameter(paramIndex + 1).getFirstInstruction() then result = this.getParameter(paramIndex + 1).getFirstInstruction(kind)
else result = this.getConstructorInitList().getFirstInstruction() else result = this.getConstructorInitList().getFirstInstruction(kind)
) )
or or
child = this.getConstructorInitList() and child = this.getConstructorInitList() and
result = this.getBody().getFirstInstruction() result = this.getBody().getFirstInstruction(kind)
or or
child = this.getBody() and child = this.getBody() and
result = this.getReturnSuccessorInstruction() result = this.getReturnSuccessorInstruction(kind)
or or
child = this.getDestructorDestructionList() and child = this.getDestructorDestructionList() and
result = this.getReadEffects().getFirstInstruction() result = this.getReadEffects().getFirstInstruction(kind)
or or
kind instanceof GotoEdge and
child = this.getReadEffects() and child = this.getReadEffects() and
if this.hasReturnValue() if this.hasReturnValue()
then result = this.getInstruction(ReturnValueAddressTag()) then result = this.getInstruction(ReturnValueAddressTag())
@@ -218,8 +222,9 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
) )
} }
final override Instruction getExceptionSuccessorInstruction() { final override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
result = this.getInstruction(UnwindTag()) result = this.getInstruction(UnwindTag()) and
kind instanceof GotoEdge
} }
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -268,8 +273,8 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
* Gets the instruction to which control should flow after a `return` * Gets the instruction to which control should flow after a `return`
* statement. * statement.
*/ */
final Instruction getReturnSuccessorInstruction() { final Instruction getReturnSuccessorInstruction(EdgeKind kind) {
result = this.getDestructorDestructionList().getFirstInstruction() result = this.getDestructorDestructionList().getFirstInstruction(kind)
} }
/** /**
@@ -369,30 +374,30 @@ TranslatedEllipsisParameter getTranslatedEllipsisParameter(Function func) {
abstract class TranslatedParameter extends TranslatedElement { abstract class TranslatedParameter extends TranslatedElement {
final override TranslatedElement getChild(int id) { none() } final override TranslatedElement getChild(int id) { none() }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(InitializerVariableAddressTag()) result = this.getInstruction(InitializerVariableAddressTag()) and
kind instanceof GotoEdge
} }
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and kind instanceof GotoEdge and
(
tag = InitializerVariableAddressTag() and tag = InitializerVariableAddressTag() and
result = this.getInstruction(InitializerStoreTag()) result = this.getInstruction(InitializerStoreTag())
or or
tag = InitializerStoreTag() and tag = InitializerStoreTag() and
if this.hasIndirection() if this.hasIndirection()
then result = this.getInstruction(InitializerIndirectAddressTag()) then kind instanceof GotoEdge and result = this.getInstruction(InitializerIndirectAddressTag())
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
or or
kind instanceof GotoEdge and
tag = InitializerIndirectAddressTag() and tag = InitializerIndirectAddressTag() and
result = this.getInstruction(InitializerIndirectStoreTag()) result = this.getInstruction(InitializerIndirectStoreTag())
or or
tag = InitializerIndirectStoreTag() and tag = InitializerIndirectStoreTag() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
)
} }
final override Instruction getChildSuccessor(TranslatedElement child) { none() } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = InitializerVariableAddressTag() and tag = InitializerVariableAddressTag() and
@@ -600,10 +605,10 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
) )
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if exists(this.getChild(0)) if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction() then result = this.getChild(0).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -614,12 +619,12 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int id | exists(int id |
child = this.getChild(id) and child = this.getChild(id) and
if exists(this.getChild(id + 1)) if exists(this.getChild(id + 1))
then result = this.getChild(id + 1).getFirstInstruction() then result = this.getChild(id + 1).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
) )
} }
@@ -667,10 +672,10 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
) )
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if exists(this.getChild(0)) if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction() then result = this.getChild(0).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -681,12 +686,12 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int id | exists(int id |
child = this.getChild(id) and child = this.getChild(id) and
if exists(this.getChild(id + 1)) if exists(this.getChild(id + 1))
then result = this.getChild(id + 1).getFirstInstruction() then result = this.getChild(id + 1).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
) )
} }
} }
@@ -714,16 +719,16 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
result = getTranslatedParameterReadEffect(func.getParameter(id)) result = getTranslatedParameterReadEffect(func.getParameter(id))
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if exists(this.getAChild()) if exists(this.getAChild())
then then
result = result =
min(TranslatedElement child, int id | child = this.getChild(id) | child order by id) min(TranslatedElement child, int id | child = this.getChild(id) | child order by id)
.getFirstInstruction() .getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int id | child = this.getChild(id) | exists(int id | child = this.getChild(id) |
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = this.getChild(id2)) if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = this.getChild(id2))
then then
@@ -732,8 +737,8 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
child2 = this.getChild(id2) and id2 > id child2 = this.getChild(id2) and id2 > id
| |
child2 order by id2 child2 order by id2
).getFirstInstruction() ).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
) )
} }
@@ -755,15 +760,17 @@ private TranslatedParameterReadEffect getTranslatedParameterReadEffect(Parameter
abstract class TranslatedReadEffect extends TranslatedElement { abstract class TranslatedReadEffect extends TranslatedElement {
override TranslatedElement getChild(int id) { none() } override TranslatedElement getChild(int id) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
kind = EdgeKind::gotoEdge() and result = this.getParent().getChildSuccessor(this, kind)
result = this.getParent().getChildSuccessor(this)
} }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
opcode instanceof Opcode::ReturnIndirection and opcode instanceof Opcode::ReturnIndirection and

View File

@@ -22,7 +22,10 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
final override Declaration getFunction() { result = var } final override Declaration getFunction() { result = var }
override Instruction getFirstInstruction() { result = this.getInstruction(EnterFunctionTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(EnterFunctionTag()) and
kind instanceof GotoEdge
}
override TranslatedElement getChild(int n) { override TranslatedElement getChild(int n) {
n = 1 and n = 1 and
@@ -63,10 +66,13 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
or or
tag = AliasedDefinitionTag() and tag = AliasedDefinitionTag() and
result = this.getInstruction(InitializerVariableAddressTag()) result = this.getInstruction(InitializerVariableAddressTag())
)
or or
tag = InitializerVariableAddressTag() and tag = InitializerVariableAddressTag() and
result = this.getChild(1).getFirstInstruction() result = this.getChild(1).getFirstInstruction(kind)
or or
kind instanceof GotoEdge and
(
tag = ReturnTag() and tag = ReturnTag() and
result = this.getInstruction(AliasedUseTag()) result = this.getInstruction(AliasedUseTag())
or or
@@ -75,9 +81,10 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
) )
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getChild(1) and child = this.getChild(1) and
result = this.getInstruction(ReturnTag()) result = this.getInstruction(ReturnTag()) and
kind instanceof GotoEdge
} }
final override CppType getInstructionMemoryOperandType( final override CppType getInstructionMemoryOperandType(

View File

@@ -37,8 +37,9 @@ abstract class InitializationContext extends TranslatedElement {
abstract class TranslatedVariableInitialization extends TranslatedElement, InitializationContext { abstract class TranslatedVariableInitialization extends TranslatedElement, InitializationContext {
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() } final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(InitializerVariableAddressTag()) result = this.getInstruction(InitializerVariableAddressTag()) and
kind instanceof GotoEdge
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -55,24 +56,24 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
( (
tag = InitializerVariableAddressTag() and tag = InitializerVariableAddressTag() and
kind instanceof GotoEdge and
if this.hasUninitializedInstruction() if this.hasUninitializedInstruction()
then result = this.getInstruction(InitializerStoreTag()) then kind instanceof GotoEdge and result = this.getInstruction(InitializerStoreTag())
else result = this.getInitialization().getFirstInstruction() else result = this.getInitialization().getFirstInstruction(kind)
) )
or or
this.hasUninitializedInstruction() and this.hasUninitializedInstruction() and
kind instanceof GotoEdge and
tag = InitializerStoreTag() and tag = InitializerStoreTag() and
( (
result = this.getInitialization().getFirstInstruction() result = this.getInitialization().getFirstInstruction(kind)
or or
not exists(this.getInitialization()) and result = this.getInitializationSuccessor() not exists(this.getInitialization()) and
result = this.getInitializationSuccessor(kind)
) )
} }
final override Instruction getChildSuccessor(TranslatedElement child) { final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and result = this.getInitializationSuccessor() child = this.getInitialization() and
result = this.getInitializationSuccessor(kind)
} }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -107,8 +108,9 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
/** /**
* Gets the `Instruction` to be executed immediately after the initialization. * Gets the `Instruction` to be executed immediately after the initialization.
* The successor edge kind is specified by `kind`.
*/ */
abstract Instruction getInitializationSuccessor(); abstract Instruction getInitializationSuccessor(EdgeKind kind);
/** /**
* Holds if this initialization requires an `Uninitialized` instruction to be emitted before * Holds if this initialization requires an `Uninitialized` instruction to be emitted before
@@ -168,18 +170,19 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
* Represents the IR translation of an initialization from an initializer list. * Represents the IR translation of an initialization from an initializer list.
*/ */
abstract class TranslatedListInitialization extends TranslatedInitialization, InitializationContext { abstract class TranslatedListInitialization extends TranslatedInitialization, InitializationContext {
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getChild(0).getFirstInstruction() result = this.getChild(0).getFirstInstruction(kind)
or or
not exists(this.getChild(0)) and result = this.getParent().getChildSuccessor(this) not exists(this.getChild(0)) and
result = this.getParent().getChildSuccessor(this, kind)
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int index | exists(int index |
child = this.getChild(index) and child = this.getChild(index) and
if exists(this.getChild(index + 1)) if exists(this.getChild(index + 1))
then result = this.getChild(index + 1).getFirstInstruction() then result = this.getChild(index + 1).getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
) )
} }
@@ -239,8 +242,8 @@ abstract class TranslatedDirectInitialization extends TranslatedInitialization {
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitializer() } override TranslatedElement getChild(int id) { id = 0 and result = this.getInitializer() }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInitializer().getFirstInstruction() result = this.getInitializer().getFirstInstruction(kind)
} }
final TranslatedExpr getInitializer() { result = getTranslatedExpr(expr) } final TranslatedExpr getInitializer() { result = getTranslatedExpr(expr) }
@@ -265,12 +268,13 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = InitializerStoreTag() and tag = InitializerStoreTag() and
result = this.getParent().getChildSuccessor(this) and result = this.getParent().getChildSuccessor(this, kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitializer() and result = this.getInstruction(InitializerStoreTag()) child = this.getInitializer() and
result = this.getInstruction(InitializerStoreTag()) and
kind instanceof GotoEdge
} }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -335,12 +339,13 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
kind instanceof GotoEdge and kind instanceof GotoEdge and
(
tag = InitializerLoadStringTag() and tag = InitializerLoadStringTag() and
result = this.getInstruction(InitializerStoreTag()) result = this.getInstruction(InitializerStoreTag())
or or
if this.zeroInitRange(_, _) if this.zeroInitRange(_, _)
then ( then (
kind instanceof GotoEdge and
(
tag = InitializerStoreTag() and tag = InitializerStoreTag() and
result = this.getInstruction(ZeroPadStringConstantTag()) result = this.getInstruction(ZeroPadStringConstantTag())
or or
@@ -352,18 +357,20 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
or or
tag = ZeroPadStringElementAddressTag() and tag = ZeroPadStringElementAddressTag() and
result = this.getInstruction(ZeroPadStringStoreTag()) result = this.getInstruction(ZeroPadStringStoreTag())
)
or or
tag = ZeroPadStringStoreTag() and tag = ZeroPadStringStoreTag() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
) else ( ) else (
tag = InitializerStoreTag() and tag = InitializerStoreTag() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
)
) )
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitializer() and result = this.getInstruction(InitializerLoadStringTag()) child = this.getInitializer() and
result = this.getInstruction(InitializerLoadStringTag()) and
kind instanceof GotoEdge
} }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -456,8 +463,8 @@ class TranslatedConstructorInitialization extends TranslatedDirectInitialization
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this) child = this.getInitializer() and result = this.getParent().getChildSuccessor(this, kind)
} }
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -502,8 +509,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable) result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(this.getFieldAddressTag()) result = this.getInstruction(this.getFieldAddressTag()) and
kind instanceof GotoEdge
} }
/** /**
@@ -558,12 +566,11 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = this.getFieldAddressTag() and tag = this.getFieldAddressTag() and
result = this.getInitialization().getFirstInstruction() and result = this.getInitialization().getFirstInstruction(kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this) child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
} }
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() } override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
@@ -608,10 +615,10 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
or or
tag = this.getFieldDefaultValueTag() and tag = this.getFieldDefaultValueTag() and
result = this.getInstruction(this.getFieldDefaultValueStoreTag()) result = this.getInstruction(this.getFieldDefaultValueStoreTag())
)
or or
tag = this.getFieldDefaultValueStoreTag() and tag = this.getFieldDefaultValueStoreTag() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
)
} }
override string getInstructionConstantValue(InstructionTag tag) { override string getInstructionConstantValue(InstructionTag tag) {
@@ -632,7 +639,7 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
) )
} }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
override TranslatedElement getChild(int id) { none() } override TranslatedElement getChild(int id) { none() }
@@ -667,8 +674,9 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable) result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
} }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(this.getElementIndexTag()) result = this.getInstruction(this.getElementIndexTag()) and
kind instanceof GotoEdge
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -745,12 +753,11 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind) result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
or or
tag = this.getElementAddressTag() and tag = this.getElementAddressTag() and
result = this.getInitialization().getFirstInstruction() and result = this.getInitialization().getFirstInstruction(kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this) child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
} }
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() } override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
@@ -803,10 +810,10 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
or or
tag = this.getElementDefaultValueTag() and tag = this.getElementDefaultValueTag() and
result = this.getInstruction(this.getElementDefaultValueStoreTag()) result = this.getInstruction(this.getElementDefaultValueStoreTag())
)
or or
tag = this.getElementDefaultValueStoreTag() and tag = this.getElementDefaultValueStoreTag() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
)
} }
override string getInstructionConstantValue(InstructionTag tag) { override string getInstructionConstantValue(InstructionTag tag) {
@@ -829,7 +836,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
) )
} }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
override TranslatedElement getChild(int id) { none() } override TranslatedElement getChild(int id) { none() }
@@ -869,9 +876,9 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
final override Function getFunction() { result = getEnclosingFunction(call) } final override Function getFunction() { result = getEnclosingFunction(call) }
final override Instruction getChildSuccessor(TranslatedElement child) { final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getStructorCall() and child = this.getStructorCall() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
final TranslatedExpr getStructorCall() { result = getTranslatedExpr(call) } final TranslatedExpr getStructorCall() { result = getTranslatedExpr(call) }
@@ -882,8 +889,9 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
* destructor from within a derived class constructor or destructor. * destructor from within a derived class constructor or destructor.
*/ */
abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStructor { abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStructor {
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
} }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -894,8 +902,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
kind instanceof GotoEdge and result = this.getStructorCall().getFirstInstruction(kind)
result = this.getStructorCall().getFirstInstruction()
} }
final override Instruction getReceiver() { result = this.getInstruction(OnlyInstructionTag()) } final override Instruction getReceiver() { result = this.getInstruction(OnlyInstructionTag()) }
@@ -936,8 +943,8 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
final override string toString() { result = "delegation construct: " + call.toString() } final override string toString() { result = "delegation construct: " + call.toString() }
final override Instruction getFirstInstruction() { final override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getStructorCall().getFirstInstruction() result = this.getStructorCall().getFirstInstruction(kind)
} }
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -998,7 +1005,9 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
final override string toString() { result = "construct base (no constructor)" } final override string toString() { result = "construct base (no constructor)" }
override Instruction getFirstInstruction() { result = this.getParent().getChildSuccessor(this) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getParent().getChildSuccessor(this, kind)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none() none()
@@ -1010,7 +1019,7 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
} }
TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) { TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) {

View File

@@ -30,7 +30,9 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
final override Locatable getAst() { result = tryExcept.getExcept() } final override Locatable getAst() { result = tryExcept.getExcept() }
override Instruction getFirstInstruction() { result = this.getChild(0).getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getChild(0).getFirstInstruction(kind)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
// t1 = -1 // t1 = -1
@@ -192,23 +194,21 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
or or
// Branch -> Handler (the condition value is always 0, -1 or 1, and we've checked for 0 or -1 already.) // Branch -> Handler (the condition value is always 0, -1 or 1, and we've checked for 0 or -1 already.)
tag = TryExceptCompareOneBranch() and tag = TryExceptCompareOneBranch() and
(
kind instanceof TrueEdge and kind instanceof TrueEdge and
result = this.getTranslatedHandler().getFirstInstruction() result = this.getTranslatedHandler().getFirstInstruction(any(GotoEdge edge))
)
or or
// Unwind -> Parent // Unwind -> Parent
tag = UnwindTag() and tag = UnwindTag() and
kind instanceof GotoEdge and result = this.getParent().getChildSuccessor(this, kind)
result = this.getParent().getChildSuccessor(this)
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
kind instanceof GotoEdge and
child = this.getTranslatedCondition() and child = this.getTranslatedCondition() and
result = this.getInstruction(TryExceptGenerateNegativeOne()) result = this.getInstruction(TryExceptGenerateNegativeOne())
or or
child = this.getTranslatedHandler() and child = this.getTranslatedHandler() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
private TranslatedExpr getTranslatedCondition() { private TranslatedExpr getTranslatedCondition() {
@@ -254,7 +254,10 @@ class TranslatedEmptyStmt extends TranslatedStmt {
override TranslatedElement getChild(int id) { none() } override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
@@ -264,11 +267,10 @@ class TranslatedEmptyStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
result = this.getParent().getChildSuccessor(this) and result = this.getParent().getChildSuccessor(this, kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
} }
/** /**
@@ -285,10 +287,11 @@ class TranslatedDeclStmt extends TranslatedStmt {
none() none()
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getDeclarationEntry(0).getFirstInstruction() result = this.getDeclarationEntry(0).getFirstInstruction(kind)
or or
not exists(this.getDeclarationEntry(0)) and result = this.getParent().getChildSuccessor(this) not exists(this.getDeclarationEntry(0)) and
result = this.getParent().getChildSuccessor(this, kind)
} }
private int getChildCount() { result = count(this.getDeclarationEntry(_)) } private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
@@ -317,12 +320,12 @@ class TranslatedDeclStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int index | exists(int index |
child = this.getDeclarationEntry(index) and child = this.getDeclarationEntry(index) and
if index = (this.getChildCount() - 1) if index = (this.getChildCount() - 1)
then result = this.getParent().getChildSuccessor(this) then result = this.getParent().getChildSuccessor(this, kind)
else result = this.getDeclarationEntry(index + 1).getFirstInstruction() else result = this.getDeclarationEntry(index + 1).getFirstInstruction(kind)
) )
} }
} }
@@ -338,13 +341,15 @@ class TranslatedExprStmt extends TranslatedStmt {
none() none()
} }
override Instruction getFirstInstruction() { result = this.getExpr().getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getExpr().getFirstInstruction(kind)
}
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getExpr() and child = this.getExpr() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
} }
@@ -362,8 +367,8 @@ abstract class TranslatedReturnStmt extends TranslatedStmt {
class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariableInitialization { class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariableInitialization {
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) } TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
final override Instruction getInitializationSuccessor() { final override Instruction getInitializationSuccessor(EdgeKind kind) {
result = this.getEnclosingFunction().getReturnSuccessorInstruction() result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
} }
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() } final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
@@ -390,7 +395,9 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
result = this.getExpr() result = this.getExpr()
} }
override Instruction getFirstInstruction() { result = this.getExpr().getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getExpr().getFirstInstruction(kind)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
@@ -400,13 +407,13 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getExpr() and child = this.getExpr() and
result = this.getInstruction(OnlyInstructionTag()) result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
} }
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) } private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
@@ -423,7 +430,10 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
override TranslatedElement getChild(int id) { none() } override TranslatedElement getChild(int id) { none() }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
@@ -433,11 +443,10 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
} }
/** /**
@@ -451,8 +460,8 @@ class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariab
not stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) not stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction())
} }
final override Instruction getInitializationSuccessor() { final override Instruction getInitializationSuccessor(EdgeKind kind) {
result = this.getEnclosingFunction().getReturnSuccessorInstruction() result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
} }
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() } final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
@@ -524,40 +533,42 @@ class TranslatedTryStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getFirstInstruction() { result = this.getBody().getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getBody().getFirstInstruction(kind)
}
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
// All non-finally children go to the successor of the `try` if // All non-finally children go to the successor of the `try` if
// there is no finally block, but if there is a finally block // there is no finally block, but if there is a finally block
// then we go to that one. // then we go to that one.
child = [this.getBody(), this.getHandler(_)] and child = [this.getBody(), this.getHandler(_)] and
( (
not exists(this.getFinally()) and not exists(this.getFinally()) and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
or or
result = this.getFinally().getFirstInstruction() result = this.getFinally().getFirstInstruction(kind)
) )
or or
// And after the finally block we go to the successor of the `try`. // And after the finally block we go to the successor of the `try`.
child = this.getFinally() and child = this.getFinally() and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
final Instruction getNextHandler(TranslatedHandler handler) { final Instruction getNextHandler(TranslatedHandler handler, EdgeKind kind) {
exists(int index | exists(int index |
handler = this.getHandler(index) and handler = this.getHandler(index) and
result = this.getHandler(index + 1).getFirstInstruction() result = this.getHandler(index + 1).getFirstInstruction(kind)
) )
or or
// The last catch clause flows to the exception successor of the parent // The last catch clause flows to the exception successor of the parent
// of the `try`, because the exception successor of the `try` itself is // of the `try`, because the exception successor of the `try` itself is
// the first catch clause. // the first catch clause.
handler = this.getHandler(stmt.getNumberOfCatchClauses() - 1) and handler = this.getHandler(stmt.getNumberOfCatchClauses() - 1) and
result = this.getParent().getExceptionSuccessorInstruction() result = this.getParent().getExceptionSuccessorInstruction(kind)
} }
final override Instruction getExceptionSuccessorInstruction() { final override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
result = this.getHandler(0).getFirstInstruction() result = this.getHandler(0).getFirstInstruction(kind)
} }
private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) } private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) }
@@ -579,10 +590,10 @@ class TranslatedBlock extends TranslatedStmt {
resultType = getVoidType() resultType = getVoidType()
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if this.isEmpty() if this.isEmpty()
then result = this.getInstruction(OnlyInstructionTag()) then kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag())
else result = this.getStmt(0).getFirstInstruction() else result = this.getStmt(0).getFirstInstruction(kind)
} }
private predicate isEmpty() { not exists(stmt.getStmt(0)) } private predicate isEmpty() { not exists(stmt.getStmt(0)) }
@@ -593,16 +604,15 @@ class TranslatedBlock extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
result = this.getParent().getChildSuccessor(this) and result = this.getParent().getChildSuccessor(this, kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int index | exists(int index |
child = this.getStmt(index) and child = this.getStmt(index) and
if index = (this.getStmtCount() - 1) if index = (this.getStmtCount() - 1)
then result = this.getParent().getChildSuccessor(this) then result = this.getParent().getChildSuccessor(this, kind)
else result = this.getStmt(index + 1).getFirstInstruction() else result = this.getStmt(index + 1).getFirstInstruction(kind)
) )
} }
} }
@@ -615,16 +625,19 @@ abstract class TranslatedHandler extends TranslatedStmt {
override TranslatedElement getChild(int id) { id = 1 and result = this.getBlock() } override TranslatedElement getChild(int id) { id = 1 and result = this.getBlock() }
override Instruction getFirstInstruction() { result = this.getInstruction(CatchTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(CatchTag()) and
override Instruction getChildSuccessor(TranslatedElement child) { kind instanceof GotoEdge
child = this.getBlock() and result = this.getParent().getChildSuccessor(this)
} }
override Instruction getExceptionSuccessorInstruction() { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getBlock() and result = this.getParent().getChildSuccessor(this, kind)
}
override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
// A throw from within a `catch` block flows to the handler for the parent of // A throw from within a `catch` block flows to the handler for the parent of
// the `try`. // the `try`.
result = this.getParent().getParent().getExceptionSuccessorInstruction() result = this.getParent().getParent().getExceptionSuccessorInstruction(kind)
} }
TranslatedStmt getBlock() { result = getTranslatedStmt(stmt.getBlock()) } TranslatedStmt getBlock() { result = getTranslatedStmt(stmt.getBlock()) }
@@ -649,20 +662,21 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
id = 0 and result = this.getParameter() id = 0 and result = this.getParameter()
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
result = super.getChildSuccessor(child) result = super.getChildSuccessor(child, kind)
or or
child = this.getParameter() and result = this.getBlock().getFirstInstruction() child = this.getParameter() and
result = this.getBlock().getFirstInstruction(kind)
} }
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and tag = CatchTag() and
( (
kind instanceof GotoEdge and kind instanceof GotoEdge and
result = this.getParameter().getFirstInstruction() result = this.getParameter().getFirstInstruction(kind)
or or
kind instanceof ExceptionEdge and kind instanceof ExceptionEdge and
result = this.getParent().(TranslatedTryStmt).getNextHandler(this) result = this.getParent().(TranslatedTryStmt).getNextHandler(this, any(GotoEdge edge))
) )
} }
@@ -690,18 +704,17 @@ class TranslatedCatchAnyHandler extends TranslatedHandler {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = CatchTag() and tag = CatchTag() and
kind instanceof GotoEdge and result = this.getBlock().getFirstInstruction(kind)
result = this.getBlock().getFirstInstruction()
} }
} }
class TranslatedIfStmt extends TranslatedStmt, ConditionContext { class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
override IfStmt stmt; override IfStmt stmt;
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if this.hasInitialization() if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction() then result = this.getInitialization().getFirstInstruction(kind)
else result = this.getFirstConditionInstruction() else result = this.getFirstConditionInstruction(kind)
} }
override TranslatedElement getChild(int id) { override TranslatedElement getChild(int id) {
@@ -724,8 +737,8 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
result = getTranslatedCondition(stmt.getCondition().getFullyConverted()) result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
} }
private Instruction getFirstConditionInstruction() { private Instruction getFirstConditionInstruction(EdgeKind kind) {
result = this.getCondition().getFirstInstruction() result = this.getCondition().getFirstInstruction(kind)
} }
private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) } private TranslatedStmt getThen() { result = getTranslatedStmt(stmt.getThen()) }
@@ -736,24 +749,24 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) { override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and child = this.getCondition() and
result = this.getThen().getFirstInstruction() result = this.getThen().getFirstInstruction(kind)
} }
override Instruction getChildFalseSuccessor(TranslatedCondition child) { override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and child = this.getCondition() and
if this.hasElse() if this.hasElse()
then result = this.getElse().getFirstInstruction() then result = this.getElse().getFirstInstruction(kind)
else result = this.getParent().getChildSuccessor(this) else result = this.getParent().getChildSuccessor(this, kind)
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and child = this.getInitialization() and
result = this.getFirstConditionInstruction() result = this.getFirstConditionInstruction(kind)
or or
(child = this.getThen() or child = this.getElse()) and (child = this.getThen() or child = this.getElse()) and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -770,10 +783,10 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) } final TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
final Instruction getFirstConditionInstruction() { final Instruction getFirstConditionInstruction(EdgeKind kind) {
if this.hasCondition() if this.hasCondition()
then result = this.getCondition().getFirstInstruction() then result = this.getCondition().getFirstInstruction(kind)
else result = this.getBody().getFirstInstruction() else result = this.getBody().getFirstInstruction(kind)
} }
final predicate hasCondition() { exists(stmt.getCondition()) } final predicate hasCondition() { exists(stmt.getCondition()) }
@@ -790,32 +803,39 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
final override Instruction getChildTrueSuccessor(TranslatedCondition child) { final override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and result = this.getBody().getFirstInstruction() child = this.getCondition() and result = this.getBody().getFirstInstruction(kind)
} }
final override Instruction getChildFalseSuccessor(TranslatedCondition child) { final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and result = this.getParent().getChildSuccessor(this) child = this.getCondition() and
result = this.getParent().getChildSuccessor(this, kind)
} }
} }
class TranslatedWhileStmt extends TranslatedLoop { class TranslatedWhileStmt extends TranslatedLoop {
TranslatedWhileStmt() { stmt instanceof WhileStmt } TranslatedWhileStmt() { stmt instanceof WhileStmt }
override Instruction getFirstInstruction() { result = this.getFirstConditionInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getFirstConditionInstruction(kind)
}
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getBody() and result = this.getFirstConditionInstruction() child = this.getBody() and
result = this.getFirstConditionInstruction(kind)
} }
} }
class TranslatedDoStmt extends TranslatedLoop { class TranslatedDoStmt extends TranslatedLoop {
TranslatedDoStmt() { stmt instanceof DoStmt } TranslatedDoStmt() { stmt instanceof DoStmt }
override Instruction getFirstInstruction() { result = this.getBody().getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getBody().getFirstInstruction(kind)
}
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getBody() and result = this.getFirstConditionInstruction() child = this.getBody() and
result = this.getFirstConditionInstruction(kind)
} }
} }
@@ -842,24 +862,24 @@ class TranslatedForStmt extends TranslatedLoop {
private predicate hasUpdate() { exists(stmt.getUpdate()) } private predicate hasUpdate() { exists(stmt.getUpdate()) }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if this.hasInitialization() if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction() then result = this.getInitialization().getFirstInstruction(kind)
else result = this.getFirstConditionInstruction() else result = this.getFirstConditionInstruction(kind)
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and child = this.getInitialization() and
result = this.getFirstConditionInstruction() result = this.getFirstConditionInstruction(kind)
or or
( (
child = this.getBody() and child = this.getBody() and
if this.hasUpdate() if this.hasUpdate()
then result = this.getUpdate().getFirstInstruction() then result = this.getUpdate().getFirstInstruction(kind)
else result = this.getFirstConditionInstruction() else result = this.getFirstConditionInstruction(kind)
) )
or or
child = this.getUpdate() and result = this.getFirstConditionInstruction() child = this.getUpdate() and result = this.getFirstConditionInstruction(kind)
} }
} }
@@ -888,25 +908,25 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
id = 5 and result = this.getBody() id = 5 and result = this.getBody()
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getRangeVariableDeclStmt().getFirstInstruction() result = this.getRangeVariableDeclStmt().getFirstInstruction(kind)
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getRangeVariableDeclStmt() and child = this.getRangeVariableDeclStmt() and
result = this.getBeginEndVariableDeclStmt().getFirstInstruction() result = this.getBeginEndVariableDeclStmt().getFirstInstruction(kind)
or or
child = this.getBeginEndVariableDeclStmt() and child = this.getBeginEndVariableDeclStmt() and
result = this.getCondition().getFirstInstruction() result = this.getCondition().getFirstInstruction(kind)
or or
child = this.getVariableDeclStmt() and child = this.getVariableDeclStmt() and
result = this.getBody().getFirstInstruction() result = this.getBody().getFirstInstruction(kind)
or or
child = this.getBody() and child = this.getBody() and
result = this.getUpdate().getFirstInstruction() result = this.getUpdate().getFirstInstruction(kind)
or or
child = this.getUpdate() and child = this.getUpdate() and
result = this.getCondition().getFirstInstruction() result = this.getCondition().getFirstInstruction(kind)
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -915,12 +935,14 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildTrueSuccessor(TranslatedCondition child) { override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and result = this.getVariableDeclStmt().getFirstInstruction() child = this.getCondition() and
result = this.getVariableDeclStmt().getFirstInstruction(kind)
} }
override Instruction getChildFalseSuccessor(TranslatedCondition child) { override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
child = this.getCondition() and result = this.getParent().getChildSuccessor(this) child = this.getCondition() and
result = this.getParent().getChildSuccessor(this, kind)
} }
private TranslatedDeclStmt getRangeVariableDeclStmt() { private TranslatedDeclStmt getRangeVariableDeclStmt() {
@@ -960,7 +982,10 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
class TranslatedJumpStmt extends TranslatedStmt { class TranslatedJumpStmt extends TranslatedStmt {
override JumpStmt stmt; override JumpStmt stmt;
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
override TranslatedElement getChild(int id) { none() } override TranslatedElement getChild(int id) { none() }
@@ -972,11 +997,10 @@ class TranslatedJumpStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
kind instanceof GotoEdge and result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind)
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction()
} }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
} }
private EdgeKind getCaseEdge(SwitchCase switchCase) { private EdgeKind getCaseEdge(SwitchCase switchCase) {
@@ -995,14 +1019,16 @@ class TranslatedSwitchStmt extends TranslatedStmt {
result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) result = getTranslatedExpr(stmt.getExpr().getFullyConverted())
} }
private Instruction getFirstExprInstruction() { result = this.getExpr().getFirstInstruction() } private Instruction getFirstExprInstruction(EdgeKind kind) {
result = this.getExpr().getFirstInstruction(kind)
}
private TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) } private TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if this.hasInitialization() if this.hasInitialization()
then result = this.getInitialization().getFirstInstruction() then result = this.getInitialization().getFirstInstruction(kind)
else result = this.getFirstExprInstruction() else result = this.getFirstExprInstruction(kind)
} }
override TranslatedElement getChild(int id) { override TranslatedElement getChild(int id) {
@@ -1036,21 +1062,24 @@ class TranslatedSwitchStmt extends TranslatedStmt {
exists(SwitchCase switchCase | exists(SwitchCase switchCase |
switchCase = stmt.getASwitchCase() and switchCase = stmt.getASwitchCase() and
kind = getCaseEdge(switchCase) and kind = getCaseEdge(switchCase) and
result = getTranslatedStmt(switchCase).getFirstInstruction() result = getTranslatedStmt(switchCase).getFirstInstruction(any(GotoEdge edge))
) )
or or
not stmt.hasDefaultCase() and not stmt.hasDefaultCase() and
tag = SwitchBranchTag() and tag = SwitchBranchTag() and
kind instanceof DefaultEdge and kind instanceof DefaultEdge and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getInitialization() and result = this.getFirstExprInstruction() child = this.getInitialization() and
result = this.getFirstExprInstruction(kind)
or or
child = this.getExpr() and result = this.getInstruction(SwitchBranchTag()) kind instanceof GotoEdge and
child = this.getExpr() and
result = this.getInstruction(SwitchBranchTag())
or or
child = this.getBody() and result = this.getParent().getChildSuccessor(this) child = this.getBody() and result = this.getParent().getChildSuccessor(this, kind)
} }
} }
@@ -1061,10 +1090,12 @@ class TranslatedAsmStmt extends TranslatedStmt {
result = getTranslatedExpr(stmt.getChild(id).(Expr).getFullyConverted()) result = getTranslatedExpr(stmt.getChild(id).(Expr).getFullyConverted())
} }
override Instruction getFirstInstruction() { override Instruction getFirstInstruction(EdgeKind kind) {
if exists(this.getChild(0)) if exists(this.getChild(0))
then result = this.getChild(0).getFirstInstruction() then result = this.getChild(0).getFirstInstruction(kind)
else result = this.getInstruction(AsmTag()) else (
kind instanceof GotoEdge and result = this.getInstruction(AsmTag())
)
} }
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -1091,16 +1122,17 @@ class TranslatedAsmStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = AsmTag() and tag = AsmTag() and
result = this.getParent().getChildSuccessor(this) and result = this.getParent().getChildSuccessor(this, kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
exists(int index | exists(int index |
child = this.getChild(index) and child = this.getChild(index) and
if exists(this.getChild(index + 1)) if exists(this.getChild(index + 1))
then result = this.getChild(index + 1).getFirstInstruction() then result = this.getChild(index + 1).getFirstInstruction(kind)
else result = this.getInstruction(AsmTag()) else (
kind instanceof GotoEdge and result = this.getInstruction(AsmTag())
)
) )
} }
} }
@@ -1113,7 +1145,9 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted()) result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted())
} }
override Instruction getFirstInstruction() { result = this.getChild(0).getFirstInstruction() } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getChild(0).getFirstInstruction(kind)
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
none() none()
@@ -1121,9 +1155,9 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
override Instruction getChildSuccessor(TranslatedElement child) { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
child = this.getChild(0) and child = this.getChild(0) and
result = this.getParent().getChildSuccessor(this) result = this.getParent().getChildSuccessor(this, kind)
} }
} }
@@ -1132,7 +1166,10 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt {
override TranslatedExpr getChild(int id) { none() } override TranslatedExpr getChild(int id) { none() }
override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } override Instruction getFirstInstruction(EdgeKind kind) {
result = this.getInstruction(OnlyInstructionTag()) and
kind instanceof GotoEdge
}
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
// TODO: This needs a new kind of instruction that represents initialization of a VLA. // TODO: This needs a new kind of instruction that represents initialization of a VLA.
@@ -1144,9 +1181,8 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt {
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
tag = OnlyInstructionTag() and tag = OnlyInstructionTag() and
result = this.getParent().getChildSuccessor(this) and result = this.getParent().getChildSuccessor(this, kind)
kind instanceof GotoEdge
} }
override Instruction getChildSuccessor(TranslatedElement child) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
} }

View File

@@ -39,3 +39,4 @@ private import implementations.ODBC
private import implementations.SqLite3 private import implementations.SqLite3
private import implementations.PostgreSql private import implementations.PostgreSql
private import implementations.System private import implementations.System
private import implementations.StructuredExceptionHandling

View File

@@ -0,0 +1,9 @@
import semmle.code.cpp.models.interfaces.Throwing
class WindowsDriverFunction extends ThrowingFunction {
WindowsDriverFunction() {
this.hasGlobalName(["RaiseException", "ExRaiseAccessViolation", "ExRaiseDatatypeMisalignment"])
}
final override predicate mayThrowException(boolean unconditional) { unconditional = true }
}

View File

@@ -0,0 +1,22 @@
/**
* Provides an abstract class for modeling whether a function may throw an
* exception.
* To use this QL library, create a QL class extending `ThrowingFunction` with
* a characteristic predicate that selects the function or set of functions you
* are modeling the exceptional flow of.
*/
import semmle.code.cpp.Function
import semmle.code.cpp.models.Models
import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs
/**
* A class that models the exceptional behavior of a function.
*/
abstract class ThrowingFunction extends Function {
/**
* Holds if this function may throw an exception during evaluation.
* If `unconditional` is `true` the function always throws an exception.
*/
abstract predicate mayThrowException(boolean unconditional);
}

View File

@@ -1815,6 +1815,42 @@ ir.c:
# 15| Type = [CharPointerType] char * # 15| Type = [CharPointerType] char *
# 15| ValueCategory = prvalue # 15| ValueCategory = prvalue
# 16| getStmt(1): [ReturnStmt] return ... # 16| getStmt(1): [ReturnStmt] return ...
# 18| [TopLevelFunction] void ExRaiseAccessViolation(int)
# 18| <params>:
# 18| getParameter(0): [Parameter] (unnamed parameter 0)
# 18| Type = [IntType] int
# 21| [TopLevelFunction] int TryExceptTest(int)
# 21| <params>:
# 21| getParameter(0): [Parameter] x
# 21| Type = [IntType] int
# 21| getEntryPoint(): [BlockStmt] { ... }
# 22| getStmt(0): [DeclStmt] declaration
# 22| getDeclarationEntry(0): [VariableDeclarationEntry] definition of localPtr
# 22| Type = [IntPointerType] int *
# 24| getStmt(1): [MicrosoftTryExceptStmt] __try { ... } __except( ... ) { ... }
# 24| getStmt(): [BlockStmt] { ... }
# 25| getStmt(0): [ExprStmt] ExprStmt
# 25| getExpr(): [FunctionCall] call to ExRaiseAccessViolation
# 25| Type = [VoidType] void
# 25| ValueCategory = prvalue
# 25| getArgument(0): [VariableAccess] x
# 25| Type = [IntType] int
# 25| ValueCategory = prvalue(load)
# 26| getCondition(): [Literal] 1
# 26| Type = [IntType] int
# 26| Value = [Literal] 1
# 26| ValueCategory = prvalue
# 26| getExcept(): [BlockStmt] { ... }
# 27| getStmt(0): [ReturnStmt] return ...
# 27| getExpr(): [Literal] 1
# 27| Type = [IntType] int
# 27| Value = [Literal] 1
# 27| ValueCategory = prvalue
# 29| getStmt(2): [ReturnStmt] return ...
# 29| getExpr(): [Literal] 0
# 29| Type = [IntType] int
# 29| Value = [Literal] 0
# 29| ValueCategory = prvalue
ir.cpp: ir.cpp:
# 1| [TopLevelFunction] void Constants() # 1| [TopLevelFunction] void Constants()
# 1| <params>: # 1| <params>:

View File

@@ -809,6 +809,58 @@ ir.c:
# 13| v13_11(void) = AliasedUse : m13_3 # 13| v13_11(void) = AliasedUse : m13_3
# 13| v13_12(void) = ExitFunction : # 13| v13_12(void) = ExitFunction :
# 21| int TryExceptTest(int)
# 21| Block 0
# 21| v21_1(void) = EnterFunction :
# 21| m21_2(unknown) = AliasedDefinition :
# 21| m21_3(unknown) = InitializeNonLocal :
# 21| m21_4(unknown) = Chi : total:m21_2, partial:m21_3
# 21| r21_5(glval<int>) = VariableAddress[x] :
# 21| m21_6(int) = InitializeParameter[x] : &:r21_5
# 22| r22_1(glval<int *>) = VariableAddress[localPtr] :
# 22| m22_2(int *) = Uninitialized[localPtr] : &:r22_1
# 25| r25_1(glval<unknown>) = FunctionAddress[ExRaiseAccessViolation] :
# 25| r25_2(glval<int>) = VariableAddress[x] :
# 25| r25_3(int) = Load[x] : &:r25_2, m21_6
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
# 25| m25_5(unknown) = ^CallSideEffect : ~m21_4
# 25| m25_6(unknown) = Chi : total:m21_4, partial:m25_5
#-----| Exception -> Block 3
# 26| Block 1
# 26| r26_1(int) = Constant[0] :
# 26| r26_2(bool) = CompareEQ : r26_7, r26_1
# 26| v26_3(void) = ConditionalBranch : r26_2
#-----| False -> Block 2
#-----| True -> Block 5
# 26| Block 2
# 26| r26_4(int) = Constant[1] :
# 26| r26_5(bool) = CompareEQ : r26_7, r26_4
# 26| v26_6(void) = ConditionalBranch : r26_5
#-----| False -> Block 5
#-----| True -> Block 4
# 26| Block 3
# 26| r26_7(int) = Constant[1] :
# 26| r26_8(int) = Constant[-1] :
# 26| r26_9(bool) = CompareEQ : r26_7, r26_8
# 26| v26_10(void) = ConditionalBranch : r26_9
#-----| False -> Block 1
#-----| True -> Block 5
# 27| Block 4
# 27| r27_1(glval<int>) = VariableAddress[#return] :
# 27| r27_2(int) = Constant[1] :
# 27| m27_3(int) = Store[#return] : &:r27_1, r27_2
# 21| r21_7(glval<int>) = VariableAddress[#return] :
# 21| v21_8(void) = ReturnValue : &:r21_7, m27_3
# 21| v21_9(void) = AliasedUse : ~m25_6
# 21| v21_10(void) = ExitFunction :
# 21| Block 5
# 21| v21_11(void) = Unreached :
ir.cpp: ir.cpp:
# 1| void Constants() # 1| void Constants()
# 1| Block 0 # 1| Block 0

View File

@@ -15,4 +15,18 @@ void CStyleCast(void *src)
char *dst = (char*)src; char *dst = (char*)src;
} }
void ExRaiseAccessViolation(int);
#define EXCEPTION_EXECUTE_HANDLER 1
int TryExceptTest(int x) {
int *localPtr;
__try {
ExRaiseAccessViolation(x);
} __except(EXCEPTION_EXECUTE_HANDLER) {
return 1;
}
return 0;
}
// semmle-extractor-options: --microsoft // semmle-extractor-options: --microsoft

View File

@@ -1005,6 +1005,31 @@
| ir.c:15:24:15:26 | Address | &:r15_2 | | ir.c:15:24:15:26 | Address | &:r15_2 |
| ir.c:15:24:15:26 | Load | m13_6 | | ir.c:15:24:15:26 | Load | m13_6 |
| ir.c:15:24:15:26 | Unary | r15_3 | | ir.c:15:24:15:26 | Unary | r15_3 |
| ir.c:21:5:21:17 | Address | &:r21_7 |
| ir.c:21:5:21:17 | ChiPartial | partial:m21_3 |
| ir.c:21:5:21:17 | ChiTotal | total:m21_2 |
| ir.c:21:5:21:17 | Load | m27_3 |
| ir.c:21:5:21:17 | SideEffect | ~m25_6 |
| ir.c:21:23:21:23 | Address | &:r21_5 |
| ir.c:22:8:22:15 | Address | &:r22_1 |
| ir.c:25:5:25:26 | CallTarget | func:r25_1 |
| ir.c:25:5:25:26 | ChiPartial | partial:m25_5 |
| ir.c:25:5:25:26 | ChiTotal | total:m21_4 |
| ir.c:25:5:25:26 | SideEffect | ~m21_4 |
| ir.c:25:28:25:28 | Address | &:r25_2 |
| ir.c:25:28:25:28 | Arg(0) | 0:r25_3 |
| ir.c:25:28:25:28 | Load | m21_6 |
| ir.c:26:14:26:38 | Left | r26_7 |
| ir.c:26:14:26:38 | Left | r26_7 |
| ir.c:26:14:26:38 | Left | r26_7 |
| ir.c:26:41:28:3 | Condition | r26_2 |
| ir.c:26:41:28:3 | Condition | r26_5 |
| ir.c:26:41:28:3 | Condition | r26_9 |
| ir.c:26:41:28:3 | Right | r26_1 |
| ir.c:26:41:28:3 | Right | r26_4 |
| ir.c:26:41:28:3 | Right | r26_8 |
| ir.c:27:5:27:13 | Address | &:r27_1 |
| ir.c:27:12:27:12 | StoreValue | r27_2 |
| ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 | | ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 |
| ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 | | ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 |
| ir.cpp:1:6:1:14 | SideEffect | m1_3 | | ir.cpp:1:6:1:14 | SideEffect | m1_3 |

View File

@@ -786,6 +786,62 @@ ir.c:
# 13| v13_10(void) = AliasedUse : ~m? # 13| v13_10(void) = AliasedUse : ~m?
# 13| v13_11(void) = ExitFunction : # 13| v13_11(void) = ExitFunction :
# 21| int TryExceptTest(int)
# 21| Block 0
# 21| v21_1(void) = EnterFunction :
# 21| mu21_2(unknown) = AliasedDefinition :
# 21| mu21_3(unknown) = InitializeNonLocal :
# 21| r21_4(glval<int>) = VariableAddress[x] :
# 21| mu21_5(int) = InitializeParameter[x] : &:r21_4
# 22| r22_1(glval<int *>) = VariableAddress[localPtr] :
# 22| mu22_2(int *) = Uninitialized[localPtr] : &:r22_1
# 25| r25_1(glval<unknown>) = FunctionAddress[ExRaiseAccessViolation] :
# 25| r25_2(glval<int>) = VariableAddress[x] :
# 25| r25_3(int) = Load[x] : &:r25_2, ~m?
# 25| v25_4(void) = Call[ExRaiseAccessViolation] : func:r25_1, 0:r25_3
# 25| mu25_5(unknown) = ^CallSideEffect : ~m?
#-----| Exception -> Block 5
# 21| Block 1
# 21| r21_6(glval<int>) = VariableAddress[#return] :
# 21| v21_7(void) = ReturnValue : &:r21_6, ~m?
# 21| v21_8(void) = AliasedUse : ~m?
# 21| v21_9(void) = ExitFunction :
# 26| Block 2
# 26| r26_1(int) = Constant[0] :
# 26| r26_2(bool) = CompareEQ : r26_8, r26_1
# 26| v26_3(void) = ConditionalBranch : r26_2
#-----| False -> Block 3
#-----| True -> Block 4
# 26| Block 3
# 26| r26_4(int) = Constant[1] :
# 26| r26_5(bool) = CompareEQ : r26_8, r26_4
# 26| v26_6(void) = ConditionalBranch : r26_5
#-----| True -> Block 6
# 26| Block 4
# 26| v26_7(void) = Unwind :
# 29| r29_1(glval<int>) = VariableAddress[#return] :
# 29| r29_2(int) = Constant[0] :
# 29| mu29_3(int) = Store[#return] : &:r29_1, r29_2
#-----| Goto -> Block 1
# 26| Block 5
# 26| r26_8(int) = Constant[1] :
# 26| r26_9(int) = Constant[-1] :
# 26| r26_10(bool) = CompareEQ : r26_8, r26_9
# 26| v26_11(void) = ConditionalBranch : r26_10
#-----| False -> Block 2
#-----| True -> Block 4
# 27| Block 6
# 27| r27_1(glval<int>) = VariableAddress[#return] :
# 27| r27_2(int) = Constant[1] :
# 27| mu27_3(int) = Store[#return] : &:r27_1, r27_2
#-----| Goto -> Block 1
ir.cpp: ir.cpp:
# 1| void Constants() # 1| void Constants()
# 1| Block 0 # 1| Block 0