Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion cpp/ql/lib/semmle/code/cpp/PrintAST.qll
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,14 @@ class ExprNode extends AstNode {

ExprNode() { expr = ast }

override AstNode getChildInternal(int childIndex) { result.getAst() = expr.getChild(childIndex) }
override AstNode getChildInternal(int childIndex) {
result.getAst() = expr.getChild(childIndex)
or
exists(int destructorIndex |
result.getAst() = expr.getImplicitDestructorCall(destructorIndex) and
childIndex = destructorIndex + max(int index | exists(expr.getChild(index)) or index = 0) + 1
)
}

override string getProperty(string key) {
result = super.getProperty(key)
Expand Down Expand Up @@ -439,6 +446,11 @@ class StmtNode extends AstNode {
result.getAst() = child.(Stmt)
)
)
or
exists(int destructorIndex |
result.getAst() = stmt.getImplicitDestructorCall(destructorIndex) and
childIndex = destructorIndex + max(int index | exists(stmt.getChild(index)) or index = 0) + 1
)
}

override string getChildAccessorPredicateInternal(int childIndex) {
Expand Down Expand Up @@ -662,13 +674,22 @@ private string getChildAccessorWithoutConversions(Locatable parent, Element chil
or
not namedStmtChildPredicates(s, child, _) and
exists(int n | s.getChild(n) = child and result = "getChild(" + n + ")")
or
exists(int n |
s.getImplicitDestructorCall(n) = child and result = "getImplicitDestructorCall(" + n + ")"
)
)
or
exists(Expr expr | expr = parent |
namedExprChildPredicates(expr, child, result)
or
not namedExprChildPredicates(expr, child, _) and
exists(int n | expr.getChild(n) = child and result = "getChild(" + n + ")")
or
exists(int n |
expr.getImplicitDestructorCall(n) = child and
result = "getImplicitDestructorCall(" + n + ")"
)
)
)
}
Expand Down
13 changes: 13 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ class Expr extends StmtParent, @expr {
/** Gets the parent of this expression, if any. */
Element getParent() { exprparents(underlyingElement(this), _, unresolveElement(result)) }

/**
* Gets the `n`th compiler-generated destructor call that is performed after this expression, in
* order of destruction.
*/
Comment on lines +61 to +64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to have an example here (specifically, for when there are multiple destructors attached to an element).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would still be good, but given that we don't actually generate any such destructor calls yet this can wait 🙈

DestructorCall getImplicitDestructorCall(int n) {
synthetic_destructor_call(this, max(int i | synthetic_destructor_call(this, i, _)) - n, result)
}

/**
* Gets a compiler-generated destructor call that is performed after this expression.
*/
DestructorCall getAnImplicitDestructorCall() { synthetic_destructor_call(this, _, result) }

/** Gets the location of this expression. */
override Location getLocation() {
result = this.getExprLocationOverride()
Expand Down
22 changes: 22 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/stmts/Stmt.qll
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,28 @@ class Stmt extends StmtParent, @stmt {
)
}

/**
* Gets the `n`th compiler-generated destructor call that is performed after this statement, in
* order of destruction.
*
* For instance, in the following code, `getImplicitDestructorCall(0)` for the block will be the
* destructor call for `c2`:
* ```cpp
* {
* MyClass c1;
* MyClass c2;
* }
* ```
*/
DestructorCall getImplicitDestructorCall(int n) {
synthetic_destructor_call(this, max(int i | synthetic_destructor_call(this, i, _)) - n, result)
}

/**
* Gets a compiler-generated destructor call that is performed after this statement.
*/
DestructorCall getAnImplicitDestructorCall() { synthetic_destructor_call(this, _, result) }

override Location getLocation() { stmts(underlyingElement(this), _, result) }

override string toString() { none() }
Expand Down
Loading