mirror of
https://github.com/github/codeql.git
synced 2026-04-22 07:15:15 +02:00
Merge branch 'main' into ir-for-vacuous-destructor-calls
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added destructors for named objects to the intermediate representation.
|
||||
@@ -60,4 +60,6 @@ Element exprEnclosingElement(Expr e) {
|
||||
)
|
||||
else result = de.getDeclaration()
|
||||
)
|
||||
or
|
||||
result.(Stmt).getAnImplicitDestructorCall() = e
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// NOTE: There are two copies of this file, and they must be kept identical:
|
||||
// - semmle/code/cpp/controlflow/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll [now DEPRECATED]
|
||||
//
|
||||
// The second one is a private copy of the `SubBasicBlocks` library for
|
||||
// internal use by the data flow library. Having an extra copy prevents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides a local analysis for identifying where a variable address
|
||||
* is effectively taken. Array-like offsets are allowed to pass through but
|
||||
* not field-like offsets.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import DataFlowPrivate
|
||||
private import DataFlowUtil
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CppOldDataFlow>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CppOldDataFlow>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides consistency queries for checking invariants in the language-specific
|
||||
* data-flow classes and predicates.
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides C++-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import DataFlowUtil
|
||||
private import DataFlowDispatch
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides C++-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides a class for handling variables in the data flow analysis.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// NOTE: There are two copies of this file, and they must be kept identical:
|
||||
// - semmle/code/cpp/controlflow/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll
|
||||
// - semmle/code/cpp/dataflow/internal/SubBasicBlocks.qll [now DEPRECATED]
|
||||
//
|
||||
// The second one is a private copy of the `SubBasicBlocks` library for
|
||||
// internal use by the data flow library. Having an extra copy prevents
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides C++-specific definitions for use in the taint tracking library.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/**
|
||||
* DEPRECATED: Use `semmle.code.cpp.dataflow.new.DataFlow` instead.
|
||||
*
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) taint-tracking analyses.
|
||||
*
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `Global` and `GlobalWithState` instead.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public
|
||||
|
||||
module Private {
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Use `Global` and `GlobalWithState` instead.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.dataflow.internal.TaintTrackingUtil as Public
|
||||
|
||||
module Private {
|
||||
|
||||
@@ -11,6 +11,7 @@ private import InstructionTag
|
||||
private import TranslatedCondition
|
||||
private import TranslatedElement
|
||||
private import TranslatedExpr
|
||||
private import TranslatedCall
|
||||
private import TranslatedStmt
|
||||
private import TranslatedFunction
|
||||
private import TranslatedGlobalVar
|
||||
|
||||
@@ -85,10 +85,14 @@ newtype TInstructionTag =
|
||||
// The next three cases handle generation of branching for __except handling.
|
||||
TryExceptCompareNegativeOneBranch() or
|
||||
TryExceptCompareZeroBranch() or
|
||||
TryExceptCompareOneBranch()
|
||||
TryExceptCompareOneBranch() or
|
||||
ImplicitDestructorTag(int index) {
|
||||
exists(Expr e | exists(e.getImplicitDestructorCall(index))) or
|
||||
exists(Stmt s | exists(s.getImplicitDestructorCall(index)))
|
||||
}
|
||||
|
||||
class InstructionTag extends TInstructionTag {
|
||||
final string toString() { result = "Tag" }
|
||||
final string toString() { result = getInstructionTagId(this) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,4 +259,8 @@ string getInstructionTagId(TInstructionTag tag) {
|
||||
tag = TryExceptCompareZeroBranch() and result = "TryExceptCompareZeroBranch"
|
||||
or
|
||||
tag = TryExceptCompareOneBranch() and result = "TryExceptCompareOneBranch"
|
||||
or
|
||||
exists(int index |
|
||||
tag = ImplicitDestructorTag(index) and result = "ImplicitDestructor(" + index + ")"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ private CallInstruction getTranslatedCallInstruction(Call call) {
|
||||
* of a higher-level constructor (e.g. the allocator call in a `NewExpr`).
|
||||
*/
|
||||
abstract class TranslatedCall extends TranslatedExpr {
|
||||
final override TranslatedElement getChild(int id) {
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
// We choose the child's id in the order of evaluation.
|
||||
// The qualifier is evaluated before the call target, because the value of
|
||||
// the call target may depend on the value of the qualifier for virtual
|
||||
@@ -47,13 +47,19 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
else result = this.getFirstCallTargetInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getSideEffects().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getSideEffects() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = CallTag() and
|
||||
opcode instanceof Opcode::Call and
|
||||
resultType = getTypeForPRValue(this.getCallResultType())
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getQualifier() and
|
||||
result = this.getFirstCallTargetInstruction(kind)
|
||||
or
|
||||
@@ -87,7 +93,7 @@ abstract class TranslatedCall extends TranslatedExpr {
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = CallTag() and
|
||||
result = this.getSideEffects().getFirstInstruction(kind)
|
||||
}
|
||||
@@ -225,7 +231,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement te, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement te, EdgeKind kind) {
|
||||
exists(int i |
|
||||
this.getChild(i) = te and
|
||||
if exists(this.getChild(i + 1))
|
||||
@@ -234,6 +240,10 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int i | exists(this.getChild(i))))
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
||||
none()
|
||||
}
|
||||
@@ -246,7 +256,18 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if exists(this.getAChild())
|
||||
then result = this.getChild(max(int i | exists(this.getChild(i)))).getALastInstruction()
|
||||
else
|
||||
// If there are no side effects, the "last" instruction should be the parent call's last
|
||||
// instruction, so that implicit destructors can be inserted in the right place.
|
||||
result = this.getParent().getInstruction(CallTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Gets the primary instruction to be associated with each side effect instruction. */
|
||||
abstract Instruction getPrimaryInstruction();
|
||||
@@ -273,8 +294,8 @@ abstract class TranslatedDirectCall extends TranslatedCall {
|
||||
resultType = getFunctionGLValueType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedCall.super.getInstructionSuccessorInternal(tag, kind)
|
||||
or
|
||||
tag = CallTargetTag() and
|
||||
result = this.getFirstArgumentOrCallInstruction(kind)
|
||||
@@ -367,6 +388,16 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
|
||||
context = this.getParent() and
|
||||
result = context.getReceiver()
|
||||
)
|
||||
or
|
||||
exists(Stmt parent |
|
||||
expr = parent.getAnImplicitDestructorCall() and
|
||||
result = getTranslatedExpr(expr.getQualifier().getFullyConverted()).getResult()
|
||||
)
|
||||
or
|
||||
exists(Expr parent |
|
||||
expr = parent.getAnImplicitDestructorCall() and
|
||||
result = getTranslatedExpr(expr.getQualifier().getFullyConverted()).getResult()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasQualifier() { any() }
|
||||
@@ -416,19 +447,25 @@ private int initializeAllocationGroup() { result = 3 }
|
||||
abstract class TranslatedSideEffect extends TranslatedElement {
|
||||
final override TranslatedElement getChild(int n) { none() }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
|
||||
tag = OnlyInstructionTag() and
|
||||
this.sideEffectInstruction(opcode, type)
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = this.getParent().getChildSuccessor(this, kind) and
|
||||
tag = OnlyInstructionTag()
|
||||
}
|
||||
|
||||
@@ -50,19 +50,29 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
|
||||
{
|
||||
TranslatedFlexibleCondition() { this = TTranslatedFlexibleCondition(expr) }
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getOperand().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
abstract TranslatedCondition getOperand();
|
||||
}
|
||||
@@ -88,12 +98,16 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
|
||||
abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition {
|
||||
TranslatedNativeCondition() { this = TTranslatedNativeCondition(expr) }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeCondition, ConditionContext {
|
||||
override BinaryLogicalOperation expr;
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
id = 0 and result = this.getLeftOperand()
|
||||
or
|
||||
@@ -104,11 +118,19 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
|
||||
result = this.getLeftOperand().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getLeftOperand().getALastInstruction()
|
||||
or
|
||||
result = this.getRightOperand().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final TranslatedCondition getLeftOperand() {
|
||||
result = getTranslatedCondition(expr.getLeftOperand().getFullyConverted())
|
||||
@@ -162,19 +184,25 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
|
||||
result = this.getValueExpr().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(ValueConditionConditionalBranchTag())
|
||||
}
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { none() } // TODO: this needs to be revisted when we get unnamed destructors
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = ValueConditionConditionalBranchTag() and
|
||||
opcode instanceof Opcode::ConditionalBranch and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getValueExpr() and
|
||||
result = this.getInstruction(ValueConditionConditionalBranchTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = ValueConditionConditionalBranchTag() and
|
||||
(
|
||||
kind instanceof TrueEdge and
|
||||
|
||||
@@ -60,6 +60,10 @@ abstract class TranslatedLocalVariableDeclaration extends TranslatedVariableInit
|
||||
*/
|
||||
abstract LocalVariable getVariable();
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
result = TranslatedVariableInitialization.super.getChildInternal(id)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = getVariableType(this.getVariable()) }
|
||||
|
||||
final override TranslatedInitialization getInitialization() {
|
||||
@@ -152,7 +156,13 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(DynamicInitializationConditionalBranchTag())
|
||||
or
|
||||
result = this.getInstruction(DynamicInitializationFlagStoreTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = DynamicInitializationFlagAddressTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(DynamicInitializationFlagLoadTag())
|
||||
@@ -178,7 +188,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getInstruction(DynamicInitializationFlagConstantTag()) and
|
||||
kind instanceof GotoEdge
|
||||
|
||||
@@ -20,10 +20,14 @@ private import SideEffects
|
||||
* they were explicit nodes in the expression tree, rather than as implicit
|
||||
* nodes as in the regular AST representation.
|
||||
*/
|
||||
private Element getRealParent(Expr expr) {
|
||||
Element getRealParent(Expr expr) {
|
||||
result = expr.getParentWithConversions()
|
||||
or
|
||||
result.(Destructor).getADestruction() = expr
|
||||
or
|
||||
result.(Expr).getAnImplicitDestructorCall() = expr
|
||||
or
|
||||
result.(Stmt).getAnImplicitDestructorCall() = expr
|
||||
}
|
||||
|
||||
IRUserVariable getIRUserVariable(Declaration decl, Variable var) {
|
||||
@@ -105,12 +109,6 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
newExpr.getAllocatorCall() = expr
|
||||
)
|
||||
or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the destructor call as we don't model it yet. Don't ignore
|
||||
// its arguments, though, as they are the arguments to the deallocator.
|
||||
deleteExpr.getDestructorCall() = expr
|
||||
)
|
||||
or
|
||||
// The extractor deliberately emits an `ErrorExpr` as the first argument to
|
||||
// the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr`
|
||||
// should not be translated.
|
||||
@@ -118,6 +116,11 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
or
|
||||
not translateFunction(getEnclosingFunction(expr)) and
|
||||
not Raw::varHasIRFunc(getEnclosingVariable(expr))
|
||||
or
|
||||
exists(DeleteOrDeleteArrayExpr deleteExpr |
|
||||
// Ignore the destructor call, because the duplicated qualifier breaks control flow.
|
||||
deleteExpr.getDestructorCall() = expr
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -608,16 +611,27 @@ newtype TTranslatedElement =
|
||||
TTranslatedInitialization(Expr expr) {
|
||||
not ignoreExpr(expr) and
|
||||
(
|
||||
exists(Initializer init | init.getExpr().getFullyConverted() = expr) or
|
||||
exists(ClassAggregateLiteral initList | initList.getAFieldExpr(_).getFullyConverted() = expr) or
|
||||
exists(Initializer init | init.getExpr().getFullyConverted() = expr)
|
||||
or
|
||||
exists(ClassAggregateLiteral initList | initList.getAFieldExpr(_).getFullyConverted() = expr)
|
||||
or
|
||||
exists(ArrayOrVectorAggregateLiteral initList |
|
||||
initList.getAnElementExpr(_).getFullyConverted() = expr
|
||||
) or
|
||||
exists(ReturnStmt returnStmt | returnStmt.getExpr().getFullyConverted() = expr) or
|
||||
exists(ConstructorFieldInit fieldInit | fieldInit.getExpr().getFullyConverted() = expr) or
|
||||
exists(NewExpr newExpr | newExpr.getInitializer().getFullyConverted() = expr) or
|
||||
exists(ThrowExpr throw | throw.getExpr().getFullyConverted() = expr) or
|
||||
exists(TemporaryObjectExpr temp | temp.getExpr() = expr) or
|
||||
)
|
||||
or
|
||||
exists(ReturnStmt returnStmt |
|
||||
returnStmt.getExpr().getFullyConverted() = expr and
|
||||
hasReturnValue(returnStmt.getEnclosingFunction())
|
||||
)
|
||||
or
|
||||
exists(ConstructorFieldInit fieldInit | fieldInit.getExpr().getFullyConverted() = expr)
|
||||
or
|
||||
exists(NewExpr newExpr | newExpr.getInitializer().getFullyConverted() = expr)
|
||||
or
|
||||
exists(ThrowExpr throw | throw.getExpr().getFullyConverted() = expr)
|
||||
or
|
||||
exists(TemporaryObjectExpr temp | temp.getExpr() = expr)
|
||||
or
|
||||
exists(LambdaExpression lambda | lambda.getInitializer().getFullyConverted() = expr)
|
||||
)
|
||||
} or
|
||||
@@ -751,8 +765,6 @@ newtype TTranslatedElement =
|
||||
// on `*this` without an `Expr`.
|
||||
TTranslatedStructorQualifierSideEffect(Call call, SideEffectOpcode opcode) {
|
||||
not ignoreSideEffects(call) and
|
||||
// Don't bother with destructor calls for now, since we won't see very many of them in the IR
|
||||
// until we start injecting implicit destructor calls.
|
||||
call instanceof ConstructorCall and
|
||||
opcode = getASideEffectOpcode(call, -1)
|
||||
} or
|
||||
@@ -866,6 +878,23 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
1 + sum(TranslatedElement child | child = this.getChildByRank(_) | child.getDescendantCount())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element has implicit destructor calls that should follow it.
|
||||
*/
|
||||
predicate hasAnImplicitDestructorCall() { none() }
|
||||
|
||||
/**
|
||||
* Gets the child index of the first destructor call that should be executed after this `TranslatedElement`
|
||||
*/
|
||||
int getFirstDestructorCallIndex() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this `TranslatedElement` includes any destructor calls that must be performed after
|
||||
* it in its `getChildSuccessorInternal`, `getInstructionSuccessorInternal`, and
|
||||
* `getALastInstructionInternal` relations, rather than needing them inserted.
|
||||
*/
|
||||
predicate handlesDestructorsExplicitly() { none() }
|
||||
|
||||
private int getUniqueId() {
|
||||
if not exists(this.getParent())
|
||||
then result = 0
|
||||
@@ -901,15 +930,81 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
/**
|
||||
* Gets the successor instruction of the instruction that was generated by
|
||||
* this element for tag `tag`. The successor edge kind is specified by `kind`.
|
||||
* This predicate does not usually include destructors, which are inserted as
|
||||
* part of `getInstructionSuccessor` unless `handlesDestructorsExplicitly`
|
||||
* holds.
|
||||
*/
|
||||
abstract Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind);
|
||||
abstract Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind);
|
||||
|
||||
/**
|
||||
* Gets the successor instruction of the instruction that was generated by
|
||||
* this element for tag `tag`. The successor edge kind is specified by `kind`.
|
||||
*/
|
||||
final Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
if
|
||||
this.hasAnImplicitDestructorCall() and
|
||||
this.getInstruction(tag) = this.getALastInstructionInternal() and
|
||||
not this.handlesDestructorsExplicitly()
|
||||
then
|
||||
result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind) and
|
||||
kind instanceof GotoEdge
|
||||
else result = this.getInstructionSuccessorInternal(tag, kind)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction within this `TranslatedElement` (including its transitive children) which
|
||||
* will be followed by an instruction outside the `TranslatedElement`.
|
||||
*/
|
||||
final Instruction getALastInstruction() {
|
||||
if this.hasAnImplicitDestructorCall() and not this.handlesDestructorsExplicitly()
|
||||
then result = this.getChild(max(int n | exists(this.getChild(n)))).getALastInstruction() // last destructor
|
||||
else result = this.getALastInstructionInternal()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instruction within this `TranslatedElement` (including its transitive children) which
|
||||
* will be followed by an instruction outside the `TranslatedElement`.
|
||||
* This predicate does not usually include destructors, which are inserted as
|
||||
* part of `getALastInstruction` unless `handlesDestructorsExplicitly` holds.
|
||||
*/
|
||||
abstract Instruction getALastInstructionInternal();
|
||||
|
||||
TranslatedElement getLastChild() { none() }
|
||||
|
||||
/**
|
||||
* Gets the successor instruction to which control should flow after the
|
||||
* child element specified by `child` has finished execution. The successor
|
||||
* edge kind is specified by `kind`.
|
||||
* This predicate does not usually include destructors, which are inserted as
|
||||
* part of `getChildSuccessor` unless `handlesDestructorsExplicitly` holds.
|
||||
*/
|
||||
Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
/**
|
||||
* Gets the successor instruction to which control should flow after the
|
||||
* child element specified by `child` has finished execution. The successor
|
||||
* edge kind is specified by `kind`.
|
||||
*/
|
||||
abstract Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind);
|
||||
final Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
(
|
||||
if
|
||||
// this is the last child and we need to handle destructors for it
|
||||
this.hasAnImplicitDestructorCall() and
|
||||
not this.handlesDestructorsExplicitly() and
|
||||
child = this.getLastChild()
|
||||
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
|
||||
else result = this.getChildSuccessorInternal(child, kind)
|
||||
)
|
||||
or
|
||||
not this.handlesDestructorsExplicitly() and
|
||||
exists(int id |
|
||||
id >= this.getFirstDestructorCallIndex() and
|
||||
child = this.getChild(id) and
|
||||
if id = max(int n | exists(this.getChild(n)))
|
||||
then result = this.getParent().getChildSuccessor(this, kind)
|
||||
else result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instruction to which control should flow if an exception is thrown
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -114,7 +114,11 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(ExitFunctionTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = EnterFunctionTag() and
|
||||
@@ -150,7 +154,7 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int paramIndex | child = this.getParameter(paramIndex) |
|
||||
if
|
||||
exists(func.getParameter(paramIndex + 1)) or
|
||||
@@ -379,7 +383,13 @@ abstract class TranslatedParameter extends TranslatedElement {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.hasIndirection()
|
||||
then result = this.getInstruction(InitializerIndirectStoreTag())
|
||||
else result = this.getInstruction(InitializerStoreTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
@@ -397,7 +407,9 @@ abstract class TranslatedParameter extends TranslatedElement {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = InitializerVariableAddressTag() and
|
||||
@@ -611,15 +623,23 @@ class TranslatedConstructorInitList extends TranslatedElement, InitializationCon
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getLastChild().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id))))
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Function getFunction() { result = func }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
if exists(this.getChild(id + 1))
|
||||
@@ -678,15 +698,23 @@ class TranslatedDestructorDestructionList extends TranslatedElement,
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id)))).getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id))))
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Function getFunction() { result = func }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
if exists(this.getChild(id + 1))
|
||||
@@ -728,7 +756,20 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if exists(this.getAChild())
|
||||
then
|
||||
result =
|
||||
max(TranslatedElement child, int id | child = this.getChild(id) | child order by id)
|
||||
.getFirstInstruction(any(GotoEdge goto))
|
||||
else result = this.getParent().getChildSuccessor(this, any(GotoEdge goto))
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result = this.getChild(max(int id | exists(this.getChild(id))))
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(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
|
||||
@@ -746,7 +787,7 @@ class TranslatedReadEffects extends TranslatedElement, TTranslatedReadEffects {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
private TranslatedThisReadEffect getTranslatedThisReadEffect(Function func) {
|
||||
@@ -760,9 +801,9 @@ private TranslatedParameterReadEffect getTranslatedParameterReadEffect(Parameter
|
||||
abstract class TranslatedReadEffect extends TranslatedElement {
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -772,6 +813,10 @@ abstract class TranslatedReadEffect extends TranslatedElement {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
opcode instanceof Opcode::ReturnIndirection and
|
||||
tag = OnlyInstructionTag() and
|
||||
|
||||
@@ -27,6 +27,10 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(ExitFunctionTag())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int n) {
|
||||
n = 1 and
|
||||
result = getTranslatedInitialization(var.getInitializer().getExpr().getFullyConverted())
|
||||
@@ -58,7 +62,7 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
type = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = EnterFunctionTag() and
|
||||
@@ -81,7 +85,7 @@ class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getChild(1) and
|
||||
result = this.getInstruction(ReturnTag()) and
|
||||
kind instanceof GotoEdge
|
||||
|
||||
@@ -35,13 +35,19 @@ abstract class InitializationContext extends TranslatedElement {
|
||||
* declarations, `return` statements, and `throw` expressions.
|
||||
*/
|
||||
abstract class TranslatedVariableInitialization extends TranslatedElement, InitializationContext {
|
||||
final override TranslatedElement getChild(int id) { id = 0 and result = this.getInitialization() }
|
||||
TranslatedElement getChildInternal(int id) { id = 0 and result = this.getInitialization() }
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(InitializerVariableAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitialization().getALastInstruction()
|
||||
or
|
||||
not exists(this.getInitialization()) and result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = InitializerVariableAddressTag() and
|
||||
opcode instanceof Opcode::VariableAddress and
|
||||
@@ -53,7 +59,7 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
|
||||
resultType = getTypeForPRValue(this.getTargetType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
(
|
||||
tag = InitializerVariableAddressTag() and
|
||||
if this.hasUninitializedInstruction()
|
||||
@@ -71,7 +77,7 @@ abstract class TranslatedVariableInitialization extends TranslatedElement, Initi
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getInitializationSuccessor(kind)
|
||||
}
|
||||
@@ -177,7 +183,11 @@ abstract class TranslatedListInitialization extends TranslatedInitialization, In
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(max(int i | exists(this.getChild(i)))).getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getChild(index) and
|
||||
if exists(this.getChild(index + 1))
|
||||
@@ -190,7 +200,9 @@ abstract class TranslatedListInitialization extends TranslatedInitialization, In
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() { result = this.getContext().getTargetAddress() }
|
||||
|
||||
@@ -260,18 +272,22 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
|
||||
not expr instanceof StringLiteral
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = InitializerStoreTag() and
|
||||
opcode instanceof Opcode::Store and
|
||||
resultType = getTypeForPRValue(this.getContext().getTargetType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = InitializerStoreTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and
|
||||
result = this.getInstruction(InitializerStoreTag()) and
|
||||
kind instanceof GotoEdge
|
||||
@@ -296,6 +312,12 @@ class TranslatedSimpleDirectInitialization extends TranslatedDirectInitializatio
|
||||
class TranslatedStringLiteralInitialization extends TranslatedDirectInitialization {
|
||||
override StringLiteral expr;
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.zeroInitRange(_, _)
|
||||
then result = this.getInstruction(ZeroPadStringStoreTag())
|
||||
else result = this.getInstruction(InitializerStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
// Load the string literal to make it a prvalue of type `char[len]`
|
||||
tag = InitializerLoadStringTag() and
|
||||
@@ -337,7 +359,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
tag = InitializerLoadStringTag() and
|
||||
result = this.getInstruction(InitializerStoreTag())
|
||||
@@ -367,7 +389,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and
|
||||
result = this.getInstruction(InitializerLoadStringTag()) and
|
||||
kind instanceof GotoEdge
|
||||
@@ -457,16 +479,22 @@ class TranslatedConstructorInitialization extends TranslatedDirectInitialization
|
||||
{
|
||||
override ConstructorCall expr;
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitializer().getALastInstruction()
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitializer() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getInitializer() }
|
||||
|
||||
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
none()
|
||||
}
|
||||
@@ -558,23 +586,29 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio
|
||||
this = TTranslatedExplicitFieldInitialization(ast, field, expr, position)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitialization().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() {
|
||||
result = this.getInstruction(this.getFieldAddressTag())
|
||||
}
|
||||
|
||||
override Type getTargetType() { result = field.getUnspecifiedType() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = this.getFieldAddressTag() and
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(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() }
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getInitialization() }
|
||||
|
||||
private TranslatedInitialization getInitialization() {
|
||||
result = getTranslatedInitialization(expr)
|
||||
}
|
||||
@@ -595,6 +629,10 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
{
|
||||
TranslatedFieldValueInitialization() { this = TTranslatedFieldValueInitialization(ast, field) }
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(this.getFieldDefaultValueStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
TranslatedFieldInitialization.super.hasInstruction(opcode, tag, resultType)
|
||||
or
|
||||
@@ -607,7 +645,7 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
resultType = getTypeForPRValue(field.getUnspecifiedType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = this.getFieldAddressTag() and
|
||||
@@ -639,7 +677,7 @@ class TranslatedFieldValueInitialization extends TranslatedFieldInitialization,
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
@@ -689,7 +727,7 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
||||
resultType = getTypeForGLValue(this.getElementType())
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = this.getElementIndexTag() and
|
||||
result = this.getInstruction(this.getElementAddressTag()) and
|
||||
kind instanceof GotoEdge
|
||||
@@ -743,20 +781,24 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ
|
||||
this = TTranslatedExplicitElementInitialization(initList, elementIndex, position)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInitialization().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() {
|
||||
result = this.getInstruction(this.getElementAddressTag())
|
||||
}
|
||||
|
||||
override Type getTargetType() { result = this.getElementType() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessorInternal(tag, kind)
|
||||
or
|
||||
tag = this.getElementAddressTag() and
|
||||
result = this.getInitialization().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
@@ -788,6 +830,10 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
this = TTranslatedElementValueInitialization(initList, elementIndex, elementCount)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(this.getElementDefaultValueStoreTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
TranslatedElementInitialization.super.hasInstruction(opcode, tag, resultType)
|
||||
or
|
||||
@@ -800,8 +846,8 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
resultType = this.getDefaultValueType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessor(tag, kind)
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
result = TranslatedElementInitialization.super.getInstructionSuccessorInternal(tag, kind)
|
||||
or
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
@@ -836,7 +882,7 @@ class TranslatedElementValueInitialization extends TranslatedElementInitializati
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
@@ -876,11 +922,13 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
|
||||
|
||||
final override Function getFunction() { result = getEnclosingFunction(call) }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getStructorCall() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getStructorCall() }
|
||||
|
||||
final TranslatedExpr getStructorCall() { result = getTranslatedExpr(call) }
|
||||
}
|
||||
|
||||
@@ -894,13 +942,17 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getStructorCall().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::ConvertToNonVirtualBase and
|
||||
resultType = getTypeForGLValue(call.getTarget().getDeclaringType())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getStructorCall().getFirstInstruction(kind)
|
||||
}
|
||||
@@ -947,11 +999,17 @@ class TranslatedConstructorDelegationInit extends TranslatedConstructorCallFromC
|
||||
result = this.getStructorCall().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getStructorCall().getALastInstruction()
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getReceiver() {
|
||||
result = getTranslatedFunction(this.getFunction()).getInitializeThisInstruction()
|
||||
@@ -1009,6 +1067,8 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() { none() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
@@ -1017,9 +1077,9 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
|
||||
override Declaration getFunction() { result = this.getParent().getFunction() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
TranslatedConstructorBareInit getTranslatedConstructorBareInit(ConstructorInit init) {
|
||||
|
||||
@@ -138,7 +138,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
result = "1"
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
// Generate -1 -> Compare condition
|
||||
tag = TryExceptGenerateNegativeOne() and
|
||||
kind instanceof GotoEdge and
|
||||
@@ -202,7 +202,7 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
child = this.getTranslatedCondition() and
|
||||
result = this.getInstruction(TryExceptGenerateNegativeOne())
|
||||
@@ -211,6 +211,14 @@ class TranslatedMicrosoftTryExceptHandler extends TranslatedElement,
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getTranslatedHandler() }
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getTranslatedHandler().getALastInstruction()
|
||||
or
|
||||
result = this.getInstruction(UnwindTag())
|
||||
}
|
||||
|
||||
private TranslatedExpr getTranslatedCondition() {
|
||||
result = getTranslatedExpr(tryExcept.getCondition())
|
||||
}
|
||||
@@ -235,6 +243,27 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
|
||||
|
||||
TranslatedStmt() { this = TTranslatedStmt(stmt) }
|
||||
|
||||
abstract TranslatedElement getChildInternal(int id);
|
||||
|
||||
final override TranslatedElement getChild(int id) {
|
||||
result = this.getChildInternal(id)
|
||||
or
|
||||
exists(int destructorIndex |
|
||||
result.(TranslatedExpr).getExpr() = stmt.getImplicitDestructorCall(destructorIndex) and
|
||||
id = this.getFirstDestructorCallIndex() + destructorIndex
|
||||
)
|
||||
}
|
||||
|
||||
final override int getFirstDestructorCallIndex() {
|
||||
result = max(int childId | exists(this.getChildInternal(childId))) + 1
|
||||
or
|
||||
not exists(this.getChildInternal(_)) and result = 0
|
||||
}
|
||||
|
||||
final override predicate hasAnImplicitDestructorCall() {
|
||||
exists(stmt.getAnImplicitDestructorCall())
|
||||
}
|
||||
|
||||
final override string toString() { result = stmt.toString() }
|
||||
|
||||
final override Locatable getAst() { result = stmt }
|
||||
@@ -252,25 +281,29 @@ class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
stmt instanceof SwitchCase
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,7 +314,7 @@ class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
class TranslatedDeclStmt extends TranslatedStmt {
|
||||
override DeclStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) { result = this.getDeclarationEntry(id) }
|
||||
override TranslatedElement getChildInternal(int id) { result = this.getDeclarationEntry(id) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
@@ -294,6 +327,12 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(this.getChildCount() - 1).getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(this.getChildCount() - 1) }
|
||||
|
||||
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
|
||||
|
||||
IRDeclarationEntry getIRDeclarationEntry(int index) {
|
||||
@@ -318,9 +357,9 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getDeclarationEntry(index) and
|
||||
if index = (this.getChildCount() - 1)
|
||||
@@ -335,7 +374,7 @@ class TranslatedExprStmt extends TranslatedStmt {
|
||||
|
||||
TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) }
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 0 and result = this.getExpr() }
|
||||
override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getExpr() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
@@ -345,9 +384,15 @@ class TranslatedExprStmt extends TranslatedStmt {
|
||||
result = this.getExpr().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getExpr().getALastInstruction()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override TranslatedElement getLastChild() { result = this.getExpr() }
|
||||
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getExpr() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -359,6 +404,21 @@ abstract class TranslatedReturnStmt extends TranslatedStmt {
|
||||
final TranslatedFunction getEnclosingFunction() {
|
||||
result = getTranslatedFunction(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
child = this.getChild(id) and
|
||||
id >= this.getFirstDestructorCallIndex() and
|
||||
(
|
||||
result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getChild(id + 1)) and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
final override predicate handlesDestructorsExplicitly() { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,7 +428,19 @@ class TranslatedReturnValueStmt extends TranslatedReturnStmt, TranslatedVariable
|
||||
TranslatedReturnValueStmt() { stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) }
|
||||
|
||||
final override Instruction getInitializationSuccessor(EdgeKind kind) {
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(1).getFirstInstruction(kind)
|
||||
else result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
result = TranslatedVariableInitialization.super.getChildSuccessorInternal(child, kind)
|
||||
or
|
||||
result = TranslatedReturnStmt.super.getChildSuccessorInternal(child, kind)
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
result = TranslatedVariableInitialization.super.getChildInternal(id)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
|
||||
@@ -390,7 +462,7 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
stmt.hasExpr() and not hasReturnValue(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and
|
||||
result = this.getExpr()
|
||||
}
|
||||
@@ -399,21 +471,31 @@ class TranslatedReturnVoidExpressionStmt extends TranslatedReturnStmt {
|
||||
result = this.getExpr().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(max(int id | exists(this.getChild(id)))).getALastInstruction()
|
||||
else result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(1).getFirstInstruction(kind)
|
||||
else result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getExpr() and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
or
|
||||
result = TranslatedReturnStmt.super.getChildSuccessorInternal(child, kind)
|
||||
}
|
||||
|
||||
private TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr()) }
|
||||
@@ -428,25 +510,43 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt {
|
||||
not stmt.hasExpr() and not hasReturnValue(stmt.getEnclosingFunction())
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(max(int id | exists(this.getChild(id)))).getALastInstruction()
|
||||
else result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
opcode instanceof Opcode::NoOp and
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(0).getFirstInstruction(kind)
|
||||
else result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id |
|
||||
this.getChild(id) = child and
|
||||
(
|
||||
result = this.getChild(id + 1).getFirstInstruction(kind)
|
||||
or
|
||||
not exists(this.getChild(id + 1)) and
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -464,6 +564,16 @@ class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariab
|
||||
result = this.getEnclosingFunction().getReturnSuccessorInstruction(kind)
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
result = TranslatedVariableInitialization.super.getChildInternal(id)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
result = TranslatedVariableInitialization.super.getChildSuccessorInternal(child, kind)
|
||||
or
|
||||
result = TranslatedReturnStmt.super.getChildSuccessorInternal(child, kind)
|
||||
}
|
||||
|
||||
final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() }
|
||||
|
||||
final override TranslatedInitialization getInitialization() { none() }
|
||||
@@ -518,7 +628,7 @@ private class TryOrMicrosoftTryStmt extends Stmt {
|
||||
class TranslatedTryStmt extends TranslatedStmt {
|
||||
override TryOrMicrosoftTryStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getBody()
|
||||
or
|
||||
result = this.getHandler(id - 1)
|
||||
@@ -531,13 +641,23 @@ class TranslatedTryStmt extends TranslatedStmt {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getLastChild().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
if exists(this.getFinally())
|
||||
then result = this.getFinally()
|
||||
else result = [this.getBody(), this.getHandler(_)]
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(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.
|
||||
@@ -581,7 +701,7 @@ class TranslatedTryStmt extends TranslatedStmt {
|
||||
class TranslatedBlock extends TranslatedStmt {
|
||||
override BlockStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) { result = this.getStmt(id) }
|
||||
override TranslatedElement getChildInternal(int id) { result = this.getStmt(id) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
this.isEmpty() and
|
||||
@@ -596,18 +716,26 @@ class TranslatedBlock extends TranslatedStmt {
|
||||
else result = this.getStmt(0).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
if this.isEmpty()
|
||||
then result = this.getInstruction(OnlyInstructionTag())
|
||||
else result = this.getStmt(this.getStmtCount() - 1).getFirstInstruction(any(GotoEdge goto))
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getStmt(this.getStmtCount() - 1) }
|
||||
|
||||
private predicate isEmpty() { not exists(stmt.getStmt(0)) }
|
||||
|
||||
private TranslatedStmt getStmt(int index) { result = getTranslatedStmt(stmt.getStmt(index)) }
|
||||
|
||||
private int getStmtCount() { result = stmt.getNumStmt() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getStmt(index) and
|
||||
if index = (this.getStmtCount() - 1)
|
||||
@@ -623,14 +751,20 @@ class TranslatedBlock extends TranslatedStmt {
|
||||
abstract class TranslatedHandler extends TranslatedStmt {
|
||||
override Handler stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) { id = 1 and result = this.getBlock() }
|
||||
override TranslatedElement getChildInternal(int id) { id = 1 and result = this.getBlock() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(CatchTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getBlock().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getBlock() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBlock() and result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
@@ -656,20 +790,20 @@ class TranslatedCatchByTypeHandler extends TranslatedHandler {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
result = super.getChild(id)
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
result = super.getChildInternal(id)
|
||||
or
|
||||
id = 0 and result = this.getParameter()
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
result = super.getChildSuccessor(child, kind)
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
result = super.getChildSuccessorInternal(child, kind)
|
||||
or
|
||||
child = this.getParameter() and
|
||||
result = this.getBlock().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = CatchTag() and
|
||||
(
|
||||
kind instanceof GotoEdge and
|
||||
@@ -702,7 +836,7 @@ class TranslatedCatchAnyHandler extends TranslatedHandler {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = CatchTag() and
|
||||
result = this.getBlock().getFirstInstruction(kind)
|
||||
}
|
||||
@@ -717,7 +851,13 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getElse().getALastInstruction() or result = this.getThen().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getElse() or result = this.getThen() }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getCondition()
|
||||
@@ -747,7 +887,7 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
|
||||
private predicate hasElse() { exists(stmt.getElse()) }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
@@ -761,7 +901,7 @@ class TranslatedIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
@@ -783,7 +923,7 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getCondition()
|
||||
@@ -813,7 +953,7 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
|
||||
private predicate hasElse() { exists(stmt.getElse()) }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
@@ -827,7 +967,7 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
@@ -838,11 +978,23 @@ class TranslatedConstExprIfStmt extends TranslatedStmt, ConditionContext {
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getThen().getALastInstruction()
|
||||
or
|
||||
result = this.getElse().getALastInstruction()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
override Loop stmt;
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getCondition().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getCondition() }
|
||||
|
||||
final TranslatedCondition getCondition() {
|
||||
result = getTranslatedCondition(stmt.getCondition().getFullyConverted())
|
||||
}
|
||||
@@ -857,7 +1009,7 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
|
||||
final predicate hasCondition() { exists(stmt.getCondition()) }
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getCondition()
|
||||
or
|
||||
id = 1 and result = this.getBody()
|
||||
@@ -867,13 +1019,15 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
none()
|
||||
}
|
||||
|
||||
final override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -882,13 +1036,36 @@ abstract class TranslatedLoop extends TranslatedStmt, ConditionContext {
|
||||
class TranslatedWhileStmt extends TranslatedLoop {
|
||||
TranslatedWhileStmt() { stmt instanceof WhileStmt }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getCondition()
|
||||
or
|
||||
id = 1 and result = this.getBody()
|
||||
or
|
||||
exists(int n |
|
||||
result.getAst() = stmt.getImplicitDestructorCall(n) and
|
||||
id = 2 + n
|
||||
)
|
||||
}
|
||||
|
||||
override predicate handlesDestructorsExplicitly() { any() }
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBody() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
child = this.getChild(this.getFirstDestructorCallIndex()) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -899,7 +1076,7 @@ class TranslatedDoStmt extends TranslatedLoop {
|
||||
result = this.getBody().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getBody() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
@@ -908,7 +1085,16 @@ class TranslatedDoStmt extends TranslatedLoop {
|
||||
class TranslatedForStmt extends TranslatedLoop {
|
||||
override ForStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override predicate handlesDestructorsExplicitly() { any() }
|
||||
|
||||
final override Instruction getChildFalseSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
if this.hasAnImplicitDestructorCall()
|
||||
then result = this.getChild(this.getFirstDestructorCallIndex()).getFirstInstruction(kind)
|
||||
else result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getCondition()
|
||||
@@ -916,6 +1102,11 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
id = 2 and result = this.getUpdate()
|
||||
or
|
||||
id = 3 and result = this.getBody()
|
||||
or
|
||||
exists(int n |
|
||||
result.getAst() = stmt.getImplicitDestructorCall(n) and
|
||||
id = 4 + n
|
||||
)
|
||||
}
|
||||
|
||||
private TranslatedStmt getInitialization() {
|
||||
@@ -934,7 +1125,7 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
else result = this.getFirstConditionInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
@@ -946,6 +1137,19 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
)
|
||||
or
|
||||
child = this.getUpdate() and result = this.getFirstConditionInstruction(kind)
|
||||
or
|
||||
exists(int destructorId |
|
||||
destructorId >= this.getFirstDestructorCallIndex() and
|
||||
child = this.getChild(destructorId) and
|
||||
result = this.getChild(destructorId + 1).getFirstInstruction(kind)
|
||||
)
|
||||
or
|
||||
exists(int lastDestructorIndex |
|
||||
lastDestructorIndex =
|
||||
max(int n | exists(this.getChild(n)) and n >= this.getFirstDestructorCallIndex()) and
|
||||
child = this.getChild(lastDestructorIndex) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,7 +1163,7 @@ class TranslatedForStmt extends TranslatedLoop {
|
||||
class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
override RangeBasedForStmt stmt;
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getRangeVariableDeclStmt()
|
||||
@@ -988,7 +1192,13 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
else result = this.getFirstRangeVariableDeclStmtInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getCondition().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getCondition() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstRangeVariableDeclStmtInstruction(kind)
|
||||
or
|
||||
@@ -1012,7 +1222,7 @@ class TranslatedRangeBasedForStmt extends TranslatedStmt, ConditionContext {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child, EdgeKind kind) {
|
||||
child = this.getCondition() and
|
||||
@@ -1070,7 +1280,11 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -1078,12 +1292,12 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
private EdgeKind getCaseEdge(SwitchCase switchCase) {
|
||||
@@ -1114,7 +1328,13 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
else result = this.getFirstExprInstruction(kind)
|
||||
}
|
||||
|
||||
override TranslatedElement getChild(int id) {
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getBody().getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getBody() }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getInitialization()
|
||||
or
|
||||
id = 1 and result = this.getExpr()
|
||||
@@ -1140,7 +1360,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
result = this.getExpr().getResult()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = SwitchBranchTag() and
|
||||
exists(SwitchCase switchCase |
|
||||
switchCase = stmt.getASwitchCase() and
|
||||
@@ -1154,7 +1374,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getInitialization() and
|
||||
result = this.getFirstExprInstruction(kind)
|
||||
or
|
||||
@@ -1169,7 +1389,7 @@ class TranslatedSwitchStmt extends TranslatedStmt {
|
||||
class TranslatedAsmStmt extends TranslatedStmt {
|
||||
override AsmStmt stmt;
|
||||
|
||||
override TranslatedExpr getChild(int id) {
|
||||
override TranslatedExpr getChildInternal(int id) {
|
||||
result = getTranslatedExpr(stmt.getChild(id).(Expr).getFullyConverted())
|
||||
}
|
||||
|
||||
@@ -1181,6 +1401,8 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() { result = this.getInstruction(AsmTag()) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = AsmTag() and
|
||||
opcode instanceof Opcode::InlineAsm and
|
||||
@@ -1191,7 +1413,7 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
exists(int index |
|
||||
tag = AsmTag() and
|
||||
operandTag = asmOperand(index) and
|
||||
result = this.getChild(index).getResult()
|
||||
result = this.getChildInternal(index).getResult()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1203,12 +1425,12 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
result = getUnknownType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AsmTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int index |
|
||||
child = this.getChild(index) and
|
||||
if exists(this.getChild(index + 1))
|
||||
@@ -1223,7 +1445,7 @@ class TranslatedAsmStmt extends TranslatedStmt {
|
||||
class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
override VlaDimensionStmt stmt;
|
||||
|
||||
override TranslatedExpr getChild(int id) {
|
||||
override TranslatedExpr getChildInternal(int id) {
|
||||
id = 0 and
|
||||
result = getTranslatedExpr(stmt.getDimensionExpr().getFullyConverted())
|
||||
}
|
||||
@@ -1232,13 +1454,19 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
result = this.getChild(0).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getChild(0).getALastInstruction()
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(0) }
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
none()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getChild(0) and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
@@ -1247,13 +1475,17 @@ class TranslatedVlaDimensionStmt extends TranslatedStmt {
|
||||
class TranslatedVlaDeclarationStmt extends TranslatedStmt {
|
||||
override VlaDeclStmt stmt;
|
||||
|
||||
override TranslatedExpr getChild(int id) { none() }
|
||||
override TranslatedExpr getChildInternal(int id) { none() }
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
// TODO: This needs a new kind of instruction that represents initialization of a VLA.
|
||||
// For now we just emit a `NoOp` instruction so that the CFG isn't incomplete.
|
||||
@@ -1262,10 +1494,10 @@ class TranslatedVlaDeclarationStmt extends TranslatedStmt {
|
||||
resultType = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getParent().getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
}
|
||||
|
||||
@@ -168,3 +168,57 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A destructor assocaited with a smart pointer. */
|
||||
private class SmartPtrDestructor extends Destructor, SideEffectFunction, AliasFunction {
|
||||
SmartPtr declaringType;
|
||||
|
||||
SmartPtrDestructor() {
|
||||
declaringType = this.getDeclaringType() and not this.isFromUninstantiatedTemplate(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the destructor associated with the base type of this smart pointer.
|
||||
*/
|
||||
private Destructor getBaseTypeDestructor() {
|
||||
result.getDeclaringType() = declaringType.getBaseType()
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificReadSideEffects() {
|
||||
this.getBaseTypeDestructor().(SideEffectFunction).hasOnlySpecificReadSideEffects()
|
||||
or
|
||||
// If there's no declared destructor for the base type then it won't have
|
||||
// any strange read side effects.
|
||||
not exists(this.getBaseTypeDestructor())
|
||||
}
|
||||
|
||||
override predicate hasOnlySpecificWriteSideEffects() {
|
||||
this.getBaseTypeDestructor().(SideEffectFunction).hasOnlySpecificWriteSideEffects()
|
||||
or
|
||||
// If there's no declared destructor for the base type then it won't have
|
||||
// any strange write side effects.
|
||||
not exists(this.getBaseTypeDestructor())
|
||||
}
|
||||
|
||||
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
|
||||
i = -1 and buffer = false
|
||||
}
|
||||
|
||||
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
|
||||
i = -1 and buffer = false and mustWrite = true
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) {
|
||||
this.getBaseTypeDestructor().(AliasFunction).parameterNeverEscapes(index)
|
||||
or
|
||||
// If there's no declared destructor for the base type then it won't cause
|
||||
// anything to escape.
|
||||
not exists(this.getBaseTypeDestructor()) and
|
||||
index = -1
|
||||
}
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) {
|
||||
// A destructor call does not have a return value
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4316,8 +4316,6 @@ ir.cpp:
|
||||
# 365| ValueCategory = prvalue
|
||||
# 361| getStmt(2): [LabelStmt] label ...:
|
||||
# 367| getStmt(1): [ReturnStmt] return ...
|
||||
# 369| [TopLevelFunction] void VoidFunc()
|
||||
# 369| <params>:
|
||||
# 370| [TopLevelFunction] int Add(int, int)
|
||||
# 370| <params>:
|
||||
# 370| getParameter(0): [Parameter] x
|
||||
@@ -5553,6 +5551,8 @@ ir.cpp:
|
||||
# 605| Type = [RValueReferenceType] String &&
|
||||
# 607| [ConstMemberFunction] char const* String::c_str() const
|
||||
# 607| <params>:
|
||||
# 608| [MemberFunction] char String::pop_back()
|
||||
# 608| <params>:
|
||||
# 613| [TopLevelFunction] String ReturnObject()
|
||||
# 613| <params>:
|
||||
# 615| [TopLevelFunction] void DeclareObject()
|
||||
@@ -9386,6 +9386,10 @@ ir.cpp:
|
||||
# 1059| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<ClassWithDestructor> &
|
||||
# 1059| [CopyAssignmentOperator] vector<String>& vector<String>::operator=(vector<String> const&)
|
||||
# 1059| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<String> &
|
||||
# 1059| [CopyAssignmentOperator] vector<int>& vector<int>::operator=(vector<int> const&)
|
||||
# 1059| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -9394,6 +9398,10 @@ ir.cpp:
|
||||
# 1059| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<ClassWithDestructor> &
|
||||
# 1059| [CopyConstructor] void vector<String>::vector(vector<String> const&)
|
||||
# 1059| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const vector<String> &
|
||||
# 1059| [CopyConstructor] void vector<int>::vector(vector<int> const&)
|
||||
# 1059| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -9406,6 +9414,14 @@ ir.cpp:
|
||||
# 1060| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] iterator &&
|
||||
# 1060| [CopyAssignmentOperator] vector<String>::iterator& vector<String>::iterator::operator=(vector<String>::iterator const public&)
|
||||
# 1060| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const iterator &
|
||||
# 1060| [MoveAssignmentOperator] vector<String>::iterator& vector<String>::iterator::operator=(vector<String>::iterator&&)
|
||||
# 1060| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] iterator &&
|
||||
# 1060| [CopyAssignmentOperator] vector<int>::iterator& vector<int>::iterator::operator=(vector<int>::iterator const public&)
|
||||
# 1060| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -9416,12 +9432,16 @@ ir.cpp:
|
||||
#-----| Type = [RValueReferenceType] iterator &&
|
||||
# 1062| [MemberFunction] vector<ClassWithDestructor>::iterator& vector<ClassWithDestructor>::iterator::operator++()
|
||||
# 1062| <params>:
|
||||
# 1062| [MemberFunction] vector<String>::iterator& vector<String>::iterator::operator++()
|
||||
# 1062| <params>:
|
||||
# 1062| [MemberFunction] vector<T>::iterator& vector<T>::iterator::operator++()
|
||||
# 1062| <params>:
|
||||
# 1062| [MemberFunction] vector<int>::iterator& vector<int>::iterator::operator++()
|
||||
# 1062| <params>:
|
||||
# 1063| [ConstMemberFunction] ClassWithDestructor& vector<ClassWithDestructor>::iterator::operator*() const
|
||||
# 1063| <params>:
|
||||
# 1063| [ConstMemberFunction] String& vector<String>::iterator::operator*() const
|
||||
# 1063| <params>:
|
||||
# 1063| [ConstMemberFunction] T& vector<T>::iterator::operator*() const
|
||||
# 1063| <params>:
|
||||
# 1063| [ConstMemberFunction] int& vector<int>::iterator::operator*() const
|
||||
@@ -9430,6 +9450,10 @@ ir.cpp:
|
||||
# 1065| <params>:
|
||||
# 1065| getParameter(0): [Parameter] right
|
||||
# 1065| Type = [NestedStruct] iterator
|
||||
# 1065| [ConstMemberFunction] bool vector<String>::iterator::operator!=(vector<String>::iterator) const
|
||||
# 1065| <params>:
|
||||
# 1065| getParameter(0): [Parameter] right
|
||||
# 1065| Type = [NestedStruct] iterator
|
||||
# 1065| [ConstMemberFunction] bool vector<T>::iterator::operator!=(vector<T>::iterator) const
|
||||
# 1065| <params>:
|
||||
# 1065| getParameter(0): [Parameter] right
|
||||
@@ -9442,6 +9466,10 @@ ir.cpp:
|
||||
# 1068| <params>:
|
||||
# 1068| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 1068| Type = [Class] ClassWithDestructor
|
||||
# 1068| [Constructor] void vector<String>::vector(String)
|
||||
# 1068| <params>:
|
||||
# 1068| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 1068| Type = [Struct] String
|
||||
# 1068| [Constructor] void vector<T>::vector(T)
|
||||
# 1068| <params>:
|
||||
# 1068| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -9458,12 +9486,16 @@ ir.cpp:
|
||||
# 1069| <params>:
|
||||
# 1070| [ConstMemberFunction] vector<ClassWithDestructor>::iterator vector<ClassWithDestructor>::begin() const
|
||||
# 1070| <params>:
|
||||
# 1070| [ConstMemberFunction] vector<String>::iterator vector<String>::begin() const
|
||||
# 1070| <params>:
|
||||
# 1070| [ConstMemberFunction] vector<T>::iterator vector<T>::begin() const
|
||||
# 1070| <params>:
|
||||
# 1070| [ConstMemberFunction] vector<int>::iterator vector<int>::begin() const
|
||||
# 1070| <params>:
|
||||
# 1071| [ConstMemberFunction] vector<ClassWithDestructor>::iterator vector<ClassWithDestructor>::end() const
|
||||
# 1071| <params>:
|
||||
# 1071| [ConstMemberFunction] vector<String>::iterator vector<String>::end() const
|
||||
# 1071| <params>:
|
||||
# 1071| [ConstMemberFunction] vector<T>::iterator vector<T>::end() const
|
||||
# 1071| <params>:
|
||||
# 1071| [ConstMemberFunction] vector<int>::iterator vector<int>::end() const
|
||||
@@ -17321,6 +17353,729 @@ ir.cpp:
|
||||
# 2208| Type = [LValueReferenceType] int &
|
||||
# 2208| ValueCategory = prvalue
|
||||
# 2209| getStmt(2): [ReturnStmt] return ...
|
||||
# 2212| [TopLevelFunction] void TryCatchDestructors(bool)
|
||||
# 2212| <params>:
|
||||
# 2212| getParameter(0): [Parameter] b
|
||||
# 2212| Type = [BoolType] bool
|
||||
# 2212| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2213| getStmt(0): [TryStmt] try { ... }
|
||||
# 2213| getStmt(): [BlockStmt] { ... }
|
||||
# 2214| getStmt(0): [DeclStmt] declaration
|
||||
# 2214| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2214| Type = [Struct] String
|
||||
# 2214| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2214| getExpr(): [ConstructorCall] call to String
|
||||
# 2214| Type = [VoidType] void
|
||||
# 2214| ValueCategory = prvalue
|
||||
# 2215| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2215| getCondition(): [VariableAccess] b
|
||||
# 2215| Type = [BoolType] bool
|
||||
# 2215| ValueCategory = prvalue(load)
|
||||
# 2215| getThen(): [BlockStmt] { ... }
|
||||
# 2216| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2216| getExpr(): [ThrowExpr] throw ...
|
||||
# 2216| Type = [PointerType] const char *
|
||||
# 2216| ValueCategory = prvalue
|
||||
# 2216| getExpr(): string literal
|
||||
# 2216| Type = [ArrayType] const char[15]
|
||||
# 2216| Value = [StringLiteral] "string literal"
|
||||
# 2216| ValueCategory = lvalue
|
||||
# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2219| Type = [VoidType] void
|
||||
# 2219| ValueCategory = prvalue
|
||||
# 2219| getQualifier(): [VariableAccess] s
|
||||
# 2219| Type = [Struct] String
|
||||
# 2219| ValueCategory = lvalue
|
||||
# 2216| getExpr().getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2216| Type = [PointerType] const char *
|
||||
# 2216| ValueCategory = prvalue
|
||||
# 2218| getStmt(2): [DeclStmt] declaration
|
||||
# 2218| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2
|
||||
# 2218| Type = [Struct] String
|
||||
# 2218| getVariable().getInitializer(): [Initializer] initializer for s2
|
||||
# 2218| getExpr(): [ConstructorCall] call to String
|
||||
# 2218| Type = [VoidType] void
|
||||
# 2218| ValueCategory = prvalue
|
||||
# 2219| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2219| Type = [VoidType] void
|
||||
# 2219| ValueCategory = prvalue
|
||||
# 2219| getQualifier(): [VariableAccess] s2
|
||||
# 2219| Type = [Struct] String
|
||||
# 2219| ValueCategory = lvalue
|
||||
# 2219| getImplicitDestructorCall(1): [DestructorCall] call to ~String
|
||||
# 2219| Type = [VoidType] void
|
||||
# 2219| ValueCategory = prvalue
|
||||
# 2219| getQualifier(): [VariableAccess] s
|
||||
# 2219| Type = [Struct] String
|
||||
# 2219| ValueCategory = lvalue
|
||||
# 2220| getChild(1): [Handler] <handler>
|
||||
# 2220| getBlock(): [CatchBlock] { ... }
|
||||
# 2221| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2221| getExpr(): [ThrowExpr] throw ...
|
||||
# 2221| Type = [Struct] String
|
||||
# 2221| ValueCategory = prvalue
|
||||
# 2221| getExpr(): [ConstructorCall] call to String
|
||||
# 2221| Type = [VoidType] void
|
||||
# 2221| ValueCategory = prvalue
|
||||
# 2221| getArgument(0): [VariableAccess] s
|
||||
# 2221| Type = [PointerType] const char *
|
||||
# 2221| ValueCategory = prvalue(load)
|
||||
# 2223| getChild(2): [Handler] <handler>
|
||||
# 2223| getBlock(): [CatchBlock] { ... }
|
||||
# 2225| getChild(3): [Handler] <handler>
|
||||
# 2225| getBlock(): [CatchAnyBlock] { ... }
|
||||
# 2226| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2226| getExpr(): [ReThrowExpr] re-throw exception
|
||||
# 2226| Type = [VoidType] void
|
||||
# 2226| ValueCategory = prvalue
|
||||
# 2228| getStmt(1): [ReturnStmt] return ...
|
||||
# 2230| [TopLevelFunction] void IfDestructors(bool)
|
||||
# 2230| <params>:
|
||||
# 2230| getParameter(0): [Parameter] b
|
||||
# 2230| Type = [BoolType] bool
|
||||
# 2230| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2231| getStmt(0): [DeclStmt] declaration
|
||||
# 2231| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1
|
||||
# 2231| Type = [Struct] String
|
||||
# 2231| getVariable().getInitializer(): [Initializer] initializer for s1
|
||||
# 2231| getExpr(): [ConstructorCall] call to String
|
||||
# 2231| Type = [VoidType] void
|
||||
# 2231| ValueCategory = prvalue
|
||||
# 2232| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2232| getCondition(): [VariableAccess] b
|
||||
# 2232| Type = [BoolType] bool
|
||||
# 2232| ValueCategory = prvalue(load)
|
||||
# 2232| getThen(): [BlockStmt] { ... }
|
||||
# 2233| getStmt(0): [DeclStmt] declaration
|
||||
# 2233| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2
|
||||
# 2233| Type = [Struct] String
|
||||
# 2233| getVariable().getInitializer(): [Initializer] initializer for s2
|
||||
# 2233| getExpr(): [ConstructorCall] call to String
|
||||
# 2233| Type = [VoidType] void
|
||||
# 2233| ValueCategory = prvalue
|
||||
# 2234| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2234| Type = [VoidType] void
|
||||
# 2234| ValueCategory = prvalue
|
||||
# 2234| getQualifier(): [VariableAccess] s2
|
||||
# 2234| Type = [Struct] String
|
||||
# 2234| ValueCategory = lvalue
|
||||
# 2234| getElse(): [BlockStmt] { ... }
|
||||
# 2235| getStmt(0): [DeclStmt] declaration
|
||||
# 2235| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s3
|
||||
# 2235| Type = [Struct] String
|
||||
# 2235| getVariable().getInitializer(): [Initializer] initializer for s3
|
||||
# 2235| getExpr(): [ConstructorCall] call to String
|
||||
# 2235| Type = [VoidType] void
|
||||
# 2235| ValueCategory = prvalue
|
||||
# 2236| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2236| Type = [VoidType] void
|
||||
# 2236| ValueCategory = prvalue
|
||||
# 2236| getQualifier(): [VariableAccess] s3
|
||||
# 2236| Type = [Struct] String
|
||||
# 2236| ValueCategory = lvalue
|
||||
# 2237| getStmt(2): [DeclStmt] declaration
|
||||
# 2237| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s4
|
||||
# 2237| Type = [Struct] String
|
||||
# 2237| getVariable().getInitializer(): [Initializer] initializer for s4
|
||||
# 2237| getExpr(): [ConstructorCall] call to String
|
||||
# 2237| Type = [VoidType] void
|
||||
# 2237| ValueCategory = prvalue
|
||||
# 2238| getStmt(3): [ReturnStmt] return ...
|
||||
# 2238| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2238| Type = [VoidType] void
|
||||
# 2238| ValueCategory = prvalue
|
||||
# 2238| getQualifier(): [VariableAccess] s4
|
||||
# 2238| Type = [Struct] String
|
||||
# 2238| ValueCategory = lvalue
|
||||
# 2238| getImplicitDestructorCall(1): [DestructorCall] call to ~String
|
||||
# 2238| Type = [VoidType] void
|
||||
# 2238| ValueCategory = prvalue
|
||||
# 2238| getQualifier(): [VariableAccess] s1
|
||||
# 2238| Type = [Struct] String
|
||||
# 2238| ValueCategory = lvalue
|
||||
# 2240| [TopLevelFunction] void ForDestructors()
|
||||
# 2240| <params>:
|
||||
# 2240| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2241| getStmt(0): [DeclStmt] declaration
|
||||
# 2241| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
|
||||
# 2241| Type = [PlainCharType] char
|
||||
# 2241| getVariable().getInitializer(): [Initializer] initializer for c
|
||||
# 2241| getExpr(): [CharLiteral] 97
|
||||
# 2241| Type = [PlainCharType] char
|
||||
# 2241| Value = [CharLiteral] 97
|
||||
# 2241| ValueCategory = prvalue
|
||||
# 2242| getStmt(1): [ForStmt] for(...;...;...) ...
|
||||
# 2242| getInitialization(): [DeclStmt] declaration
|
||||
# 2242| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2242| Type = [Struct] String
|
||||
# 2242| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2242| getExpr(): [ConstructorCall] call to String
|
||||
# 2242| Type = [VoidType] void
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getArgument(0): hello
|
||||
# 2242| Type = [ArrayType] const char[6]
|
||||
# 2242| Value = [StringLiteral] "hello"
|
||||
# 2242| ValueCategory = lvalue
|
||||
# 2242| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2242| Type = [PointerType] const char *
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getCondition(): [NEExpr] ... != ...
|
||||
# 2242| Type = [BoolType] bool
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getLeftOperand(): [VariableAccess] c
|
||||
# 2242| Type = [PlainCharType] char
|
||||
# 2242| ValueCategory = prvalue(load)
|
||||
# 2242| getRightOperand(): [Literal] 0
|
||||
# 2242| Type = [IntType] int
|
||||
# 2242| Value = [Literal] 0
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getLeftOperand().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 2242| Conversion = [IntegralConversion] integral conversion
|
||||
# 2242| Type = [IntType] int
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getUpdate(): [AssignExpr] ... = ...
|
||||
# 2242| Type = [PlainCharType] char
|
||||
# 2242| ValueCategory = lvalue
|
||||
# 2242| getLValue(): [VariableAccess] c
|
||||
# 2242| Type = [PlainCharType] char
|
||||
# 2242| ValueCategory = lvalue
|
||||
# 2242| getRValue(): [FunctionCall] call to pop_back
|
||||
# 2242| Type = [PlainCharType] char
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getQualifier(): [VariableAccess] s
|
||||
# 2242| Type = [Struct] String
|
||||
# 2242| ValueCategory = lvalue
|
||||
# 2242| getStmt(): [BlockStmt] { ... }
|
||||
# 2243| getStmt(0): [DeclStmt] declaration
|
||||
# 2243| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2
|
||||
# 2243| Type = [Struct] String
|
||||
# 2243| getVariable().getInitializer(): [Initializer] initializer for s2
|
||||
# 2243| getExpr(): [ConstructorCall] call to String
|
||||
# 2243| Type = [VoidType] void
|
||||
# 2243| ValueCategory = prvalue
|
||||
# 2244| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2244| Type = [VoidType] void
|
||||
# 2244| ValueCategory = prvalue
|
||||
# 2244| getQualifier(): [VariableAccess] s2
|
||||
# 2244| Type = [Struct] String
|
||||
# 2244| ValueCategory = lvalue
|
||||
# 2242| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2242| Type = [VoidType] void
|
||||
# 2242| ValueCategory = prvalue
|
||||
# 2242| getQualifier(): [VariableAccess] s
|
||||
# 2242| Type = [Struct] String
|
||||
# 2242| ValueCategory = lvalue
|
||||
# 2246| getStmt(2): [RangeBasedForStmt] for(...:...) ...
|
||||
# 2246| getChild(1): [DeclStmt] declaration
|
||||
# 2246| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__range)
|
||||
# 2246| Type = [RValueReferenceType] vector<String> &&
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for (__range)
|
||||
# 2246| getExpr(): [ConstructorCall] call to vector
|
||||
# 2246| Type = [VoidType] void
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getArgument(0): [ConstructorCall] call to String
|
||||
# 2246| Type = [VoidType] void
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getArgument(0): hello
|
||||
# 2246| Type = [ArrayType] const char[6]
|
||||
# 2246| Value = [StringLiteral] "hello"
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2246| Type = [PointerType] const char *
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object
|
||||
# 2246| Type = [Struct] String
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 2246| Type = [LValueReferenceType] vector<String> &
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getExpr(): [TemporaryObjectExpr] temporary object
|
||||
# 2246| Type = [ClassTemplateInstantiation,Struct] vector<String>
|
||||
# 2246| ValueCategory = xvalue
|
||||
# 2246| getBeginEndDeclaration(): [DeclStmt] declaration
|
||||
# 2246| getDeclarationEntry(0): [VariableDeclarationEntry] declaration of (__begin)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for (__begin)
|
||||
# 2246| getExpr(): [FunctionCall] call to begin
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getQualifier(): [VariableAccess] (__range)
|
||||
# 2246| Type = [RValueReferenceType] vector<String> &&
|
||||
# 2246| ValueCategory = prvalue(load)
|
||||
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector<String>)...
|
||||
#-----| Conversion = [GlvalueConversion] glvalue conversion
|
||||
#-----| Type = [SpecifiedType] const vector<String>
|
||||
#-----| ValueCategory = lvalue
|
||||
#-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
#-----| Type = [ClassTemplateInstantiation,Struct] vector<String>
|
||||
#-----| ValueCategory = lvalue
|
||||
# 2246| getDeclarationEntry(1): [VariableDeclarationEntry] declaration of (__end)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
#-----| getVariable().getInitializer(): [Initializer] initializer for (__end)
|
||||
# 2246| getExpr(): [FunctionCall] call to end
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getQualifier(): [VariableAccess] (__range)
|
||||
# 2246| Type = [RValueReferenceType] vector<String> &&
|
||||
# 2246| ValueCategory = prvalue(load)
|
||||
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const vector<String>)...
|
||||
#-----| Conversion = [GlvalueConversion] glvalue conversion
|
||||
#-----| Type = [SpecifiedType] const vector<String>
|
||||
#-----| ValueCategory = lvalue
|
||||
#-----| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
#-----| Type = [ClassTemplateInstantiation,Struct] vector<String>
|
||||
#-----| ValueCategory = lvalue
|
||||
# 2246| getCondition(): [FunctionCall] call to operator!=
|
||||
# 2246| Type = [BoolType] bool
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getQualifier(): [VariableAccess] (__begin)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getArgument(0): [VariableAccess] (__end)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = prvalue(load)
|
||||
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)...
|
||||
#-----| Conversion = [GlvalueConversion] glvalue conversion
|
||||
#-----| Type = [SpecifiedType] const iterator
|
||||
#-----| ValueCategory = lvalue
|
||||
# 2246| getUpdate(): [FunctionCall] call to operator++
|
||||
# 2246| Type = [LValueReferenceType] iterator &
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getQualifier(): [VariableAccess] (__begin)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getChild(5): [DeclStmt] declaration
|
||||
# 2246| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2246| Type = [Struct] String
|
||||
# 2246| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2246| getExpr(): [ConstructorCall] call to String
|
||||
# 2246| Type = [VoidType] void
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getArgument(0): [OverloadedPointerDereferenceExpr] call to operator*
|
||||
# 2246| Type = [LValueReferenceType] String &
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getQualifier(): [VariableAccess] (__begin)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = lvalue
|
||||
#-----| getQualifier().getFullyConverted(): [CStyleCast] (const iterator)...
|
||||
#-----| Conversion = [GlvalueConversion] glvalue conversion
|
||||
#-----| Type = [SpecifiedType] const iterator
|
||||
#-----| ValueCategory = lvalue
|
||||
# 2246| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 2246| Type = [LValueReferenceType] const String &
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getExpr(): [CStyleCast] (const String)...
|
||||
# 2246| Conversion = [GlvalueConversion] glvalue conversion
|
||||
# 2246| Type = [SpecifiedType] const String
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getExpr(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 2246| Type = [Struct] String
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getStmt(): [BlockStmt] { ... }
|
||||
# 2247| getStmt(0): [DeclStmt] declaration
|
||||
# 2247| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2
|
||||
# 2247| Type = [Struct] String
|
||||
# 2247| getVariable().getInitializer(): [Initializer] initializer for s2
|
||||
# 2247| getExpr(): [ConstructorCall] call to String
|
||||
# 2247| Type = [VoidType] void
|
||||
# 2247| ValueCategory = prvalue
|
||||
# 2248| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2248| Type = [VoidType] void
|
||||
# 2248| ValueCategory = prvalue
|
||||
# 2248| getQualifier(): [VariableAccess] s2
|
||||
# 2248| Type = [Struct] String
|
||||
# 2248| ValueCategory = lvalue
|
||||
# 2246| getImplicitDestructorCall(1): [DestructorCall] call to ~String
|
||||
# 2246| Type = [VoidType] void
|
||||
# 2246| ValueCategory = prvalue
|
||||
# 2246| getQualifier(): [VariableAccess] s
|
||||
# 2246| Type = [Struct] String
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2246| getUpdate().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
|
||||
# 2246| Type = [NestedStruct] iterator
|
||||
# 2246| ValueCategory = lvalue
|
||||
# 2250| getStmt(3): [ForStmt] for(...;...;...) ...
|
||||
# 2250| getInitialization(): [DeclStmt] declaration
|
||||
# 2250| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2250| Type = [Struct] String
|
||||
# 2250| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2250| getExpr(): [ConstructorCall] call to String
|
||||
# 2250| Type = [VoidType] void
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getArgument(0): hello
|
||||
# 2250| Type = [ArrayType] const char[6]
|
||||
# 2250| Value = [StringLiteral] "hello"
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2250| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2250| Type = [PointerType] const char *
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getDeclarationEntry(1): [VariableDeclarationEntry] definition of s2
|
||||
# 2250| Type = [Struct] String
|
||||
# 2250| getVariable().getInitializer(): [Initializer] initializer for s2
|
||||
# 2250| getExpr(): [ConstructorCall] call to String
|
||||
# 2250| Type = [VoidType] void
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getArgument(0): world
|
||||
# 2250| Type = [ArrayType] const char[6]
|
||||
# 2250| Value = [StringLiteral] "world"
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2250| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2250| Type = [PointerType] const char *
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getCondition(): [NEExpr] ... != ...
|
||||
# 2250| Type = [BoolType] bool
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getLeftOperand(): [VariableAccess] c
|
||||
# 2250| Type = [PlainCharType] char
|
||||
# 2250| ValueCategory = prvalue(load)
|
||||
# 2250| getRightOperand(): [Literal] 0
|
||||
# 2250| Type = [IntType] int
|
||||
# 2250| Value = [Literal] 0
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getLeftOperand().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 2250| Conversion = [IntegralConversion] integral conversion
|
||||
# 2250| Type = [IntType] int
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getUpdate(): [AssignExpr] ... = ...
|
||||
# 2250| Type = [PlainCharType] char
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2250| getLValue(): [VariableAccess] c
|
||||
# 2250| Type = [PlainCharType] char
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2250| getRValue(): [FunctionCall] call to pop_back
|
||||
# 2250| Type = [PlainCharType] char
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getQualifier(): [VariableAccess] s
|
||||
# 2250| Type = [Struct] String
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2250| getStmt(): [BlockStmt] { ... }
|
||||
# 2251| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2251| getExpr(): [AssignExpr] ... = ...
|
||||
# 2251| Type = [PlainCharType] char
|
||||
# 2251| ValueCategory = lvalue
|
||||
# 2251| getLValue(): [VariableAccess] c
|
||||
# 2251| Type = [PlainCharType] char
|
||||
# 2251| ValueCategory = lvalue
|
||||
# 2251| getRValue(): [Literal] 0
|
||||
# 2251| Type = [IntType] int
|
||||
# 2251| Value = [Literal] 0
|
||||
# 2251| ValueCategory = prvalue
|
||||
# 2251| getRValue().getFullyConverted(): [CStyleCast] (char)...
|
||||
# 2251| Conversion = [IntegralConversion] integral conversion
|
||||
# 2251| Type = [PlainCharType] char
|
||||
# 2251| Value = [CStyleCast] 0
|
||||
# 2251| ValueCategory = prvalue
|
||||
# 2250| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2250| Type = [VoidType] void
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getQualifier(): [VariableAccess] s2
|
||||
# 2250| Type = [Struct] String
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2250| getImplicitDestructorCall(1): [DestructorCall] call to ~String
|
||||
# 2250| Type = [VoidType] void
|
||||
# 2250| ValueCategory = prvalue
|
||||
# 2250| getQualifier(): [VariableAccess] s
|
||||
# 2250| Type = [Struct] String
|
||||
# 2250| ValueCategory = lvalue
|
||||
# 2253| getStmt(4): [ReturnStmt] return ...
|
||||
# 2255| [TopLevelFunction] void IfDestructors2(bool)
|
||||
# 2255| <params>:
|
||||
# 2255| getParameter(0): [Parameter] b
|
||||
# 2255| Type = [BoolType] bool
|
||||
# 2255| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2256| getStmt(0): [IfStmt] if (...) ...
|
||||
# 2256| getInitialization(): [DeclStmt] declaration
|
||||
# 2256| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2256| Type = [Struct] String
|
||||
# 2256| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2256| getExpr(): [ConstructorCall] call to String
|
||||
# 2256| Type = [VoidType] void
|
||||
# 2256| ValueCategory = prvalue
|
||||
# 2256| getArgument(0): hello
|
||||
# 2256| Type = [ArrayType] const char[6]
|
||||
# 2256| Value = [StringLiteral] "hello"
|
||||
# 2256| ValueCategory = lvalue
|
||||
# 2256| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
|
||||
# 2256| Type = [PointerType] const char *
|
||||
# 2256| ValueCategory = prvalue
|
||||
# 2256| getCondition(): [VariableAccess] b
|
||||
# 2256| Type = [BoolType] bool
|
||||
# 2256| ValueCategory = prvalue(load)
|
||||
# 2256| getThen(): [BlockStmt] { ... }
|
||||
# 2257| getStmt(0): [DeclStmt] declaration
|
||||
# 2257| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2257| Type = [IntType] int
|
||||
# 2257| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 2257| getExpr(): [Literal] 0
|
||||
# 2257| Type = [IntType] int
|
||||
# 2257| Value = [Literal] 0
|
||||
# 2257| ValueCategory = prvalue
|
||||
# 2258| getElse(): [BlockStmt] { ... }
|
||||
# 2259| getStmt(0): [DeclStmt] declaration
|
||||
# 2259| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 2259| Type = [IntType] int
|
||||
# 2259| getVariable().getInitializer(): [Initializer] initializer for y
|
||||
# 2259| getExpr(): [Literal] 0
|
||||
# 2259| Type = [IntType] int
|
||||
# 2259| Value = [Literal] 0
|
||||
# 2259| ValueCategory = prvalue
|
||||
# 2260| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2260| Type = [VoidType] void
|
||||
# 2260| ValueCategory = prvalue
|
||||
# 2260| getQualifier(): [VariableAccess] s
|
||||
# 2260| Type = [Struct] String
|
||||
# 2260| ValueCategory = lvalue
|
||||
# 2261| getStmt(1): [ReturnStmt] return ...
|
||||
# 2263| [CopyAssignmentOperator] Bool& Bool::operator=(Bool const&)
|
||||
# 2263| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Bool &
|
||||
# 2263| [CopyConstructor] void Bool::Bool(Bool const&)
|
||||
# 2263| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Bool &
|
||||
# 2265| [Constructor] void Bool::Bool(bool)
|
||||
# 2265| <params>:
|
||||
# 2265| getParameter(0): [Parameter] b_
|
||||
# 2265| Type = [BoolType] bool
|
||||
# 2266| [ConversionOperator] bool Bool::operator bool()
|
||||
# 2266| <params>:
|
||||
# 2267| [Destructor] void Bool::~Bool()
|
||||
# 2267| <params>:
|
||||
# 2270| [TopLevelFunction] void IfDestructors3(bool)
|
||||
# 2270| <params>:
|
||||
# 2270| getParameter(0): [Parameter] b
|
||||
# 2270| Type = [BoolType] bool
|
||||
# 2270| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2271| getStmt(0): [IfStmt] if (...) ...
|
||||
# 2271| getCondition(): [ConditionDeclExpr] (condition decl)
|
||||
# 2271| Type = [BoolType] bool
|
||||
# 2271| ValueCategory = prvalue
|
||||
# 2271| getChild(0): [FunctionCall] call to operator bool
|
||||
# 2271| Type = [BoolType] bool
|
||||
# 2271| ValueCategory = prvalue
|
||||
# 2271| getQualifier(): [VariableAccess] B
|
||||
# 2271| Type = [Class] Bool
|
||||
# 2271| ValueCategory = prvalue(load)
|
||||
# 2271| getThen(): [BlockStmt] { ... }
|
||||
# 2272| getStmt(0): [DeclStmt] declaration
|
||||
# 2272| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s1
|
||||
# 2272| Type = [Struct] String
|
||||
# 2272| getVariable().getInitializer(): [Initializer] initializer for s1
|
||||
# 2272| getExpr(): [ConstructorCall] call to String
|
||||
# 2272| Type = [VoidType] void
|
||||
# 2272| ValueCategory = prvalue
|
||||
# 2273| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2273| Type = [VoidType] void
|
||||
# 2273| ValueCategory = prvalue
|
||||
# 2273| getQualifier(): [VariableAccess] s1
|
||||
# 2273| Type = [Struct] String
|
||||
# 2273| ValueCategory = lvalue
|
||||
# 2273| getElse(): [BlockStmt] { ... }
|
||||
# 2274| getStmt(0): [DeclStmt] declaration
|
||||
# 2274| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s2
|
||||
# 2274| Type = [Struct] String
|
||||
# 2274| getVariable().getInitializer(): [Initializer] initializer for s2
|
||||
# 2274| getExpr(): [ConstructorCall] call to String
|
||||
# 2274| Type = [VoidType] void
|
||||
# 2274| ValueCategory = prvalue
|
||||
# 2275| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2275| Type = [VoidType] void
|
||||
# 2275| ValueCategory = prvalue
|
||||
# 2275| getQualifier(): [VariableAccess] s2
|
||||
# 2275| Type = [Struct] String
|
||||
# 2275| ValueCategory = lvalue
|
||||
# 2275| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool
|
||||
# 2275| Type = [VoidType] void
|
||||
# 2275| ValueCategory = prvalue
|
||||
# 2275| getQualifier(): [VariableAccess] B
|
||||
# 2275| Type = [Class] Bool
|
||||
# 2275| ValueCategory = lvalue
|
||||
# 2276| getStmt(1): [ReturnStmt] return ...
|
||||
# 2278| [TopLevelFunction] void WhileLoopDestructors(bool)
|
||||
# 2278| <params>:
|
||||
# 2278| getParameter(0): [Parameter] b
|
||||
# 2278| Type = [BoolType] bool
|
||||
# 2278| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2279| getStmt(0): [BlockStmt] { ... }
|
||||
# 2280| getStmt(0): [DeclStmt] declaration
|
||||
# 2280| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2280| Type = [Struct] String
|
||||
# 2280| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2280| getExpr(): [ConstructorCall] call to String
|
||||
# 2280| Type = [VoidType] void
|
||||
# 2280| ValueCategory = prvalue
|
||||
# 2281| getStmt(1): [WhileStmt] while (...) ...
|
||||
# 2281| getCondition(): [VariableAccess] b
|
||||
# 2281| Type = [BoolType] bool
|
||||
# 2281| ValueCategory = prvalue(load)
|
||||
# 2281| getStmt(): [BlockStmt] { ... }
|
||||
# 2282| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2282| getExpr(): [AssignExpr] ... = ...
|
||||
# 2282| Type = [BoolType] bool
|
||||
# 2282| ValueCategory = lvalue
|
||||
# 2282| getLValue(): [VariableAccess] b
|
||||
# 2282| Type = [BoolType] bool
|
||||
# 2282| ValueCategory = lvalue
|
||||
# 2282| getRValue(): [Literal] 0
|
||||
# 2282| Type = [BoolType] bool
|
||||
# 2282| Value = [Literal] 0
|
||||
# 2282| ValueCategory = prvalue
|
||||
# 2284| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2284| Type = [VoidType] void
|
||||
# 2284| ValueCategory = prvalue
|
||||
# 2284| getQualifier(): [VariableAccess] s
|
||||
# 2284| Type = [Struct] String
|
||||
# 2284| ValueCategory = lvalue
|
||||
# 2286| getStmt(1): [BlockStmt] { ... }
|
||||
# 2287| getStmt(0): [WhileStmt] while (...) ...
|
||||
# 2287| getCondition(): [ConditionDeclExpr] (condition decl)
|
||||
# 2287| Type = [BoolType] bool
|
||||
# 2287| ValueCategory = prvalue
|
||||
# 2287| getChild(0): [FunctionCall] call to operator bool
|
||||
# 2287| Type = [BoolType] bool
|
||||
# 2287| ValueCategory = prvalue
|
||||
# 2287| getQualifier(): [VariableAccess] B
|
||||
# 2287| Type = [Class] Bool
|
||||
# 2287| ValueCategory = prvalue(load)
|
||||
# 2287| getStmt(): [BlockStmt] { ... }
|
||||
# 2288| getStmt(0): [ExprStmt] ExprStmt
|
||||
# 2288| getExpr(): [AssignExpr] ... = ...
|
||||
# 2288| Type = [BoolType] bool
|
||||
# 2288| ValueCategory = lvalue
|
||||
# 2288| getLValue(): [VariableAccess] b
|
||||
# 2288| Type = [BoolType] bool
|
||||
# 2288| ValueCategory = lvalue
|
||||
# 2288| getRValue(): [Literal] 0
|
||||
# 2288| Type = [BoolType] bool
|
||||
# 2288| Value = [Literal] 0
|
||||
# 2288| ValueCategory = prvalue
|
||||
# 2289| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool
|
||||
# 2289| Type = [VoidType] void
|
||||
# 2289| ValueCategory = prvalue
|
||||
# 2289| getQualifier(): [VariableAccess] B
|
||||
# 2289| Type = [Class] Bool
|
||||
# 2289| ValueCategory = lvalue
|
||||
# 2289| getImplicitDestructorCall(0): [DestructorCall] call to ~Bool
|
||||
# 2289| Type = [VoidType] void
|
||||
# 2289| ValueCategory = prvalue
|
||||
# 2289| getQualifier(): [VariableAccess] B
|
||||
# 2289| Type = [Class] Bool
|
||||
# 2289| ValueCategory = lvalue
|
||||
# 2291| getStmt(2): [ReturnStmt] return ...
|
||||
# 2293| [TopLevelFunction] void VoidFunc()
|
||||
# 2293| <params>:
|
||||
# 2293| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2293| getStmt(0): [ReturnStmt] return ...
|
||||
# 2295| [TopLevelFunction] void IfReturnDestructors(bool)
|
||||
# 2295| <params>:
|
||||
# 2295| getParameter(0): [Parameter] b
|
||||
# 2295| Type = [BoolType] bool
|
||||
# 2295| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2296| getStmt(0): [DeclStmt] declaration
|
||||
# 2296| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2296| Type = [Struct] String
|
||||
# 2296| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2296| getExpr(): [ConstructorCall] call to String
|
||||
# 2296| Type = [VoidType] void
|
||||
# 2296| ValueCategory = prvalue
|
||||
# 2297| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2297| getCondition(): [VariableAccess] b
|
||||
# 2297| Type = [BoolType] bool
|
||||
# 2297| ValueCategory = prvalue(load)
|
||||
# 2297| getThen(): [BlockStmt] { ... }
|
||||
# 2298| getStmt(0): [ReturnStmt] return ...
|
||||
# 2304| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2304| Type = [VoidType] void
|
||||
# 2304| ValueCategory = prvalue
|
||||
# 2304| getQualifier(): [VariableAccess] s
|
||||
# 2304| Type = [Struct] String
|
||||
# 2304| ValueCategory = lvalue
|
||||
# 2300| getStmt(2): [IfStmt] if (...) ...
|
||||
# 2300| getCondition(): [VariableAccess] b
|
||||
# 2300| Type = [BoolType] bool
|
||||
# 2300| ValueCategory = prvalue(load)
|
||||
# 2300| getThen(): [BlockStmt] { ... }
|
||||
# 2301| getStmt(0): [ReturnStmt] return ...
|
||||
# 2301| getExpr(): [FunctionCall] call to VoidFunc
|
||||
# 2301| Type = [VoidType] void
|
||||
# 2301| ValueCategory = prvalue
|
||||
# 2304| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2304| Type = [VoidType] void
|
||||
# 2304| ValueCategory = prvalue
|
||||
# 2304| getQualifier(): [VariableAccess] s
|
||||
# 2304| Type = [Struct] String
|
||||
# 2304| ValueCategory = lvalue
|
||||
# 2303| getStmt(3): [ExprStmt] ExprStmt
|
||||
# 2303| getExpr(): [VariableAccess] s
|
||||
# 2303| Type = [Struct] String
|
||||
# 2303| ValueCategory = lvalue
|
||||
# 2304| getStmt(4): [ReturnStmt] return ...
|
||||
# 2304| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2304| Type = [VoidType] void
|
||||
# 2304| ValueCategory = prvalue
|
||||
# 2304| getQualifier(): [VariableAccess] s
|
||||
# 2304| Type = [Struct] String
|
||||
# 2304| ValueCategory = lvalue
|
||||
# 2306| [TopLevelFunction] int IfReturnDestructors3(bool)
|
||||
# 2306| <params>:
|
||||
# 2306| getParameter(0): [Parameter] b
|
||||
# 2306| Type = [BoolType] bool
|
||||
# 2306| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2307| getStmt(0): [DeclStmt] declaration
|
||||
# 2307| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2307| Type = [Struct] String
|
||||
# 2307| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2307| getExpr(): [ConstructorCall] call to String
|
||||
# 2307| Type = [VoidType] void
|
||||
# 2307| ValueCategory = prvalue
|
||||
# 2308| getStmt(1): [IfStmt] if (...) ...
|
||||
# 2308| getCondition(): [VariableAccess] b
|
||||
# 2308| Type = [BoolType] bool
|
||||
# 2308| ValueCategory = prvalue(load)
|
||||
# 2308| getThen(): [BlockStmt] { ... }
|
||||
# 2309| getStmt(0): [ReturnStmt] return ...
|
||||
# 2309| getExpr(): [Literal] 1
|
||||
# 2309| Type = [IntType] int
|
||||
# 2309| Value = [Literal] 1
|
||||
# 2309| ValueCategory = prvalue
|
||||
# 2312| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2312| Type = [VoidType] void
|
||||
# 2312| ValueCategory = prvalue
|
||||
# 2312| getQualifier(): [VariableAccess] s
|
||||
# 2312| Type = [Struct] String
|
||||
# 2312| ValueCategory = lvalue
|
||||
# 2311| getStmt(2): [ReturnStmt] return ...
|
||||
# 2311| getExpr(): [Literal] 0
|
||||
# 2311| Type = [IntType] int
|
||||
# 2311| Value = [Literal] 0
|
||||
# 2311| ValueCategory = prvalue
|
||||
# 2312| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2312| Type = [VoidType] void
|
||||
# 2312| ValueCategory = prvalue
|
||||
# 2312| getQualifier(): [VariableAccess] s
|
||||
# 2312| Type = [Struct] String
|
||||
# 2312| ValueCategory = lvalue
|
||||
# 2314| [TopLevelFunction] void VoidReturnDestructors()
|
||||
# 2314| <params>:
|
||||
# 2314| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2315| getStmt(0): [DeclStmt] declaration
|
||||
# 2315| getDeclarationEntry(0): [VariableDeclarationEntry] definition of s
|
||||
# 2315| Type = [Struct] String
|
||||
# 2315| getVariable().getInitializer(): [Initializer] initializer for s
|
||||
# 2315| getExpr(): [ConstructorCall] call to String
|
||||
# 2315| Type = [VoidType] void
|
||||
# 2315| ValueCategory = prvalue
|
||||
# 2316| getStmt(1): [ReturnStmt] return ...
|
||||
# 2316| getExpr(): [FunctionCall] call to VoidFunc
|
||||
# 2316| Type = [VoidType] void
|
||||
# 2316| ValueCategory = prvalue
|
||||
# 2317| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 2317| Type = [VoidType] void
|
||||
# 2317| ValueCategory = prvalue
|
||||
# 2317| getQualifier(): [VariableAccess] s
|
||||
# 2317| Type = [Struct] String
|
||||
# 2317| ValueCategory = lvalue
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -605,7 +605,7 @@ struct String {
|
||||
String& operator=(String&&);
|
||||
|
||||
const char* c_str() const;
|
||||
|
||||
char pop_back();
|
||||
private:
|
||||
const char* p;
|
||||
};
|
||||
@@ -2209,4 +2209,111 @@ namespace vacuous_destructor_call {
|
||||
}
|
||||
}
|
||||
|
||||
void TryCatchDestructors(bool b) {
|
||||
try {
|
||||
String s;
|
||||
if (b) {
|
||||
throw "string literal";
|
||||
}
|
||||
String s2;
|
||||
}
|
||||
catch (const char* s) {
|
||||
throw String(s);
|
||||
}
|
||||
catch (const String& e) {
|
||||
}
|
||||
catch (...) {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void IfDestructors(bool b) {
|
||||
String s1;
|
||||
if(b) {
|
||||
String s2;
|
||||
} else {
|
||||
String s3;
|
||||
}
|
||||
String s4;
|
||||
}
|
||||
|
||||
void ForDestructors() {
|
||||
char c = 'a';
|
||||
for(String s("hello"); c != 0; c = s.pop_back()) {
|
||||
String s2;
|
||||
}
|
||||
|
||||
for(String s : vector<String>(String("hello"))) {
|
||||
String s2;
|
||||
}
|
||||
|
||||
for(String s("hello"), s2("world"); c != 0; c = s.pop_back()) {
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void IfDestructors2(bool b) {
|
||||
if(String s = String("hello"); b) {
|
||||
int x = 0;
|
||||
} else {
|
||||
int y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Bool {
|
||||
public:
|
||||
Bool(bool b_);
|
||||
operator bool();
|
||||
~Bool();
|
||||
};
|
||||
|
||||
void IfDestructors3(bool b) {
|
||||
if(Bool B = Bool(b)) {
|
||||
String s1;
|
||||
} else {
|
||||
String s2;
|
||||
}
|
||||
}
|
||||
|
||||
void WhileLoopDestructors(bool b) {
|
||||
{
|
||||
String s;
|
||||
while(b) {
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
while (Bool B = Bool(b)) {
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoidFunc() {}
|
||||
|
||||
void IfReturnDestructors(bool b) {
|
||||
String s;
|
||||
if(b) {
|
||||
return;
|
||||
}
|
||||
if(b) {
|
||||
return VoidFunc();
|
||||
}
|
||||
s;
|
||||
}
|
||||
|
||||
int IfReturnDestructors3(bool b) {
|
||||
String s;
|
||||
if(b) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VoidReturnDestructors() {
|
||||
String s;
|
||||
return VoidFunc();
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++20 --clang
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -9,6 +9,7 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
|
||||
@@ -10,6 +10,9 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| statements.cpp:26:3:26:3 | IndirectMayWriteSideEffect: inner | Instruction 'IndirectMayWriteSideEffect: inner' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| statements.cpp:28:1:28:1 | IndirectMayWriteSideEffect: before | Instruction 'IndirectMayWriteSideEffect: before' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
| stmt_expr.cpp:29:11:32:11 | CopyValue: (statement expression) | Instruction 'CopyValue: (statement expression)' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
| stmt_in_type.cpp:5:53:5:53 | Constant: 1 | Instruction 'Constant: 1' has no successors in function '$@'. | stmt_in_type.cpp:2:6:2:12 | void cpp_fun() | void cpp_fun() |
|
||||
|
||||
@@ -9,6 +9,7 @@ sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
|
||||
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
|
||||
| statements.cpp:25:5:25:9 | ReThrow: re-throw exception | Instruction 'ReThrow: re-throw exception ' has no successors in function '$@'. | statements.cpp:21:6:21:16 | void early_throw(int) | void early_throw(int) |
|
||||
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
|
||||
Reference in New Issue
Block a user