From 10ae793de5046f245abca6223c4c648652015236 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 30 Jan 2024 11:27:15 +0000 Subject: [PATCH] C++: Add an 'EdgeKind' column to 'getFirstInstruction'. --- .../raw/internal/IRConstruction.qll | 8 +- .../raw/internal/TranslatedCall.qll | 67 ++--- .../raw/internal/TranslatedCondition.qll | 16 +- .../internal/TranslatedDeclarationEntry.qll | 7 +- .../raw/internal/TranslatedElement.qll | 5 +- .../raw/internal/TranslatedExpr.qll | 249 ++++++++++-------- .../raw/internal/TranslatedFunction.qll | 112 ++++---- .../raw/internal/TranslatedGlobalVar.qll | 16 +- .../raw/internal/TranslatedInitialization.qll | 61 ++--- .../raw/internal/TranslatedStmt.qll | 239 +++++++++-------- 10 files changed, 421 insertions(+), 359 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index 005eaeb7d1a..7e4c3e7934c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -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() ) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 61cfd97b4c5..1abfd0b3836 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -40,10 +40,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) { @@ -53,19 +53,18 @@ abstract class TranslatedCall extends TranslatedExpr { } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and - ( - child = this.getQualifier() and - result = this.getFirstCallTargetInstruction() - or - child = this.getCallTarget() and - result = this.getFirstArgumentOrCallInstruction() - 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()) + child = this.getQualifier() and + result = this.getFirstCallTargetInstruction(kind) + or + child = this.getCallTarget() and + 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(kind) + else ( + result = this.getInstruction(CallTag()) and kind instanceof GotoEdge ) ) or @@ -81,9 +80,8 @@ abstract class TranslatedCall extends TranslatedExpr { } 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) { @@ -125,8 +123,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) } /** @@ -163,10 +161,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()) + ) } /** @@ -211,7 +211,7 @@ abstract class TranslatedSideEffects extends TranslatedElement { exists(int i | this.getChild(i) = te and if exists(this.getChild(i + 1)) - then kind instanceof GotoEdge and result = this.getChild(i + 1).getFirstInstruction() + then result = this.getChild(i + 1).getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, kind) ) } @@ -220,12 +220,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, any(GotoEdge edge)) + result = this.getParent().getChildSuccessor(this, kind) } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } @@ -240,8 +240,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()) } @@ -258,8 +259,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) } } @@ -383,8 +383,9 @@ abstract class TranslatedSideEffect extends TranslatedElement { 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) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll index fbce3c70ebe..7a90d0557b8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCondition.qll @@ -44,8 +44,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) { @@ -92,8 +92,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) { @@ -116,7 +116,7 @@ class TranslatedLogicalAndExpr extends TranslatedBinaryLogicalOperation { override Instruction getChildTrueSuccessor(TranslatedCondition child) { child = this.getLeftOperand() and - result = this.getRightOperand().getFirstInstruction() + result = this.getRightOperand().getFirstInstruction(any(GotoEdge edge)) or child = this.getRightOperand() and result = this.getConditionContext().getChildTrueSuccessor(this) @@ -138,7 +138,7 @@ class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation { override Instruction getChildFalseSuccessor(TranslatedCondition child) { child = this.getLeftOperand() and - result = this.getRightOperand().getFirstInstruction() + result = this.getRightOperand().getFirstInstruction(any(GotoEdge edge)) or child = this.getRightOperand() and result = this.getConditionContext().getChildFalseSuccessor(this) @@ -150,7 +150,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 diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll index 6013c19318a..d04ae4fa97c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll @@ -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) { @@ -166,7 +167,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio 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 diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index fe9e43d700d..9f22a253602 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -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. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index e3ef34cbe89..cede7b0e467 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -180,7 +180,9 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext, override TranslatedElement getChild(int id) { id = 0 and result = this.getCondition() } - override Instruction getFirstInstruction() { result = this.getCondition().getFirstInstruction() } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getCondition().getFirstInstruction(kind) + } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { ( @@ -310,8 +312,8 @@ class TranslatedConditionValue extends TranslatedCoreExpr, ConditionContext, * temporary variable. */ abstract class TranslatedValueCategoryAdjustment extends TranslatedExpr { - final override Instruction getFirstInstruction() { - result = this.getOperand().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getOperand().getFirstInstruction(kind) } final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } @@ -438,7 +440,9 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy { override string toString() { result = "Result of " + expr.toString() } - override Instruction getFirstInstruction() { result = this.getOperand().getFirstInstruction() } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getOperand().getFirstInstruction(kind) + } override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } @@ -475,8 +479,8 @@ class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy { class TranslatedCommaExpr extends TranslatedNonConstantExpr { override CommaExpr expr; - override Instruction getFirstInstruction() { - result = this.getLeftOperand().getFirstInstruction() + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getLeftOperand().getFirstInstruction(kind) } override TranslatedElement getChild(int id) { @@ -491,8 +495,7 @@ class TranslatedCommaExpr extends TranslatedNonConstantExpr { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { child = this.getLeftOperand() and - result = this.getRightOperand().getFirstInstruction() and - kind instanceof GotoEdge + result = this.getRightOperand().getFirstInstruction(kind) or child = this.getRightOperand() and result = this.getParent().getChildSuccessor(this, kind) } @@ -583,8 +586,8 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr { ) } - final override Instruction getFirstInstruction() { - result = this.getLoadedOperand().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getLoadedOperand().getFirstInstruction(kind) } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { @@ -686,8 +689,8 @@ class TranslatedPostfixCrementOperation extends TranslatedCrementOperation { class TranslatedArrayExpr extends TranslatedNonConstantExpr { override ArrayExpr expr; - final override Instruction getFirstInstruction() { - result = this.getBaseOperand().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getBaseOperand().getFirstInstruction(kind) } final override TranslatedElement getChild(int id) { @@ -702,14 +705,12 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr { } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { + child = this.getBaseOperand() and + result = this.getOffsetOperand().getFirstInstruction(kind) + or kind instanceof GotoEdge and - ( - child = this.getBaseOperand() and - result = this.getOffsetOperand().getFirstInstruction() - or - child = this.getOffsetOperand() and - result = this.getInstruction(OnlyInstructionTag()) - ) + child = this.getOffsetOperand() and + result = this.getInstruction(OnlyInstructionTag()) } override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) } @@ -746,8 +747,8 @@ class TranslatedArrayExpr extends TranslatedNonConstantExpr { } abstract class TranslatedTransparentExpr extends TranslatedNonConstantExpr { - final override Instruction getFirstInstruction() { - result = this.getOperand().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getOperand().getFirstInstruction(kind) } final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } @@ -821,8 +822,9 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr { final override Instruction getResult() { result = this.getInstruction(ThisLoadTag()) } - final override Instruction getFirstInstruction() { - result = this.getInstruction(ThisAddressTag()) + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(ThisAddressTag()) and + kind instanceof GotoEdge } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { @@ -878,10 +880,12 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess { not expr instanceof FieldAccess and not isNonReferenceStructuredBinding(expr.getTarget()) } - override Instruction getFirstInstruction() { + override Instruction getFirstInstruction(EdgeKind kind) { if exists(this.getQualifier()) - then result = this.getQualifier().getFirstInstruction() - else result = this.getInstruction(OnlyInstructionTag()) + then result = this.getQualifier().getFirstInstruction(kind) + else ( + kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag()) + ) } override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { @@ -914,7 +918,9 @@ private predicate accessHasEnclosingDeclarationAndVariable( class TranslatedFieldAccess extends TranslatedVariableAccess { override FieldAccess expr; - override Instruction getFirstInstruction() { result = this.getQualifier().getFirstInstruction() } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getQualifier().getFirstInstruction(kind) + } override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { tag = OnlyInstructionTag() and @@ -948,8 +954,9 @@ class TranslatedStructuredBindingVariableAccess extends TranslatedNonConstantExp TranslatedStructuredBindingVariableAccess() { isNonReferenceStructuredBinding(expr.getTarget()) } - override Instruction getFirstInstruction() { + override Instruction getFirstInstruction(EdgeKind kind) { // Structured bindings cannot be qualified. + kind instanceof GotoEdge and result = this.getInstruction(StructuredBindingAccessTag()) } @@ -1009,10 +1016,12 @@ class TranslatedFunctionAccess extends TranslatedNonConstantExpr { result = getTranslatedExpr(expr.getQualifier().getFullyConverted()) } - override Instruction getFirstInstruction() { + override Instruction getFirstInstruction(EdgeKind kind) { if exists(this.getQualifier()) - then result = this.getQualifier().getFirstInstruction() - else result = this.getInstruction(OnlyInstructionTag()) + then result = this.getQualifier().getFirstInstruction(kind) + else ( + kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag()) + ) } override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) } @@ -1061,8 +1070,9 @@ abstract class TranslatedConstantExpr extends TranslatedCoreExpr, TTranslatedVal isIRConstant(expr) } - final override Instruction getFirstInstruction() { - result = this.getInstruction(OnlyInstructionTag()) + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(OnlyInstructionTag()) and + kind instanceof GotoEdge } final override TranslatedElement getChild(int id) { none() } @@ -1138,8 +1148,8 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr { expr instanceof UnaryMinusExpr } - final override Instruction getFirstInstruction() { - result = this.getOperand().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getOperand().getFirstInstruction(kind) } final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } @@ -1179,7 +1189,9 @@ class TranslatedUnaryExpr extends TranslatedSingleInstructionExpr { abstract class TranslatedConversion extends TranslatedNonConstantExpr { override Conversion expr; - override Instruction getFirstInstruction() { result = this.getOperand().getFirstInstruction() } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getOperand().getFirstInstruction(kind) + } final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } @@ -1414,8 +1426,8 @@ class TranslatedBinaryOperation extends TranslatedSingleInstructionExpr { expr instanceof ComparisonOperation } - override Instruction getFirstInstruction() { - result = this.getLeftOperand().getFirstInstruction() + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getLeftOperand().getFirstInstruction(kind) } final override TranslatedElement getChild(int id) { @@ -1510,9 +1522,9 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr { id = 1 and result = this.getRightOperand() } - final override Instruction getFirstInstruction() { + final override Instruction getFirstInstruction(EdgeKind kind) { // Evaluation is right-to-left - result = this.getRightOperand().getFirstInstruction() + result = this.getRightOperand().getFirstInstruction(kind) } final override Instruction getResult() { @@ -1549,6 +1561,9 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr { child = this.getRightOperand() and result = this.getLeftOperand().getFirstInstruction(kind) or + child = this.getRightOperand() and + result = this.getLeftOperand().getFirstInstruction(kind) + or kind instanceof GotoEdge and child = this.getLeftOperand() and result = this.getInstruction(AssignmentStoreTag()) @@ -1581,9 +1596,9 @@ class TranslatedBlockAssignExpr extends TranslatedNonConstantExpr { id = 1 and result = this.getRightOperand() } - final override Instruction getFirstInstruction() { + final override Instruction getFirstInstruction(EdgeKind kind) { // The operand evaluation order should not matter since block assignments behave like memcpy. - result = this.getLeftOperand().getFirstInstruction() + result = this.getLeftOperand().getFirstInstruction(kind) } final override Instruction getResult() { result = this.getInstruction(AssignmentStoreTag()) } @@ -1607,8 +1622,9 @@ class TranslatedBlockAssignExpr extends TranslatedNonConstantExpr { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { child = this.getLeftOperand() and - result = this.getRightOperand().getFirstInstruction() + result = this.getRightOperand().getFirstInstruction(kind) or + kind instanceof GotoEdge and child = this.getRightOperand() and result = this.getInstruction(LoadTag()) } @@ -1649,9 +1665,9 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr { id = 1 and result = this.getRightOperand() } - final override Instruction getFirstInstruction() { + final override Instruction getFirstInstruction(EdgeKind kind) { // Evaluation is right-to-left - result = this.getRightOperand().getFirstInstruction() + result = this.getRightOperand().getFirstInstruction(kind) } final override Instruction getResult() { @@ -1714,8 +1730,9 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { // Operands are evaluated right-to-left. child = this.getRightOperand() and - result = this.getLoadedLeftOperand().getFirstInstruction() + result = this.getLoadedLeftOperand().getFirstInstruction(kind) or + kind instanceof GotoEdge and child = this.getLoadedLeftOperand() and if this.leftOperandNeedsConversion() then result = this.getInstruction(AssignOperationConvertLeftTag()) @@ -1876,7 +1893,8 @@ TranslatedAllocationSize getTranslatedAllocationSize(NewOrNewArrayExpr newExpr) class TranslatedConstantAllocationSize extends TranslatedAllocationSize { TranslatedConstantAllocationSize() { not exists(expr.(NewArrayExpr).getExtent()) } - final override Instruction getFirstInstruction() { + final override Instruction getFirstInstruction(EdgeKind kind) { + kind instanceof GotoEdge and result = this.getInstruction(AllocationSizeTag()) } @@ -1913,8 +1931,8 @@ class TranslatedNonConstantAllocationSize extends TranslatedAllocationSize { TranslatedNonConstantAllocationSize() { exists(expr.getExtent()) } - final override Instruction getFirstInstruction() { - result = this.getExtent().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getExtent().getFirstInstruction(kind) } final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { @@ -2056,8 +2074,9 @@ TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, TranslatedCall { override DeleteOrDeleteArrayExpr expr; - 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()) } @@ -2076,8 +2095,7 @@ class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, Trans result = TranslatedCall.super.getInstructionSuccessor(tag, kind) or tag = CallTargetTag() and - kind instanceof GotoEdge and - result = this.getFirstArgumentOrCallInstruction() + result = this.getFirstArgumentOrCallInstruction(kind) } override Function getInstructionFunction(InstructionTag tag) { @@ -2139,8 +2157,7 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { tag = OnlyInstructionTag() and - kind instanceof GotoEdge and - result = this.getDestructorCall().getFirstInstruction() + result = this.getDestructorCall().getFirstInstruction(kind) } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { @@ -2150,8 +2167,9 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St final override Instruction getResult() { 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 Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { @@ -2385,7 +2403,9 @@ class TranslatedTernaryConditionalExpr extends TranslatedConditionalExpr, Condit id = 2 and result = this.getElse() } - override Instruction getFirstInstruction() { result = this.getCondition().getFirstInstruction() } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getCondition().getFirstInstruction(kind) + } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { result = TranslatedConditionalExpr.super.getChildSuccessor(child, kind) @@ -2403,12 +2423,12 @@ class TranslatedTernaryConditionalExpr extends TranslatedConditionalExpr, Condit override Instruction getChildTrueSuccessor(TranslatedCondition child) { child = this.getCondition() and - result = this.getThen().getFirstInstruction() + result = this.getThen().getFirstInstruction(any(GotoEdge edge)) } override Instruction getChildFalseSuccessor(TranslatedCondition child) { child = this.getCondition() and - result = this.getElse().getFirstInstruction() + result = this.getElse().getFirstInstruction(any(GotoEdge edge)) } private TranslatedCondition getCondition() { @@ -2438,7 +2458,9 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { id = 1 and result = this.getElse() } - override Instruction getFirstInstruction() { result = this.getCondition().getFirstInstruction() } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getCondition().getFirstInstruction(kind) + } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { super.hasInstruction(opcode, tag, resultType) @@ -2458,7 +2480,7 @@ class TranslatedBinaryConditionalExpr extends TranslatedConditionalExpr { result = this.getInstruction(ConditionValueTrueTempAddressTag()) or kind instanceof FalseEdge and - result = this.getElse().getFirstInstruction() + result = this.getElse().getFirstInstruction(any(GotoEdge edge)) ) } @@ -2617,7 +2639,10 @@ class TranslatedReThrowExpr extends TranslatedThrowExpr { override TranslatedElement getChild(int id) { none() } - override Instruction getFirstInstruction() { result = this.getInstruction(ThrowTag()) } + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(ThrowTag()) and + kind instanceof GotoEdge + } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() } @@ -2642,10 +2667,12 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr { final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) } - final override Instruction getFirstInstruction() { + final override Instruction getFirstInstruction(EdgeKind kind) { if exists(this.getChild(0)) - then result = this.getChild(0).getFirstInstruction() - else result = this.getInstruction(OnlyInstructionTag()) + then result = this.getChild(0).getFirstInstruction(kind) + else ( + kind instanceof GotoEdge and result = this.getInstruction(OnlyInstructionTag()) + ) } final override TranslatedElement getChild(int id) { @@ -2658,14 +2685,12 @@ class TranslatedBuiltInOperation extends TranslatedNonConstantExpr { } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and - exists(int id | - child = this.getChild(id) and - ( - result = this.getChild(id + 1).getFirstInstruction() - or - not exists(this.getChild(id + 1)) and result = this.getInstruction(OnlyInstructionTag()) - ) + exists(int id | child = this.getChild(id) | + result = this.getChild(id + 1).getFirstInstruction(kind) + or + kind instanceof GotoEdge and + not exists(this.getChild(id + 1)) and + result = this.getInstruction(OnlyInstructionTag()) ) } @@ -2759,8 +2784,9 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr { resultType = getTypeForPRValue(getVAListType(expr.getVAList().getFullyConverted())) } - final override Instruction getFirstInstruction() { - result = this.getInstruction(VarArgsStartEllipsisAddressTag()) + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(VarArgsStartEllipsisAddressTag()) and + kind instanceof GotoEdge } final override Instruction getResult() { none() } @@ -2777,8 +2803,7 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr { result = this.getInstruction(VarArgsStartTag()) or tag = VarArgsStartTag() and - kind instanceof GotoEdge and - result = this.getVAList().getFirstInstruction() + result = this.getVAList().getFirstInstruction(kind) or tag = VarArgsVAListStoreTag() and result = this.getParent().getChildSuccessor(this, kind) @@ -2833,8 +2858,8 @@ class TranslatedVarArg extends TranslatedNonConstantExpr { resultType = getTypeForPRValue(getVAListType(expr.getVAList().getFullyConverted())) } - final override Instruction getFirstInstruction() { - result = this.getVAList().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getVAList().getFirstInstruction(kind) } final override Instruction getResult() { result = this.getInstruction(VarArgsArgAddressTag()) } @@ -2905,8 +2930,8 @@ class TranslatedVarArgsEnd extends TranslatedNonConstantExpr { resultType = getVoidType() } - final override Instruction getFirstInstruction() { - result = this.getVAList().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getVAList().getFirstInstruction(kind) } final override Instruction getResult() { none() } @@ -2951,8 +2976,8 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr { resultType = getTypeForPRValue(getVAListType(expr.getDestinationVAList().getFullyConverted())) } - final override Instruction getFirstInstruction() { - result = this.getSourceVAList().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getSourceVAList().getFirstInstruction(kind) } final override Instruction getResult() { result = this.getInstruction(VarArgsVAListStoreTag()) } @@ -2973,19 +2998,21 @@ class TranslatedVarArgCopy extends TranslatedNonConstantExpr { final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { tag = VarArgsVAListLoadTag() and - kind instanceof GotoEdge and - result = this.getDestinationVAList().getFirstInstruction() + result = this.getDestinationVAList().getFirstInstruction(kind) or tag = VarArgsVAListStoreTag() and result = this.getParent().getChildSuccessor(this, kind) } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - child = this.getSourceVAList() and - result = this.getInstruction(VarArgsVAListLoadTag()) - or - child = this.getDestinationVAList() and - result = this.getInstruction(VarArgsVAListStoreTag()) + kind instanceof GotoEdge and + ( + child = this.getSourceVAList() and + result = this.getInstruction(VarArgsVAListLoadTag()) + or + child = this.getDestinationVAList() and + result = this.getInstruction(VarArgsVAListStoreTag()) + ) } final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { @@ -3023,17 +3050,16 @@ abstract class TranslatedNewOrNewArrayExpr extends TranslatedNonConstantExpr, In resultType = this.getResultType() } - final override Instruction getFirstInstruction() { - result = this.getAllocatorCall().getFirstInstruction() + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getAllocatorCall().getFirstInstruction(kind) } final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) } final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { - kind instanceof GotoEdge and tag = OnlyInstructionTag() and if exists(this.getInitialization()) - then kind instanceof GotoEdge and result = this.getInitialization().getFirstInstruction() + then result = this.getInitialization().getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, kind) } @@ -3098,7 +3124,9 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr { class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr { override ConditionDeclExpr expr; - final override Instruction getFirstInstruction() { result = this.getDecl().getFirstInstruction() } + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getDecl().getFirstInstruction(kind) + } final override TranslatedElement getChild(int id) { id = 0 and result = this.getDecl() @@ -3111,9 +3139,8 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr { override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and child = this.getDecl() and - result = this.getConditionExpr().getFirstInstruction() + result = this.getConditionExpr().getFirstInstruction(kind) or child = this.getConditionExpr() and result = this.getParent().getChildSuccessor(this, kind) } @@ -3136,8 +3163,9 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr { class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationContext { override LambdaExpression expr; - final override Instruction getFirstInstruction() { - result = this.getInstruction(InitializerVariableAddressTag()) + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(InitializerVariableAddressTag()) and + kind instanceof GotoEdge } final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() } @@ -3150,11 +3178,12 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont result = this.getInstruction(InitializerStoreTag()) or tag = InitializerStoreTag() and - kind instanceof GotoEdge and ( - result = this.getInitialization().getFirstInstruction() + result = this.getInitialization().getFirstInstruction(kind) or - not this.hasInitializer() and result = this.getInstruction(LoadTag()) + kind instanceof GotoEdge and + not this.hasInitializer() and + result = this.getInstruction(LoadTag()) ) or tag = LoadTag() and @@ -3226,7 +3255,9 @@ class TranslatedLambdaExpr extends TranslatedNonConstantExpr, InitializationCont class TranslatedStmtExpr extends TranslatedNonConstantExpr { override StmtExpr expr; - final override Instruction getFirstInstruction() { result = this.getStmt().getFirstInstruction() } + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getStmt().getFirstInstruction(kind) + } final override TranslatedElement getChild(int id) { id = 0 and result = this.getStmt() } @@ -3261,8 +3292,9 @@ class TranslatedStmtExpr extends TranslatedNonConstantExpr { class TranslatedErrorExpr extends TranslatedSingleInstructionExpr { override ErrorExpr expr; - final override Instruction getFirstInstruction() { - result = this.getInstruction(OnlyInstructionTag()) + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(OnlyInstructionTag()) and + kind instanceof GotoEdge } final override TranslatedElement getChild(int id) { none() } @@ -3354,8 +3386,9 @@ class TranslatedAssumeExpr extends TranslatedSingleInstructionExpr { final override Opcode getOpcode() { result instanceof Opcode::NoOp } - final override Instruction getFirstInstruction() { - result = this.getInstruction(OnlyInstructionTag()) + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(OnlyInstructionTag()) and + kind instanceof GotoEdge } final override TranslatedElement getChild(int id) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll index 66b61257572..75e9ed81b97 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll @@ -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() - else - if exists(this.getParameter(0)) - then result = this.getParameter(0).getFirstInstruction() - else result = this.getBody().getFirstInstruction() - ) - or + ) + or + ( + tag = InitializeNonLocalTag() and + if exists(this.getThisType()) + then result = this.getParameter(-1).getFirstInstruction(kind) + else + if exists(this.getParameter(0)) + 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 @@ -147,31 +151,28 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction { } final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and - ( - exists(int paramIndex | - child = this.getParameter(paramIndex) and - if - exists(func.getParameter(paramIndex + 1)) or - getEllipsisParameterIndexForFunction(func) = paramIndex + 1 - then result = this.getParameter(paramIndex + 1).getFirstInstruction() - else result = this.getConstructorInitList().getFirstInstruction() - ) - or - child = this.getConstructorInitList() and - result = this.getBody().getFirstInstruction() - or - child = this.getBody() and - result = this.getReturnSuccessorInstruction() - or - child = this.getDestructorDestructionList() and - result = this.getReadEffects().getFirstInstruction() - or - child = this.getReadEffects() and - if this.hasReturnValue() - then result = this.getInstruction(ReturnValueAddressTag()) - else result = this.getInstruction(ReturnTag()) + 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(kind) + else result = this.getConstructorInitList().getFirstInstruction(kind) ) + or + child = this.getConstructorInitList() and + result = this.getBody().getFirstInstruction(kind) + or + child = this.getBody() and + result = this.getReturnSuccessorInstruction(kind) + or + child = this.getDestructorDestructionList() and + result = this.getReadEffects().getFirstInstruction(kind) + or + kind instanceof GotoEdge and + child = this.getReadEffects() and + if this.hasReturnValue() + then result = this.getInstruction(ReturnValueAddressTag()) + else result = this.getInstruction(ReturnTag()) } final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { @@ -271,8 +272,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) } /** @@ -372,8 +373,9 @@ 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) { @@ -602,10 +604,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, any(GotoEdge edge)) + then result = this.getChild(0).getFirstInstruction(kind) + else result = this.getParent().getChildSuccessor(this, kind) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { @@ -620,7 +622,7 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon exists(int id | child = this.getChild(id) and if exists(this.getChild(id + 1)) - then kind instanceof GotoEdge and result = this.getChild(id + 1).getFirstInstruction() + then result = this.getChild(id + 1).getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, kind) ) } @@ -669,9 +671,9 @@ class TranslatedDestructorDestructionList extends TranslatedElement, ) } - override Instruction getFirstInstruction() { + override Instruction getFirstInstruction(EdgeKind kind) { if exists(this.getChild(0)) - then result = this.getChild(0).getFirstInstruction() + then result = this.getChild(0).getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, any(GotoEdge edge)) } @@ -687,7 +689,7 @@ class TranslatedDestructorDestructionList extends TranslatedElement, exists(int id | child = this.getChild(id) and if exists(this.getChild(id + 1)) - then kind instanceof GotoEdge and result = this.getChild(id + 1).getFirstInstruction() + then result = this.getChild(id + 1).getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, kind) ) } @@ -716,26 +718,25 @@ 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, any(GotoEdge edge)) + .getFirstInstruction(kind) + else result = this.getParent().getChildSuccessor(this, kind) } 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 - kind instanceof GotoEdge and result = min(TranslatedReadEffect child2, int id2 | child2 = this.getChild(id2) and id2 > id | child2 order by id2 - ).getFirstInstruction() + ).getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, kind) ) } @@ -765,7 +766,10 @@ abstract class TranslatedReadEffect extends TranslatedElement { 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 diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedGlobalVar.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedGlobalVar.qll index ac7a8cc8a31..d14adfa80e8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedGlobalVar.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedGlobalVar.qll @@ -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() - or + ) + or + tag = InitializerVariableAddressTag() and + result = this.getChild(1).getFirstInstruction(kind) + or + kind instanceof GotoEdge and + ( tag = ReturnTag() and result = this.getInstruction(AliasedUseTag()) or diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll index b01c293c79e..bca55d654d4 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -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,19 +56,19 @@ 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() + kind instanceof GotoEdge and + not exists(this.getInitialization()) and + result = this.getInitializationSuccessor() ) } @@ -170,18 +171,18 @@ 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, any(GotoEdge edge)) + result = this.getParent().getChildSuccessor(this, kind) } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { exists(int index | child = this.getChild(index) and if exists(this.getChild(index + 1)) - then kind instanceof GotoEdge and result = this.getChild(index + 1).getFirstInstruction() + then result = this.getChild(index + 1).getFirstInstruction(kind) else result = this.getParent().getChildSuccessor(this, kind) ) } @@ -242,8 +243,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) } @@ -509,8 +510,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 } /** @@ -565,8 +567,7 @@ 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, EdgeKind kind) { @@ -674,8 +675,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) { @@ -752,8 +754,7 @@ 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, EdgeKind kind) { @@ -889,8 +890,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) { @@ -901,8 +903,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()) } @@ -943,8 +944,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) { @@ -1005,8 +1006,8 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr final override string toString() { result = "construct base (no constructor)" } - override Instruction getFirstInstruction() { - result = this.getParent().getChildSuccessor(this, any(GotoEdge edge)) + override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getParent().getChildSuccessor(this, kind) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 8a0f7a38a88..7e311ab3b1e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -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,10 +194,8 @@ 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() - ) + kind instanceof TrueEdge and + result = this.getTranslatedHandler().getFirstInstruction(any(GotoEdge edge)) or // Unwind -> Parent tag = UnwindTag() and @@ -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 @@ -284,11 +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, any(GotoEdge edge)) + result = this.getParent().getChildSuccessor(this, kind) } private int getChildCount() { result = count(this.getDeclarationEntry(_)) } @@ -322,10 +325,7 @@ class TranslatedDeclStmt extends TranslatedStmt { child = this.getDeclarationEntry(index) and if index = (this.getChildCount() - 1) then result = this.getParent().getChildSuccessor(this, kind) - else ( - kind instanceof GotoEdge and - result = this.getDeclarationEntry(index + 1).getFirstInstruction() - ) + else result = this.getDeclarationEntry(index + 1).getFirstInstruction(kind) ) } } @@ -341,7 +341,9 @@ 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() } @@ -366,7 +368,7 @@ class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariable TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) } final override Instruction getInitializationSuccessor() { - result = this.getEnclosingFunction().getReturnSuccessorInstruction() + result = this.getEnclosingFunction().getReturnSuccessorInstruction(any(GotoEdge edge)) } final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() } @@ -393,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 @@ -403,8 +407,7 @@ 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, EdgeKind kind) { @@ -427,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 @@ -437,8 +443,7 @@ 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, EdgeKind kind) { none() } @@ -456,7 +461,7 @@ class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariab } final override Instruction getInitializationSuccessor() { - result = this.getEnclosingFunction().getReturnSuccessorInstruction() + result = this.getEnclosingFunction().getReturnSuccessorInstruction(any(GotoEdge edge)) } final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() } @@ -528,7 +533,9 @@ 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, EdgeKind kind) { // All non-finally children go to the successor of the `try` if @@ -539,8 +546,7 @@ class TranslatedTryStmt extends TranslatedStmt { not exists(this.getFinally()) and result = this.getParent().getChildSuccessor(this, kind) or - kind instanceof GotoEdge and - result = this.getFinally().getFirstInstruction() + result = this.getFinally().getFirstInstruction(kind) ) or // And after the finally block we go to the successor of the `try`. @@ -548,21 +554,22 @@ class TranslatedTryStmt extends TranslatedStmt { 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. + kind instanceof GotoEdge and handler = this.getHandler(stmt.getNumberOfCatchClauses() - 1) and result = this.getParent().getExceptionSuccessorInstruction() } final override Instruction getExceptionSuccessorInstruction() { - result = this.getHandler(0).getFirstInstruction() + result = this.getHandler(0).getFirstInstruction(any(GotoEdge edge)) } private TranslatedElement getHandler(int index) { result = stmt.getTranslatedHandler(index) } @@ -584,10 +591,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)) } @@ -606,9 +613,7 @@ class TranslatedBlock extends TranslatedStmt { child = this.getStmt(index) and if index = (this.getStmtCount() - 1) then result = this.getParent().getChildSuccessor(this, kind) - else ( - kind instanceof GotoEdge and result = this.getStmt(index + 1).getFirstInstruction() - ) + else result = this.getStmt(index + 1).getFirstInstruction(kind) ) } } @@ -621,7 +626,10 @@ 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 getFirstInstruction(EdgeKind kind) { + result = this.getInstruction(CatchTag()) and + kind instanceof GotoEdge + } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { child = this.getBlock() and result = this.getParent().getChildSuccessor(this, kind) @@ -658,19 +666,18 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler { override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { result = super.getChildSuccessor(child, kind) or - kind instanceof GotoEdge and child = this.getParameter() and - result = this.getBlock().getFirstInstruction() + 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)) ) } @@ -698,18 +705,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) { @@ -732,8 +738,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()) } @@ -746,20 +752,19 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext { override Instruction getChildTrueSuccessor(TranslatedCondition child) { child = this.getCondition() and - result = this.getThen().getFirstInstruction() + result = this.getThen().getFirstInstruction(any(GotoEdge edge)) } override Instruction getChildFalseSuccessor(TranslatedCondition child) { child = this.getCondition() and if this.hasElse() - then result = this.getElse().getFirstInstruction() + then result = this.getElse().getFirstInstruction(any(GotoEdge edge)) else result = this.getParent().getChildSuccessor(this, any(GotoEdge edge)) } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and 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, kind) @@ -779,10 +784,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()) } @@ -800,7 +805,7 @@ 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() + child = this.getCondition() and result = this.getBody().getFirstInstruction(any(GotoEdge edge)) } final override Instruction getChildFalseSuccessor(TranslatedCondition child) { @@ -812,24 +817,26 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext { 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, EdgeKind kind) { child = this.getBody() and - result = this.getFirstConditionInstruction() and - kind instanceof GotoEdge + 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, EdgeKind kind) { child = this.getBody() and - result = this.getFirstConditionInstruction() and - kind instanceof GotoEdge + result = this.getFirstConditionInstruction(kind) } } @@ -856,27 +863,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, EdgeKind kind) { - kind instanceof GotoEdge and + child = this.getInitialization() and + result = this.getFirstConditionInstruction(kind) + or ( - child = this.getInitialization() and - result = this.getFirstConditionInstruction() - or - ( - child = this.getBody() and - if this.hasUpdate() - then result = this.getUpdate().getFirstInstruction() - else result = this.getFirstConditionInstruction() - ) - or - child = this.getUpdate() and result = this.getFirstConditionInstruction() + child = this.getBody() and + if this.hasUpdate() + then result = this.getUpdate().getFirstInstruction(kind) + else result = this.getFirstConditionInstruction(kind) ) + or + child = this.getUpdate() and result = this.getFirstConditionInstruction(kind) } } @@ -905,28 +909,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, EdgeKind kind) { - kind instanceof GotoEdge and - ( - child = this.getRangeVariableDeclStmt() and - result = this.getBeginEndVariableDeclStmt().getFirstInstruction() - or - child = this.getBeginEndVariableDeclStmt() and - result = this.getCondition().getFirstInstruction() - or - child = this.getVariableDeclStmt() and - result = this.getBody().getFirstInstruction() - or - child = this.getBody() and - result = this.getUpdate().getFirstInstruction() - or - child = this.getUpdate() and - result = this.getCondition().getFirstInstruction() - ) + child = this.getRangeVariableDeclStmt() and + result = this.getBeginEndVariableDeclStmt().getFirstInstruction(kind) + or + child = this.getBeginEndVariableDeclStmt() and + result = this.getCondition().getFirstInstruction(kind) + or + child = this.getVariableDeclStmt() and + result = this.getBody().getFirstInstruction(kind) + or + child = this.getBody() and + result = this.getUpdate().getFirstInstruction(kind) + or + child = this.getUpdate() and + result = this.getCondition().getFirstInstruction(kind) } override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { @@ -936,7 +937,8 @@ 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() + child = this.getCondition() and + result = this.getVariableDeclStmt().getFirstInstruction(any(GotoEdge edge)) } override Instruction getChildFalseSuccessor(TranslatedCondition child) { @@ -981,7 +983,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() } @@ -993,8 +998,7 @@ 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, EdgeKind kind) { none() } @@ -1016,14 +1020,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) { @@ -1057,7 +1063,7 @@ 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 @@ -1067,9 +1073,8 @@ class TranslatedSwitchStmt extends TranslatedStmt { } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and child = this.getInitialization() and - result = this.getFirstExprInstruction() + result = this.getFirstExprInstruction(kind) or kind instanceof GotoEdge and child = this.getExpr() and @@ -1086,10 +1091,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) { @@ -1120,12 +1127,13 @@ class TranslatedAsmStmt extends TranslatedStmt { } override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { - kind instanceof GotoEdge and 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()) + ) ) } } @@ -1138,7 +1146,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() @@ -1157,7 +1167,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.