mirror of
https://github.com/github/codeql.git
synced 2025-12-22 03:36:30 +01:00
Merge pull request #15461 from MathiasVP/propagate-edge-kinds
C++: Support function calls throwing exceptions in the IR
This commit is contained in:
4
cpp/ql/lib/change-notes/2024-01-30-throwing-model.md
Normal file
4
cpp/ql/lib/change-notes/2024-01-30-throwing-model.md
Normal 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.
|
||||
@@ -285,7 +285,7 @@ private predicate backEdgeCandidate(
|
||||
// is a back edge. This includes edges from `continue` and the fall-through
|
||||
// edge(s) after the last instruction(s) in the body.
|
||||
exists(TranslatedWhileStmt s |
|
||||
targetInstruction = s.getFirstConditionInstruction() and
|
||||
targetInstruction = s.getFirstConditionInstruction(_) and
|
||||
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
|
||||
requiredAncestor = s.getBody()
|
||||
)
|
||||
@@ -296,7 +296,7 @@ private predicate backEdgeCandidate(
|
||||
// { ... } while (0)` statement. Note that all `continue` statements in a
|
||||
// do-while loop produce forward edges.
|
||||
exists(TranslatedDoStmt s |
|
||||
targetInstruction = s.getBody().getFirstInstruction() and
|
||||
targetInstruction = s.getBody().getFirstInstruction(_) and
|
||||
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
|
||||
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
|
||||
// which case `getFirstConditionInstruction` returns the body instead.
|
||||
exists(TranslatedForStmt s |
|
||||
targetInstruction = s.getFirstConditionInstruction() and
|
||||
targetInstruction = s.getFirstConditionInstruction(_) and
|
||||
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
|
||||
(
|
||||
requiredAncestor = s.getUpdate()
|
||||
@@ -322,7 +322,7 @@ private predicate backEdgeCandidate(
|
||||
// Any edge from within the update of the loop to the condition of
|
||||
// the loop is a back edge.
|
||||
exists(TranslatedRangeBasedForStmt s |
|
||||
targetInstruction = s.getCondition().getFirstInstruction() and
|
||||
targetInstruction = s.getCondition().getFirstInstruction(_) and
|
||||
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
|
||||
requiredAncestor = s.getUpdate()
|
||||
)
|
||||
|
||||
@@ -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.internal.CppType
|
||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import semmle.code.cpp.models.interfaces.Throwing
|
||||
private import InstructionTag
|
||||
private import SideEffects
|
||||
private import TranslatedElement
|
||||
@@ -40,10 +41,10 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
id = this.getNumberOfArguments() and result = this.getSideEffects()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if exists(this.getQualifier())
|
||||
then result = this.getQualifier().getFirstInstruction()
|
||||
else result = this.getFirstCallTargetInstruction()
|
||||
then result = this.getQualifier().getFirstInstruction(kind)
|
||||
else result = this.getFirstCallTargetInstruction(kind)
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
@@ -52,34 +53,43 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
resultType = getTypeForPRValue(this.getCallResultType())
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getQualifier() and
|
||||
result = this.getFirstCallTargetInstruction()
|
||||
result = this.getFirstCallTargetInstruction(kind)
|
||||
or
|
||||
child = this.getCallTarget() and
|
||||
result = this.getFirstArgumentOrCallInstruction()
|
||||
result = this.getFirstArgumentOrCallInstruction(kind)
|
||||
or
|
||||
exists(int argIndex |
|
||||
child = this.getArgument(argIndex) and
|
||||
if exists(this.getArgument(argIndex + 1))
|
||||
then result = this.getArgument(argIndex + 1).getFirstInstruction()
|
||||
else result = this.getInstruction(CallTag())
|
||||
then result = this.getArgument(argIndex + 1).getFirstInstruction(kind)
|
||||
else (
|
||||
result = this.getInstruction(CallTag()) and kind instanceof GotoEdge
|
||||
)
|
||||
)
|
||||
or
|
||||
child = this.getSideEffects() and
|
||||
if this.isNoReturn()
|
||||
then
|
||||
kind instanceof GotoEdge and
|
||||
result =
|
||||
any(UnreachedInstruction instr |
|
||||
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) {
|
||||
kind instanceof GotoEdge and
|
||||
tag = CallTag() and
|
||||
result = this.getSideEffects().getFirstInstruction()
|
||||
result = this.getSideEffects().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
@@ -100,6 +110,16 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
|
||||
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.
|
||||
*/
|
||||
@@ -121,8 +141,8 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
* 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).
|
||||
*/
|
||||
Instruction getFirstCallTargetInstruction() {
|
||||
result = this.getCallTarget().getFirstInstruction()
|
||||
Instruction getFirstCallTargetInstruction(EdgeKind kind) {
|
||||
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
|
||||
* argument. Otherwise, returns the call instruction.
|
||||
*/
|
||||
final Instruction getFirstArgumentOrCallInstruction() {
|
||||
final Instruction getFirstArgumentOrCallInstruction(EdgeKind kind) {
|
||||
if this.hasArguments()
|
||||
then result = this.getArgument(0).getFirstInstruction()
|
||||
else result = this.getInstruction(CallTag())
|
||||
then result = this.getArgument(0).getFirstInstruction(kind)
|
||||
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 |
|
||||
this.getChild(i) = te and
|
||||
if exists(this.getChild(i + 1))
|
||||
then result = this.getChild(i + 1).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getChild(i + 1).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -216,11 +238,12 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getChild(0).getFirstInstruction()
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getChild(0).getFirstInstruction(kind)
|
||||
or
|
||||
// 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() }
|
||||
@@ -235,8 +258,9 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
* (`TranslatedAllocatorCall`).
|
||||
*/
|
||||
abstract class TranslatedDirectCall extends TranslatedCall {
|
||||
final override Instruction getFirstCallTargetInstruction() {
|
||||
result = this.getInstruction(CallTargetTag())
|
||||
final override Instruction getFirstCallTargetInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(CallTargetTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
|
||||
@@ -253,8 +277,7 @@ abstract class TranslatedDirectCall extends TranslatedCall {
|
||||
result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
|
||||
or
|
||||
tag = CallTargetTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getFirstArgumentOrCallInstruction()
|
||||
result = this.getFirstArgumentOrCallInstruction(kind)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,6 +313,15 @@ class TranslatedExprCall extends TranslatedCallExpr {
|
||||
override TranslatedExpr getCallTarget() {
|
||||
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
|
||||
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 {
|
||||
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() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
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) {
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
tag = OnlyInstructionTag() and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this, kind) and
|
||||
tag = OnlyInstructionTag()
|
||||
}
|
||||
|
||||
final override Declaration getFunction() { result = this.getParent().getFunction() }
|
||||
|
||||
@@ -7,9 +7,17 @@ private import TranslatedElement
|
||||
private import TranslatedExpr
|
||||
|
||||
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 }
|
||||
@@ -44,8 +52,8 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getOperand().getFirstInstruction()
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
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 getChildSuccessor(TranslatedElement child) { none() }
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
abstract TranslatedCondition getOperand();
|
||||
}
|
||||
@@ -62,14 +70,14 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
|
||||
class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
|
||||
override ParenthesisExpr expr;
|
||||
|
||||
final override Instruction getChildTrueSuccessor(TranslatedCondition child) {
|
||||
final override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
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
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this)
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override TranslatedCondition getOperand() {
|
||||
@@ -80,7 +88,7 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
|
||||
abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition {
|
||||
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 {
|
||||
@@ -92,8 +100,8 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
|
||||
id = 1 and result = this.getRightOperand()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getLeftOperand().getFirstInstruction()
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getLeftOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
@@ -114,34 +122,34 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
|
||||
class TranslatedLogicalAndExpr extends TranslatedBinaryLogicalOperation {
|
||||
TranslatedLogicalAndExpr() { expr instanceof LogicalAndExpr }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getLeftOperand() and
|
||||
result = this.getRightOperand().getFirstInstruction()
|
||||
result = this.getRightOperand().getFirstInstruction(kind)
|
||||
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() or child = this.getRightOperand()) and
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this)
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this, kind)
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation {
|
||||
override LogicalOrExpr expr;
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
(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
|
||||
result = this.getRightOperand().getFirstInstruction()
|
||||
result = this.getRightOperand().getFirstInstruction(kind)
|
||||
or
|
||||
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 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) {
|
||||
tag = ValueConditionConditionalBranchTag() and
|
||||
@@ -158,19 +168,20 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getValueExpr() and
|
||||
result = this.getInstruction(ValueConditionConditionalBranchTag())
|
||||
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = ValueConditionConditionalBranchTag() and
|
||||
(
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getConditionContext().getChildTrueSuccessor(this)
|
||||
result = this.getConditionContext().getChildTrueSuccessor(this, any(GotoEdge edge))
|
||||
or
|
||||
kind instanceof FalseEdge and
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this)
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this, any(GotoEdge edge))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
|
||||
getTranslatedInitialization(this.getVariable().getInitializer().getExpr().getFullyConverted())
|
||||
}
|
||||
|
||||
final override Instruction getInitializationSuccessor() {
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
final override Instruction getInitializationSuccessor(EdgeKind kind) {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override IRVariable getIRVariable() {
|
||||
@@ -147,8 +147,9 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
type = getBoolType()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(DynamicInitializationFlagAddressTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(DynamicInitializationFlagAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
@@ -163,10 +164,10 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
tag = DynamicInitializationConditionalBranchTag() and
|
||||
(
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
|
||||
or
|
||||
kind instanceof FalseEdge and
|
||||
result = this.getInitialization().getFirstInstruction()
|
||||
result = this.getInitialization().getFirstInstruction(any(GotoEdge edge))
|
||||
)
|
||||
or
|
||||
tag = DynamicInitializationFlagConstantTag() and
|
||||
@@ -174,13 +175,13 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
result = this.getInstruction(DynamicInitializationFlagStoreTag())
|
||||
or
|
||||
tag = DynamicInitializationFlagStoreTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getInstruction(DynamicInitializationFlagConstantTag())
|
||||
result = this.getInstruction(DynamicInitializationFlagConstantTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override IRDynamicInitializationFlag getInstructionVariable(InstructionTag tag) {
|
||||
|
||||
@@ -827,9 +827,10 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
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.
|
||||
@@ -904,18 +905,19 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* within this element. This will generally return first `catch` block of the
|
||||
* 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() {
|
||||
result = this.getParent().getExceptionSuccessorInstruction()
|
||||
Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
|
||||
result = this.getParent().getExceptionSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -109,8 +109,9 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
result = getTranslatedEllipsisParameter(func)
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(EnterFunctionTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(EnterFunctionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
@@ -121,17 +122,20 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
or
|
||||
tag = AliasedDefinitionTag() and
|
||||
result = this.getInstruction(InitializeNonLocalTag())
|
||||
)
|
||||
or
|
||||
(
|
||||
tag = InitializeNonLocalTag() and
|
||||
if exists(this.getThisType())
|
||||
then result = this.getParameter(-1).getFirstInstruction()
|
||||
then result = this.getParameter(-1).getFirstInstruction(kind)
|
||||
else
|
||||
if exists(this.getParameter(0))
|
||||
then result = this.getParameter(0).getFirstInstruction()
|
||||
else result = this.getBody().getFirstInstruction()
|
||||
then result = this.getParameter(0).getFirstInstruction(kind)
|
||||
else result = this.getBody().getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = ReturnValueAddressTag() and
|
||||
result = this.getInstruction(ReturnTag())
|
||||
or
|
||||
@@ -146,25 +150,25 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
exists(int paramIndex |
|
||||
child = this.getParameter(paramIndex) and
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int paramIndex | child = this.getParameter(paramIndex) |
|
||||
if
|
||||
exists(func.getParameter(paramIndex + 1)) or
|
||||
getEllipsisParameterIndexForFunction(func) = paramIndex + 1
|
||||
then result = this.getParameter(paramIndex + 1).getFirstInstruction()
|
||||
else result = this.getConstructorInitList().getFirstInstruction()
|
||||
then result = this.getParameter(paramIndex + 1).getFirstInstruction(kind)
|
||||
else result = this.getConstructorInitList().getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
child = this.getConstructorInitList() and
|
||||
result = this.getBody().getFirstInstruction()
|
||||
result = this.getBody().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getBody() and
|
||||
result = this.getReturnSuccessorInstruction()
|
||||
result = this.getReturnSuccessorInstruction(kind)
|
||||
or
|
||||
child = this.getDestructorDestructionList() and
|
||||
result = this.getReadEffects().getFirstInstruction()
|
||||
result = this.getReadEffects().getFirstInstruction(kind)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
child = this.getReadEffects() and
|
||||
if this.hasReturnValue()
|
||||
then result = this.getInstruction(ReturnValueAddressTag())
|
||||
@@ -218,8 +222,9 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getExceptionSuccessorInstruction() {
|
||||
result = this.getInstruction(UnwindTag())
|
||||
final override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(UnwindTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
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`
|
||||
* statement.
|
||||
*/
|
||||
final Instruction getReturnSuccessorInstruction() {
|
||||
result = this.getDestructorDestructionList().getFirstInstruction()
|
||||
final Instruction getReturnSuccessorInstruction(EdgeKind kind) {
|
||||
result = this.getDestructorDestructionList().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,30 +374,30 @@ TranslatedEllipsisParameter getTranslatedEllipsisParameter(Function func) {
|
||||
abstract class TranslatedParameter extends TranslatedElement {
|
||||
final override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(InitializerVariableAddressTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(InitializerVariableAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
or
|
||||
tag = InitializerStoreTag() and
|
||||
if this.hasIndirection()
|
||||
then result = this.getInstruction(InitializerIndirectAddressTag())
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then kind instanceof GotoEdge and result = this.getInstruction(InitializerIndirectAddressTag())
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
tag = InitializerIndirectAddressTag() and
|
||||
result = this.getInstruction(InitializerIndirectStoreTag())
|
||||
or
|
||||
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) {
|
||||
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))
|
||||
then result = this.getChild(0).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getChild(0).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
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 getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
if exists(this.getChild(id + 1))
|
||||
then result = this.getChild(id + 1).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
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))
|
||||
then result = this.getChild(0).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getChild(0).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
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 getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
if exists(this.getChild(id + 1))
|
||||
then result = this.getChild(id + 1).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -714,16 +719,16 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
result = getTranslatedParameterReadEffect(func.getParameter(id))
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if exists(this.getAChild())
|
||||
then
|
||||
result =
|
||||
min(TranslatedElement child, int id | child = this.getChild(id) | child order by id)
|
||||
.getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
.getFirstInstruction(kind)
|
||||
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) |
|
||||
if exists(TranslatedReadEffect child2, int id2 | id2 > id and child2 = this.getChild(id2))
|
||||
then
|
||||
@@ -732,8 +737,8 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
child2 = this.getChild(id2) and id2 > id
|
||||
|
|
||||
child2 order by id2
|
||||
).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -755,15 +760,17 @@ private TranslatedParameterReadEffect getTranslatedParameterReadEffect(Parameter
|
||||
abstract class TranslatedReadEffect extends TranslatedElement {
|
||||
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) {
|
||||
tag = OnlyInstructionTag() and
|
||||
kind = EdgeKind::gotoEdge() and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
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) {
|
||||
opcode instanceof Opcode::ReturnIndirection and
|
||||
|
||||
@@ -22,7 +22,10 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
|
||||
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) {
|
||||
n = 1 and
|
||||
@@ -63,10 +66,13 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
or
|
||||
tag = AliasedDefinitionTag() and
|
||||
result = this.getInstruction(InitializerVariableAddressTag())
|
||||
)
|
||||
or
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result = this.getChild(1).getFirstInstruction()
|
||||
result = this.getChild(1).getFirstInstruction(kind)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = ReturnTag() and
|
||||
result = this.getInstruction(AliasedUseTag())
|
||||
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
|
||||
result = this.getInstruction(ReturnTag())
|
||||
result = this.getInstruction(ReturnTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override CppType getInstructionMemoryOperandType(
|
||||
|
||||
@@ -37,8 +37,9 @@ abstract class InitializationContext extends TranslatedElement {
|
||||
abstract class TranslatedVariableInitialization extends TranslatedElement, InitializationContext {
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(InitializerVariableAddressTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(InitializerVariableAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
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) {
|
||||
(
|
||||
tag = InitializerVariableAddressTag() and
|
||||
kind instanceof GotoEdge and
|
||||
if this.hasUninitializedInstruction()
|
||||
then result = this.getInstruction(InitializerStoreTag())
|
||||
else result = this.getInitialization().getFirstInstruction()
|
||||
then kind instanceof GotoEdge and result = this.getInstruction(InitializerStoreTag())
|
||||
else result = this.getInitialization().getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
this.hasUninitializedInstruction() and
|
||||
kind instanceof GotoEdge and
|
||||
tag = InitializerStoreTag() and
|
||||
(
|
||||
result = this.getInitialization().getFirstInstruction()
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getInitialization()) and result = this.getInitializationSuccessor()
|
||||
not exists(this.getInitialization()) and
|
||||
result = this.getInitializationSuccessor(kind)
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitialization() and result = this.getInitializationSuccessor()
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getInitializationSuccessor(kind)
|
||||
}
|
||||
|
||||
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.
|
||||
* 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
|
||||
@@ -168,18 +170,19 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
|
||||
* Represents the IR translation of an initialization from an initializer list.
|
||||
*/
|
||||
abstract class TranslatedListInitialization extends TranslatedInitialization, InitializationContext {
|
||||
override Instruction getFirstInstruction() {
|
||||
result = this.getChild(0).getFirstInstruction()
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getChild(0).getFirstInstruction(kind)
|
||||
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 |
|
||||
child = this.getChild(index) and
|
||||
if exists(this.getChild(index + 1))
|
||||
then result = this.getChild(index + 1).getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getChild(index + 1).getFirstInstruction(kind)
|
||||
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 Instruction getFirstInstruction() {
|
||||
result = this.getInitializer().getFirstInstruction()
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInitializer().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final TranslatedExpr getInitializer() { result = getTranslatedExpr(expr) }
|
||||
@@ -265,12 +268,13 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = InitializerStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitializer() and result = this.getInstruction(InitializerStoreTag())
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and
|
||||
result = this.getInstruction(InitializerStoreTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
@@ -335,12 +339,13 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = InitializerLoadStringTag() and
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
or
|
||||
if this.zeroInitRange(_, _)
|
||||
then (
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = InitializerStoreTag() and
|
||||
result = this.getInstruction(ZeroPadStringConstantTag())
|
||||
or
|
||||
@@ -352,18 +357,20 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
|
||||
or
|
||||
tag = ZeroPadStringElementAddressTag() and
|
||||
result = this.getInstruction(ZeroPadStringStoreTag())
|
||||
)
|
||||
or
|
||||
tag = ZeroPadStringStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
) else (
|
||||
tag = InitializerStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitializer() and result = this.getInstruction(InitializerLoadStringTag())
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and
|
||||
result = this.getInstruction(InitializerLoadStringTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
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 getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this)
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
@@ -502,8 +509,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
|
||||
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(this.getFieldAddressTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(this.getFieldAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -558,12 +566,11 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = this.getFieldAddressTag() and
|
||||
result = this.getInitialization().getFirstInstruction() and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
|
||||
@@ -608,10 +615,10 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
or
|
||||
tag = this.getFieldDefaultValueTag() and
|
||||
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
|
||||
)
|
||||
or
|
||||
tag = this.getFieldDefaultValueStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
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() }
|
||||
|
||||
@@ -667,8 +674,9 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
||||
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(this.getElementIndexTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(this.getElementIndexTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
@@ -745,12 +753,11 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
|
||||
or
|
||||
tag = this.getElementAddressTag() and
|
||||
result = this.getInitialization().getFirstInstruction() and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this)
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
|
||||
@@ -803,10 +810,10 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
or
|
||||
tag = this.getElementDefaultValueTag() and
|
||||
result = this.getInstruction(this.getElementDefaultValueStoreTag())
|
||||
)
|
||||
or
|
||||
tag = this.getElementDefaultValueStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
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() }
|
||||
|
||||
@@ -869,9 +876,9 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
|
||||
|
||||
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
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStructor {
|
||||
final override Instruction getFirstInstruction() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
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) {
|
||||
tag = OnlyInstructionTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getStructorCall().getFirstInstruction()
|
||||
result = this.getStructorCall().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
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 Instruction getFirstInstruction() {
|
||||
result = this.getStructorCall().getFirstInstruction()
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getStructorCall().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
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)" }
|
||||
|
||||
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) {
|
||||
none()
|
||||
@@ -1010,7 +1019,7 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
|
||||
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) {
|
||||
|
||||
@@ -30,7 +30,9 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
|
||||
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) {
|
||||
// t1 = -1
|
||||
@@ -192,23 +194,21 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
or
|
||||
// Branch -> Handler (the condition value is always 0, -1 or 1, and we've checked for 0 or -1 already.)
|
||||
tag = TryExceptCompareOneBranch() and
|
||||
(
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getTranslatedHandler().getFirstInstruction()
|
||||
)
|
||||
result = this.getTranslatedHandler().getFirstInstruction(any(GotoEdge edge))
|
||||
or
|
||||
// Unwind -> Parent
|
||||
tag = UnwindTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
child = this.getTranslatedCondition() and
|
||||
result = this.getInstruction(TryExceptGenerateNegativeOne())
|
||||
or
|
||||
child = this.getTranslatedHandler() and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
private TranslatedExpr getTranslatedCondition() {
|
||||
@@ -254,7 +254,10 @@ class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
|
||||
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) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -264,11 +267,10 @@ class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) { none() }
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,10 +287,11 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
result = this.getDeclarationEntry(0).getFirstInstruction()
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getDeclarationEntry(0).getFirstInstruction(kind)
|
||||
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(_)) }
|
||||
@@ -317,12 +320,12 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getDeclarationEntry(index) and
|
||||
if index = (this.getChildCount() - 1)
|
||||
then result = this.getParent().getChildSuccessor(this)
|
||||
else result = this.getDeclarationEntry(index + 1).getFirstInstruction()
|
||||
then result = this.getParent().getChildSuccessor(this, kind)
|
||||
else result = this.getDeclarationEntry(index + 1).getFirstInstruction(kind)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -338,13 +341,15 @@ class TranslatedExprStmt extends TranslatedStmt {
|
||||
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 getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
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 {
|
||||
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
|
||||
|
||||
final override Instruction getInitializationSuccessor() {
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction()
|
||||
final override Instruction getInitializationSuccessor(EdgeKind kind) {
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
|
||||
@@ -390,7 +395,9 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
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) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -400,13 +407,13 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getExpr() and
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
|
||||
@@ -423,7 +430,10 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
|
||||
|
||||
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) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -433,11 +443,10 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction() and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
final override Instruction getInitializationSuccessor() {
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction()
|
||||
final override Instruction getInitializationSuccessor(EdgeKind kind) {
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
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 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
|
||||
// there is no finally block, but if there is a finally block
|
||||
// then we go to that one.
|
||||
child = [this.getBody(), this.getHandler(_)] and
|
||||
(
|
||||
not exists(this.getFinally()) and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
or
|
||||
result = this.getFinally().getFirstInstruction()
|
||||
result = this.getFinally().getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
// And after the finally block we go to the successor of the `try`.
|
||||
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 |
|
||||
handler = this.getHandler(index) and
|
||||
result = this.getHandler(index + 1).getFirstInstruction()
|
||||
result = this.getHandler(index + 1).getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
// The last catch clause flows to the exception successor of the parent
|
||||
// of the `try`, because the exception successor of the `try` itself is
|
||||
// the first catch clause.
|
||||
handler = this.getHandler(stmt.getNumberOfCatchClauses() - 1) and
|
||||
result = this.getParent().getExceptionSuccessorInstruction()
|
||||
result = this.getParent().getExceptionSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getExceptionSuccessorInstruction() {
|
||||
result = this.getHandler(0).getFirstInstruction()
|
||||
final override Instruction getExceptionSuccessorInstruction(EdgeKind kind) {
|
||||
result = this.getHandler(0).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) }
|
||||
@@ -579,10 +590,10 @@ class TranslatedBlock extends TranslatedStmt {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if this.isEmpty()
|
||||
then result = this.getInstruction(OnlyInstructionTag())
|
||||
else result = this.getStmt(0).getFirstInstruction()
|
||||
then kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag())
|
||||
else result = this.getStmt(0).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
private predicate isEmpty() { not exists(stmt.getStmt(0)) }
|
||||
@@ -593,16 +604,15 @@ class TranslatedBlock extends TranslatedStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getStmt(index) and
|
||||
if index = (this.getStmtCount() - 1)
|
||||
then result = this.getParent().getChildSuccessor(this)
|
||||
else result = this.getStmt(index + 1).getFirstInstruction()
|
||||
then result = this.getParent().getChildSuccessor(this, kind)
|
||||
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 Instruction getFirstInstruction() { result = this.getInstruction(CatchTag()) }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getBlock() and result = this.getParent().getChildSuccessor(this)
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(CatchTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
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
|
||||
// the `try`.
|
||||
result = this.getParent().getParent().getExceptionSuccessorInstruction()
|
||||
result = this.getParent().getParent().getExceptionSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
TranslatedStmt getBlock() { result = getTranslatedStmt(stmt.getBlock()) }
|
||||
@@ -649,20 +662,21 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
|
||||
id = 0 and result = this.getParameter()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
result = super.getChildSuccessor(child)
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
result = super.getChildSuccessor(child, kind)
|
||||
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) {
|
||||
tag = CatchTag() and
|
||||
(
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getParameter().getFirstInstruction()
|
||||
result = this.getParameter().getFirstInstruction(kind)
|
||||
or
|
||||
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) {
|
||||
tag = CatchTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getBlock().getFirstInstruction()
|
||||
result = this.getBlock().getFirstInstruction(kind)
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
override IfStmt stmt;
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if this.hasInitialization()
|
||||
then result = this.getInitialization().getFirstInstruction()
|
||||
else result = this.getFirstConditionInstruction()
|
||||
then result = this.getInitialization().getFirstInstruction(kind)
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
@@ -724,8 +737,8 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
|
||||
}
|
||||
|
||||
private Instruction getFirstConditionInstruction() {
|
||||
result = this.getCondition().getFirstInstruction()
|
||||
private Instruction getFirstConditionInstruction(EdgeKind kind) {
|
||||
result = this.getCondition().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
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 getChildTrueSuccessor(TranslatedCondition child) {
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
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
|
||||
if this.hasElse()
|
||||
then result = this.getElse().getFirstInstruction()
|
||||
else result = this.getParent().getChildSuccessor(this)
|
||||
then result = this.getElse().getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction()
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
(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) {
|
||||
@@ -770,10 +783,10 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
|
||||
final TranslatedStmt getBody() { result = getTranslatedStmt(stmt.getStmt()) }
|
||||
|
||||
final Instruction getFirstConditionInstruction() {
|
||||
final Instruction getFirstConditionInstruction(EdgeKind kind) {
|
||||
if this.hasCondition()
|
||||
then result = this.getCondition().getFirstInstruction()
|
||||
else result = this.getBody().getFirstInstruction()
|
||||
then result = this.getCondition().getFirstInstruction(kind)
|
||||
else result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
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 getChildTrueSuccessor(TranslatedCondition child) {
|
||||
child = this.getCondition() and result = this.getBody().getFirstInstruction()
|
||||
final override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child) {
|
||||
child = this.getCondition() and result = this.getParent().getChildSuccessor(this)
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedWhileStmt extends TranslatedLoop {
|
||||
TranslatedWhileStmt() { stmt instanceof WhileStmt }
|
||||
|
||||
override Instruction getFirstInstruction() { result = this.getFirstConditionInstruction() }
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getBody() and result = this.getFirstConditionInstruction()
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBody() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedDoStmt extends TranslatedLoop {
|
||||
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) {
|
||||
child = this.getBody() and result = this.getFirstConditionInstruction()
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBody() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,24 +862,24 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
|
||||
private predicate hasUpdate() { exists(stmt.getUpdate()) }
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if this.hasInitialization()
|
||||
then result = this.getInitialization().getFirstInstruction()
|
||||
else result = this.getFirstConditionInstruction()
|
||||
then result = this.getInitialization().getFirstInstruction(kind)
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction()
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
(
|
||||
child = this.getBody() and
|
||||
if this.hasUpdate()
|
||||
then result = this.getUpdate().getFirstInstruction()
|
||||
else result = this.getFirstConditionInstruction()
|
||||
then result = this.getUpdate().getFirstInstruction(kind)
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
)
|
||||
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()
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
result = this.getRangeVariableDeclStmt().getFirstInstruction()
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getRangeVariableDeclStmt().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getRangeVariableDeclStmt() and
|
||||
result = this.getBeginEndVariableDeclStmt().getFirstInstruction()
|
||||
result = this.getBeginEndVariableDeclStmt().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getBeginEndVariableDeclStmt() and
|
||||
result = this.getCondition().getFirstInstruction()
|
||||
result = this.getCondition().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getVariableDeclStmt() and
|
||||
result = this.getBody().getFirstInstruction()
|
||||
result = this.getBody().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getBody() and
|
||||
result = this.getUpdate().getFirstInstruction()
|
||||
result = this.getUpdate().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getUpdate() and
|
||||
result = this.getCondition().getFirstInstruction()
|
||||
result = this.getCondition().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
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 getChildTrueSuccessor(TranslatedCondition child) {
|
||||
child = this.getCondition() and result = this.getVariableDeclStmt().getFirstInstruction()
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
result = this.getVariableDeclStmt().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
|
||||
child = this.getCondition() and result = this.getParent().getChildSuccessor(this)
|
||||
override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
private TranslatedDeclStmt getRangeVariableDeclStmt() {
|
||||
@@ -960,7 +982,10 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
class TranslatedJumpStmt extends TranslatedStmt {
|
||||
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() }
|
||||
|
||||
@@ -972,11 +997,10 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction()
|
||||
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) { none() }
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
private EdgeKind getCaseEdge(SwitchCase switchCase) {
|
||||
@@ -995,14 +1019,16 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
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()) }
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if this.hasInitialization()
|
||||
then result = this.getInitialization().getFirstInstruction()
|
||||
else result = this.getFirstExprInstruction()
|
||||
then result = this.getInitialization().getFirstInstruction(kind)
|
||||
else result = this.getFirstExprInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
@@ -1036,21 +1062,24 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
exists(SwitchCase switchCase |
|
||||
switchCase = stmt.getASwitchCase() and
|
||||
kind = getCaseEdge(switchCase) and
|
||||
result = getTranslatedStmt(switchCase).getFirstInstruction()
|
||||
result = getTranslatedStmt(switchCase).getFirstInstruction(any(GotoEdge edge))
|
||||
)
|
||||
or
|
||||
not stmt.hasDefaultCase() and
|
||||
tag = SwitchBranchTag() and
|
||||
kind instanceof DefaultEdge and
|
||||
result = this.getParent().getChildSuccessor(this)
|
||||
result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = this.getInitialization() and result = this.getFirstExprInstruction()
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstExprInstruction(kind)
|
||||
or
|
||||
child = this.getExpr() and result = this.getInstruction(SwitchBranchTag())
|
||||
kind instanceof GotoEdge and
|
||||
child = this.getExpr() and
|
||||
result = this.getInstruction(SwitchBranchTag())
|
||||
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())
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction() {
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
if exists(this.getChild(0))
|
||||
then result = this.getChild(0).getFirstInstruction()
|
||||
else result = this.getInstruction(AsmTag())
|
||||
then result = this.getChild(0).getFirstInstruction(kind)
|
||||
else (
|
||||
kind instanceof GotoEdge and result = this.getInstruction(AsmTag())
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
@@ -1091,16 +1122,17 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AsmTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getChild(index) and
|
||||
if exists(this.getChild(index + 1))
|
||||
then result = this.getChild(index + 1).getFirstInstruction()
|
||||
else result = this.getInstruction(AsmTag())
|
||||
then result = this.getChild(index + 1).getFirstInstruction(kind)
|
||||
else (
|
||||
kind instanceof GotoEdge and result = this.getInstruction(AsmTag())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1113,7 +1145,9 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
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) {
|
||||
none()
|
||||
@@ -1121,9 +1155,9 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
|
||||
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
|
||||
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 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) {
|
||||
// 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) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this) and
|
||||
kind instanceof GotoEdge
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) { none() }
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
@@ -39,3 +39,4 @@ private import implementations.ODBC
|
||||
private import implementations.SqLite3
|
||||
private import implementations.PostgreSql
|
||||
private import implementations.System
|
||||
private import implementations.StructuredExceptionHandling
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
22
cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll
Normal file
22
cpp/ql/lib/semmle/code/cpp/models/interfaces/Throwing.qll
Normal 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);
|
||||
}
|
||||
@@ -1815,6 +1815,42 @@ ir.c:
|
||||
# 15| Type = [CharPointerType] char *
|
||||
# 15| ValueCategory = prvalue
|
||||
# 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:
|
||||
# 1| [TopLevelFunction] void Constants()
|
||||
# 1| <params>:
|
||||
|
||||
@@ -809,6 +809,58 @@ ir.c:
|
||||
# 13| v13_11(void) = AliasedUse : m13_3
|
||||
# 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:
|
||||
# 1| void Constants()
|
||||
# 1| Block 0
|
||||
|
||||
@@ -15,4 +15,18 @@ void CStyleCast(void *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
|
||||
|
||||
@@ -1005,6 +1005,31 @@
|
||||
| ir.c:15:24:15:26 | Address | &:r15_2 |
|
||||
| ir.c:15:24:15:26 | Load | m13_6 |
|
||||
| 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 | ChiTotal | total:m1_2 |
|
||||
| ir.cpp:1:6:1:14 | SideEffect | m1_3 |
|
||||
|
||||
@@ -786,6 +786,62 @@ ir.c:
|
||||
# 13| v13_10(void) = AliasedUse : ~m?
|
||||
# 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:
|
||||
# 1| void Constants()
|
||||
# 1| Block 0
|
||||
|
||||
Reference in New Issue
Block a user