Merge pull request #15506 from rdmarsh2/rdmarsh2/cpp/ir-synthetic-destructors

C++: Add implicit destructors for named variables to the IR
This commit is contained in:
Mathias Vorreiter Pedersen
2024-02-27 15:12:46 +00:00
committed by GitHub
23 changed files with 6015 additions and 987 deletions

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added destructors for named objects to the intermediate representation.

View File

@@ -60,4 +60,6 @@ Element exprEnclosingElement(Expr e) {
)
else result = de.getDeclaration()
)
or
result.(Stmt).getAnImplicitDestructorCall() = e
}

View File

@@ -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

View File

@@ -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 + ")"
)
}

View File

@@ -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()
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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() }
}

View File

@@ -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()
}
}