mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #15318 from rdmarsh2/rdmarsh2/cpp/first-class-destructors
C++: First-class destructors in AST
This commit is contained in:
@@ -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)
|
||||
@@ -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) {
|
||||
@@ -662,6 +674,10 @@ 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 |
|
||||
@@ -669,6 +685,11 @@ private string getChildAccessorWithoutConversions(Locatable parent, Element chil
|
||||
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 + ")"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
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()
|
||||
|
||||
@@ -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() }
|
||||
|
||||
383
cpp/ql/test/library-tests/destructors/PrintAST.expected
Normal file
383
cpp/ql/test/library-tests/destructors/PrintAST.expected
Normal file
@@ -0,0 +1,383 @@
|
||||
#-----| [CopyAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag const&)
|
||||
#-----| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const __va_list_tag &
|
||||
#-----| [MoveAssignmentOperator] __va_list_tag& __va_list_tag::operator=(__va_list_tag&&)
|
||||
#-----| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] __va_list_tag &&
|
||||
destructors.cpp:
|
||||
# 2| [CopyAssignmentOperator] C& C::operator=(C const&)
|
||||
# 2| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const C &
|
||||
# 2| [CopyConstructor] void C::C(C const&)
|
||||
# 2| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const C &
|
||||
# 4| [Constructor] void C::C(int)
|
||||
# 4| <params>:
|
||||
# 4| getParameter(0): [Parameter] x
|
||||
# 4| Type = [IntType] int
|
||||
# 5| [Destructor] void C::~C()
|
||||
# 5| <params>:
|
||||
# 8| [TopLevelFunction] void f(int, int)
|
||||
# 8| <params>:
|
||||
# 8| getParameter(0): [Parameter] b1
|
||||
# 8| Type = [IntType] int
|
||||
# 8| getParameter(1): [Parameter] b2
|
||||
# 8| Type = [IntType] int
|
||||
# 8| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 9| getStmt(0): [DeclStmt] declaration
|
||||
# 9| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c10
|
||||
# 9| Type = [Class] C
|
||||
# 9| getVariable().getInitializer(): [Initializer] initializer for c10
|
||||
# 9| getExpr(): [ConstructorCall] call to C
|
||||
# 9| Type = [VoidType] void
|
||||
# 9| ValueCategory = prvalue
|
||||
# 9| getArgument(0): [Literal] 110
|
||||
# 9| Type = [IntType] int
|
||||
# 9| Value = [Literal] 110
|
||||
# 9| ValueCategory = prvalue
|
||||
# 10| getStmt(1): [BlockStmt] { ... }
|
||||
# 11| getStmt(0): [DeclStmt] declaration
|
||||
# 11| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c20
|
||||
# 11| Type = [Class] C
|
||||
# 11| getVariable().getInitializer(): [Initializer] initializer for c20
|
||||
# 11| getExpr(): [ConstructorCall] call to C
|
||||
# 11| Type = [VoidType] void
|
||||
# 11| ValueCategory = prvalue
|
||||
# 11| getArgument(0): [Literal] 120
|
||||
# 11| Type = [IntType] int
|
||||
# 11| Value = [Literal] 120
|
||||
# 11| ValueCategory = prvalue
|
||||
# 12| getStmt(1): [BlockStmt] { ... }
|
||||
# 13| getStmt(0): [DeclStmt] declaration
|
||||
# 13| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c30
|
||||
# 13| Type = [Class] C
|
||||
# 13| getVariable().getInitializer(): [Initializer] initializer for c30
|
||||
# 13| getExpr(): [ConstructorCall] call to C
|
||||
# 13| Type = [VoidType] void
|
||||
# 13| ValueCategory = prvalue
|
||||
# 13| getArgument(0): [Literal] 130
|
||||
# 13| Type = [IntType] int
|
||||
# 13| Value = [Literal] 130
|
||||
# 13| ValueCategory = prvalue
|
||||
# 14| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 14| Type = [VoidType] void
|
||||
# 14| ValueCategory = prvalue
|
||||
# 14| getQualifier(): [VariableAccess] c30
|
||||
# 14| Type = [Class] C
|
||||
# 14| ValueCategory = lvalue
|
||||
# 15| getStmt(2): [BlockStmt] { ... }
|
||||
# 16| getStmt(0): [DeclStmt] declaration
|
||||
# 16| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c31
|
||||
# 16| Type = [Class] C
|
||||
# 16| getVariable().getInitializer(): [Initializer] initializer for c31
|
||||
# 16| getExpr(): [ConstructorCall] call to C
|
||||
# 16| Type = [VoidType] void
|
||||
# 16| ValueCategory = prvalue
|
||||
# 16| getArgument(0): [Literal] 131
|
||||
# 16| Type = [IntType] int
|
||||
# 16| Value = [Literal] 131
|
||||
# 16| ValueCategory = prvalue
|
||||
# 17| getStmt(1): [IfStmt] if (...) ...
|
||||
# 17| getCondition(): [VariableAccess] b1
|
||||
# 17| Type = [IntType] int
|
||||
# 17| ValueCategory = prvalue(load)
|
||||
# 17| getThen(): [GotoStmt] goto ...
|
||||
# 21| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getQualifier(): [VariableAccess] c31
|
||||
# 21| Type = [Class] C
|
||||
# 21| ValueCategory = lvalue
|
||||
# 26| getImplicitDestructorCall(1): [DestructorCall] call to ~C
|
||||
# 26| Type = [VoidType] void
|
||||
# 26| ValueCategory = prvalue
|
||||
# 26| getQualifier(): [VariableAccess] c20
|
||||
# 26| Type = [Class] C
|
||||
# 26| ValueCategory = lvalue
|
||||
# 17| getCondition().getFullyConverted(): [CStyleCast] (bool)...
|
||||
# 17| Conversion = [BoolConversion] conversion to bool
|
||||
# 17| Type = [BoolType] bool
|
||||
# 17| ValueCategory = prvalue
|
||||
# 18| getStmt(2): [DeclStmt] declaration
|
||||
# 18| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c32
|
||||
# 18| Type = [Class] C
|
||||
# 18| getVariable().getInitializer(): [Initializer] initializer for c32
|
||||
# 18| getExpr(): [ConstructorCall] call to C
|
||||
# 18| Type = [VoidType] void
|
||||
# 18| ValueCategory = prvalue
|
||||
# 18| getArgument(0): [Literal] 132
|
||||
# 18| Type = [IntType] int
|
||||
# 18| Value = [Literal] 132
|
||||
# 18| ValueCategory = prvalue
|
||||
# 19| getStmt(3): [IfStmt] if (...) ...
|
||||
# 19| getCondition(): [VariableAccess] b2
|
||||
# 19| Type = [IntType] int
|
||||
# 19| ValueCategory = prvalue(load)
|
||||
# 19| getThen(): [ReturnStmt] return ...
|
||||
# 21| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getQualifier(): [VariableAccess] c32
|
||||
# 21| Type = [Class] C
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getImplicitDestructorCall(1): [DestructorCall] call to ~C
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getQualifier(): [VariableAccess] c31
|
||||
# 21| Type = [Class] C
|
||||
# 21| ValueCategory = lvalue
|
||||
# 26| getImplicitDestructorCall(2): [DestructorCall] call to ~C
|
||||
# 26| Type = [VoidType] void
|
||||
# 26| ValueCategory = prvalue
|
||||
# 26| getQualifier(): [VariableAccess] c20
|
||||
# 26| Type = [Class] C
|
||||
# 26| ValueCategory = lvalue
|
||||
# 35| getImplicitDestructorCall(3): [DestructorCall] call to ~C
|
||||
# 35| Type = [VoidType] void
|
||||
# 35| ValueCategory = prvalue
|
||||
# 35| getQualifier(): [VariableAccess] c10
|
||||
# 35| Type = [Class] C
|
||||
# 35| ValueCategory = lvalue
|
||||
# 19| getCondition().getFullyConverted(): [CStyleCast] (bool)...
|
||||
# 19| Conversion = [BoolConversion] conversion to bool
|
||||
# 19| Type = [BoolType] bool
|
||||
# 19| ValueCategory = prvalue
|
||||
# 20| getStmt(4): [DeclStmt] declaration
|
||||
# 20| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c33
|
||||
# 20| Type = [Class] C
|
||||
# 20| getVariable().getInitializer(): [Initializer] initializer for c33
|
||||
# 20| getExpr(): [ConstructorCall] call to C
|
||||
# 20| Type = [VoidType] void
|
||||
# 20| ValueCategory = prvalue
|
||||
# 20| getArgument(0): [Literal] 133
|
||||
# 20| Type = [IntType] int
|
||||
# 20| Value = [Literal] 133
|
||||
# 20| ValueCategory = prvalue
|
||||
# 21| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getQualifier(): [VariableAccess] c33
|
||||
# 21| Type = [Class] C
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getImplicitDestructorCall(1): [DestructorCall] call to ~C
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getQualifier(): [VariableAccess] c32
|
||||
# 21| Type = [Class] C
|
||||
# 21| ValueCategory = lvalue
|
||||
# 21| getImplicitDestructorCall(2): [DestructorCall] call to ~C
|
||||
# 21| Type = [VoidType] void
|
||||
# 21| ValueCategory = prvalue
|
||||
# 21| getQualifier(): [VariableAccess] c31
|
||||
# 21| Type = [Class] C
|
||||
# 21| ValueCategory = lvalue
|
||||
# 22| getStmt(3): [BlockStmt] { ... }
|
||||
# 23| getStmt(0): [DeclStmt] declaration
|
||||
# 23| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c34
|
||||
# 23| Type = [Class] C
|
||||
# 23| getVariable().getInitializer(): [Initializer] initializer for c34
|
||||
# 23| getExpr(): [ConstructorCall] call to C
|
||||
# 23| Type = [VoidType] void
|
||||
# 23| ValueCategory = prvalue
|
||||
# 23| getArgument(0): [Literal] 134
|
||||
# 23| Type = [IntType] int
|
||||
# 23| Value = [Literal] 134
|
||||
# 23| ValueCategory = prvalue
|
||||
# 24| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 24| Type = [VoidType] void
|
||||
# 24| ValueCategory = prvalue
|
||||
# 24| getQualifier(): [VariableAccess] c34
|
||||
# 24| Type = [Class] C
|
||||
# 24| ValueCategory = lvalue
|
||||
# 25| getStmt(4): [DeclStmt] declaration
|
||||
# 25| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c21
|
||||
# 25| Type = [Class] C
|
||||
# 25| getVariable().getInitializer(): [Initializer] initializer for c21
|
||||
# 25| getExpr(): [ConstructorCall] call to C
|
||||
# 25| Type = [VoidType] void
|
||||
# 25| ValueCategory = prvalue
|
||||
# 25| getArgument(0): [Literal] 121
|
||||
# 25| Type = [IntType] int
|
||||
# 25| Value = [Literal] 121
|
||||
# 25| ValueCategory = prvalue
|
||||
# 26| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 26| Type = [VoidType] void
|
||||
# 26| ValueCategory = prvalue
|
||||
# 26| getQualifier(): [VariableAccess] c21
|
||||
# 26| Type = [Class] C
|
||||
# 26| ValueCategory = lvalue
|
||||
# 26| getImplicitDestructorCall(1): [DestructorCall] call to ~C
|
||||
# 26| Type = [VoidType] void
|
||||
# 26| ValueCategory = prvalue
|
||||
# 26| getQualifier(): [VariableAccess] c20
|
||||
# 26| Type = [Class] C
|
||||
# 26| ValueCategory = lvalue
|
||||
# 27| getStmt(2): [BlockStmt] { ... }
|
||||
# 28| getStmt(0): [DeclStmt] declaration
|
||||
# 28| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c22
|
||||
# 28| Type = [Class] C
|
||||
# 28| getVariable().getInitializer(): [Initializer] initializer for c22
|
||||
# 28| getExpr(): [ConstructorCall] call to C
|
||||
# 28| Type = [VoidType] void
|
||||
# 28| ValueCategory = prvalue
|
||||
# 28| getArgument(0): [Literal] 122
|
||||
# 28| Type = [IntType] int
|
||||
# 28| Value = [Literal] 122
|
||||
# 28| ValueCategory = prvalue
|
||||
# 29| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 29| Type = [VoidType] void
|
||||
# 29| ValueCategory = prvalue
|
||||
# 29| getQualifier(): [VariableAccess] c22
|
||||
# 29| Type = [Class] C
|
||||
# 29| ValueCategory = lvalue
|
||||
# 30| getStmt(3): [BlockStmt] { ... }
|
||||
# 31| getStmt(0): [LabelStmt] label ...:
|
||||
# 32| getStmt(1): [DeclStmt] declaration
|
||||
# 32| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c23
|
||||
# 32| Type = [Class] C
|
||||
# 32| getVariable().getInitializer(): [Initializer] initializer for c23
|
||||
# 32| getExpr(): [ConstructorCall] call to C
|
||||
# 32| Type = [VoidType] void
|
||||
# 32| ValueCategory = prvalue
|
||||
# 32| getArgument(0): [Literal] 123
|
||||
# 32| Type = [IntType] int
|
||||
# 32| Value = [Literal] 123
|
||||
# 32| ValueCategory = prvalue
|
||||
# 33| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 33| Type = [VoidType] void
|
||||
# 33| ValueCategory = prvalue
|
||||
# 33| getQualifier(): [VariableAccess] c23
|
||||
# 33| Type = [Class] C
|
||||
# 33| ValueCategory = lvalue
|
||||
# 34| getStmt(4): [DeclStmt] declaration
|
||||
# 34| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c11
|
||||
# 34| Type = [Class] C
|
||||
# 34| getVariable().getInitializer(): [Initializer] initializer for c11
|
||||
# 34| getExpr(): [ConstructorCall] call to C
|
||||
# 34| Type = [VoidType] void
|
||||
# 34| ValueCategory = prvalue
|
||||
# 34| getArgument(0): [Literal] 111
|
||||
# 34| Type = [IntType] int
|
||||
# 34| Value = [Literal] 111
|
||||
# 34| ValueCategory = prvalue
|
||||
# 35| getStmt(5): [ReturnStmt] return ...
|
||||
# 35| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 35| Type = [VoidType] void
|
||||
# 35| ValueCategory = prvalue
|
||||
# 35| getQualifier(): [VariableAccess] c11
|
||||
# 35| Type = [Class] C
|
||||
# 35| ValueCategory = lvalue
|
||||
# 35| getImplicitDestructorCall(1): [DestructorCall] call to ~C
|
||||
# 35| Type = [VoidType] void
|
||||
# 35| ValueCategory = prvalue
|
||||
# 35| getQualifier(): [VariableAccess] c10
|
||||
# 35| Type = [Class] C
|
||||
# 35| ValueCategory = lvalue
|
||||
destructors2.cpp:
|
||||
# 5| [CopyAssignmentOperator] Class2& Class2::operator=(Class2 const&)
|
||||
# 5| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Class2 &
|
||||
# 5| [CopyConstructor] void Class2::Class2(Class2 const&)
|
||||
# 5| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Class2 &
|
||||
# 5| <initializations>:
|
||||
# 5| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 5| getStmt(0): [ReturnStmt] return ...
|
||||
# 7| [Constructor] void Class2::Class2()
|
||||
# 7| <params>:
|
||||
# 8| [Destructor] void Class2::~Class2()
|
||||
# 8| <params>:
|
||||
# 11| [TopLevelFunction] Class2 getClass2()
|
||||
# 11| <params>:
|
||||
# 13| [CopyAssignmentOperator] Outer& Outer::operator=(Outer const&)
|
||||
# 13| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Outer &
|
||||
# 13| [MoveAssignmentOperator] Outer& Outer::operator=(Outer&&)
|
||||
# 13| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] Outer &&
|
||||
# 15| [CopyAssignmentOperator] Outer::Inner& Outer::Inner::operator=(Outer::Inner const public&)
|
||||
# 15| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Inner &
|
||||
# 15| [CopyConstructor] void Outer::Inner::Inner(Outer::Inner const public&)
|
||||
# 15| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [LValueReferenceType] const Inner &
|
||||
# 17| [Constructor] void Outer::Inner::Inner(Class2 const&)
|
||||
# 17| <params>:
|
||||
# 17| getParameter(0): [Parameter] c
|
||||
# 17| Type = [LValueReferenceType] const Class2 &
|
||||
# 17| <initializations>:
|
||||
# 17| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 17| getStmt(0): [ReturnStmt] return ...
|
||||
# 18| [Destructor] void Outer::Inner::~Inner()
|
||||
# 18| <params>:
|
||||
# 18| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 18| getStmt(0): [ReturnStmt] return ...
|
||||
# 18| <destructions>:
|
||||
# 21| [MemberFunction] void Outer::f2(int)
|
||||
# 21| <params>:
|
||||
# 21| getParameter(0): [Parameter] i
|
||||
# 21| Type = [IntType] int
|
||||
# 21| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 22| getStmt(0): [DeclStmt] declaration
|
||||
# 22| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
|
||||
# 22| Type = [Class] Class2
|
||||
# 22| getVariable().getInitializer(): [Initializer] initializer for c
|
||||
# 22| getExpr(): [FunctionCall] call to getClass2
|
||||
# 22| Type = [Class] Class2
|
||||
# 22| ValueCategory = prvalue
|
||||
# 23| getStmt(1): [IfStmt] if (...) ...
|
||||
# 23| getCondition(): [VariableAccess] i
|
||||
# 23| Type = [IntType] int
|
||||
# 23| ValueCategory = prvalue(load)
|
||||
# 23| getThen(): [BlockStmt] { ... }
|
||||
# 24| getStmt(0): [ReturnStmt] return ...
|
||||
# 27| getImplicitDestructorCall(0): [DestructorCall] call to ~Class2
|
||||
# 27| Type = [VoidType] void
|
||||
# 27| ValueCategory = prvalue
|
||||
# 27| getQualifier(): [VariableAccess] c
|
||||
# 27| Type = [Class] Class2
|
||||
# 27| ValueCategory = lvalue
|
||||
# 23| getCondition().getFullyConverted(): [CStyleCast] (bool)...
|
||||
# 23| Conversion = [BoolConversion] conversion to bool
|
||||
# 23| Type = [BoolType] bool
|
||||
# 23| ValueCategory = prvalue
|
||||
# 26| getStmt(2): [DeclStmt] declaration
|
||||
# 26| getDeclarationEntry(0): [VariableDeclarationEntry] definition of inner
|
||||
# 26| Type = [NestedClass] Inner
|
||||
# 26| getVariable().getInitializer(): [Initializer] initializer for inner
|
||||
# 26| getExpr(): [ConstructorCall] call to Inner
|
||||
# 26| Type = [VoidType] void
|
||||
# 26| ValueCategory = prvalue
|
||||
# 26| getArgument(0): [VariableAccess] c
|
||||
# 26| Type = [Class] Class2
|
||||
# 26| ValueCategory = lvalue
|
||||
# 26| getArgument(0).getFullyConverted(): [ReferenceToExpr] (reference to)
|
||||
# 26| Type = [LValueReferenceType] const Class2 &
|
||||
# 26| ValueCategory = prvalue
|
||||
# 26| getExpr(): [CStyleCast] (const Class2)...
|
||||
# 26| Conversion = [GlvalueConversion] glvalue conversion
|
||||
# 26| Type = [SpecifiedType] const Class2
|
||||
# 26| ValueCategory = lvalue
|
||||
# 27| getStmt(3): [ReturnStmt] return ...
|
||||
# 27| getImplicitDestructorCall(0): [DestructorCall] call to ~Inner
|
||||
# 27| Type = [VoidType] void
|
||||
# 27| ValueCategory = prvalue
|
||||
# 27| getQualifier(): [VariableAccess] inner
|
||||
# 27| Type = [NestedClass] Inner
|
||||
# 27| ValueCategory = lvalue
|
||||
# 27| getImplicitDestructorCall(1): [DestructorCall] call to ~Class2
|
||||
# 27| Type = [VoidType] void
|
||||
# 27| ValueCategory = prvalue
|
||||
# 27| getQualifier(): [VariableAccess] c
|
||||
# 27| Type = [Class] Class2
|
||||
# 27| ValueCategory = lvalue
|
||||
10
cpp/ql/test/library-tests/destructors/PrintAST.ql
Normal file
10
cpp/ql/test/library-tests/destructors/PrintAST.ql
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
private import cpp
|
||||
private import semmle.code.cpp.PrintAST
|
||||
|
||||
private class PrintConfig extends PrintAstConfiguration {
|
||||
override predicate shouldPrintDeclaration(Declaration decl) { any() }
|
||||
}
|
||||
22
cpp/ql/test/library-tests/destructors/destructors.expected
Normal file
22
cpp/ql/test/library-tests/destructors/destructors.expected
Normal file
@@ -0,0 +1,22 @@
|
||||
exprDestructors
|
||||
stmtDestructors
|
||||
| destructors2.cpp:24:13:24:19 | return ... | 0 | destructors2.cpp:27:5:27:5 | call to ~Class2 | destructors2.cpp:27:5:27:5 | c |
|
||||
| destructors2.cpp:27:5:27:5 | return ... | 0 | destructors2.cpp:27:5:27:5 | call to ~Inner | destructors2.cpp:27:5:27:5 | inner |
|
||||
| destructors2.cpp:27:5:27:5 | return ... | 1 | destructors2.cpp:27:5:27:5 | call to ~Class2 | destructors2.cpp:27:5:27:5 | c |
|
||||
| destructors.cpp:10:5:26:5 | { ... } | 0 | destructors.cpp:26:5:26:5 | call to ~C | destructors.cpp:26:5:26:5 | c21 |
|
||||
| destructors.cpp:10:5:26:5 | { ... } | 1 | destructors.cpp:26:5:26:5 | call to ~C | destructors.cpp:26:5:26:5 | c20 |
|
||||
| destructors.cpp:12:9:14:9 | { ... } | 0 | destructors.cpp:14:9:14:9 | call to ~C | destructors.cpp:14:9:14:9 | c30 |
|
||||
| destructors.cpp:15:9:21:9 | { ... } | 0 | destructors.cpp:21:9:21:9 | call to ~C | destructors.cpp:21:9:21:9 | c33 |
|
||||
| destructors.cpp:15:9:21:9 | { ... } | 1 | destructors.cpp:21:9:21:9 | call to ~C | destructors.cpp:21:9:21:9 | c32 |
|
||||
| destructors.cpp:15:9:21:9 | { ... } | 2 | destructors.cpp:21:9:21:9 | call to ~C | destructors.cpp:21:9:21:9 | c31 |
|
||||
| destructors.cpp:17:21:17:29 | goto ... | 0 | destructors.cpp:21:9:21:9 | call to ~C | destructors.cpp:21:9:21:9 | c31 |
|
||||
| destructors.cpp:17:21:17:29 | goto ... | 1 | destructors.cpp:26:5:26:5 | call to ~C | destructors.cpp:26:5:26:5 | c20 |
|
||||
| destructors.cpp:19:21:19:27 | return ... | 0 | destructors.cpp:21:9:21:9 | call to ~C | destructors.cpp:21:9:21:9 | c32 |
|
||||
| destructors.cpp:19:21:19:27 | return ... | 1 | destructors.cpp:21:9:21:9 | call to ~C | destructors.cpp:21:9:21:9 | c31 |
|
||||
| destructors.cpp:19:21:19:27 | return ... | 2 | destructors.cpp:26:5:26:5 | call to ~C | destructors.cpp:26:5:26:5 | c20 |
|
||||
| destructors.cpp:19:21:19:27 | return ... | 3 | destructors.cpp:35:1:35:1 | call to ~C | destructors.cpp:35:1:35:1 | c10 |
|
||||
| destructors.cpp:22:9:24:9 | { ... } | 0 | destructors.cpp:24:9:24:9 | call to ~C | destructors.cpp:24:9:24:9 | c34 |
|
||||
| destructors.cpp:27:5:29:5 | { ... } | 0 | destructors.cpp:29:5:29:5 | call to ~C | destructors.cpp:29:5:29:5 | c22 |
|
||||
| destructors.cpp:30:5:33:5 | { ... } | 0 | destructors.cpp:33:5:33:5 | call to ~C | destructors.cpp:33:5:33:5 | c23 |
|
||||
| destructors.cpp:35:1:35:1 | return ... | 0 | destructors.cpp:35:1:35:1 | call to ~C | destructors.cpp:35:1:35:1 | c11 |
|
||||
| destructors.cpp:35:1:35:1 | return ... | 1 | destructors.cpp:35:1:35:1 | call to ~C | destructors.cpp:35:1:35:1 | c10 |
|
||||
11
cpp/ql/test/library-tests/destructors/destructors.ql
Normal file
11
cpp/ql/test/library-tests/destructors/destructors.ql
Normal file
@@ -0,0 +1,11 @@
|
||||
import cpp
|
||||
|
||||
query predicate exprDestructors(Expr e, int i, DestructorCall d, Expr destructed) {
|
||||
d = e.getImplicitDestructorCall(i) and
|
||||
d.getQualifier() = destructed
|
||||
}
|
||||
|
||||
query predicate stmtDestructors(Stmt s, int i, DestructorCall d, Expr destructed) {
|
||||
d = s.getImplicitDestructorCall(i) and
|
||||
d.getQualifier() = destructed
|
||||
}
|
||||
@@ -5565,6 +5565,30 @@ ir.cpp:
|
||||
# 619| Type = [PointerType] const char *
|
||||
# 619| ValueCategory = prvalue
|
||||
# 620| getStmt(4): [ReturnStmt] return ...
|
||||
# 620| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 620| Type = [VoidType] void
|
||||
# 620| ValueCategory = prvalue
|
||||
# 620| getQualifier(): [VariableAccess] s4
|
||||
# 620| Type = [Struct] String
|
||||
# 620| ValueCategory = lvalue
|
||||
# 620| getImplicitDestructorCall(1): [DestructorCall] call to ~String
|
||||
# 620| Type = [VoidType] void
|
||||
# 620| ValueCategory = prvalue
|
||||
# 620| getQualifier(): [VariableAccess] s3
|
||||
# 620| Type = [Struct] String
|
||||
# 620| ValueCategory = lvalue
|
||||
# 620| getImplicitDestructorCall(2): [DestructorCall] call to ~String
|
||||
# 620| Type = [VoidType] void
|
||||
# 620| ValueCategory = prvalue
|
||||
# 620| getQualifier(): [VariableAccess] s2
|
||||
# 620| Type = [Struct] String
|
||||
# 620| ValueCategory = lvalue
|
||||
# 620| getImplicitDestructorCall(3): [DestructorCall] call to ~String
|
||||
# 620| Type = [VoidType] void
|
||||
# 620| ValueCategory = prvalue
|
||||
# 620| getQualifier(): [VariableAccess] s1
|
||||
# 620| Type = [Struct] String
|
||||
# 620| ValueCategory = lvalue
|
||||
# 622| [TopLevelFunction] void CallMethods(String&, String*, String)
|
||||
# 622| <params>:
|
||||
# 622| getParameter(0): [Parameter] r
|
||||
@@ -7312,6 +7336,24 @@ ir.cpp:
|
||||
# 839| Type = [PointerType] Base *
|
||||
# 839| ValueCategory = prvalue
|
||||
# 840| getStmt(34): [ReturnStmt] return ...
|
||||
# 840| getImplicitDestructorCall(0): [DestructorCall] call to ~Derived
|
||||
# 840| Type = [VoidType] void
|
||||
# 840| ValueCategory = prvalue
|
||||
# 840| getQualifier(): [VariableAccess] d
|
||||
# 840| Type = [Struct] Derived
|
||||
# 840| ValueCategory = lvalue
|
||||
# 840| getImplicitDestructorCall(1): [DestructorCall] call to ~Middle
|
||||
# 840| Type = [VoidType] void
|
||||
# 840| ValueCategory = prvalue
|
||||
# 840| getQualifier(): [VariableAccess] m
|
||||
# 840| Type = [Struct] Middle
|
||||
# 840| ValueCategory = lvalue
|
||||
# 840| getImplicitDestructorCall(2): [DestructorCall] call to ~Base
|
||||
# 840| Type = [VoidType] void
|
||||
# 840| ValueCategory = prvalue
|
||||
# 840| getQualifier(): [VariableAccess] b
|
||||
# 840| Type = [Struct,VirtualBaseClass] Base
|
||||
# 840| ValueCategory = lvalue
|
||||
# 842| [CopyAssignmentOperator] PolymorphicBase& PolymorphicBase::operator=(PolymorphicBase const&)
|
||||
# 842| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -7475,6 +7517,18 @@ ir.cpp:
|
||||
# 864| Type = [PointerType] const void *
|
||||
# 864| ValueCategory = prvalue
|
||||
# 865| getStmt(10): [ReturnStmt] return ...
|
||||
# 865| getImplicitDestructorCall(0): [DestructorCall] call to ~PolymorphicDerived
|
||||
# 865| Type = [VoidType] void
|
||||
# 865| ValueCategory = prvalue
|
||||
# 865| getQualifier(): [VariableAccess] d
|
||||
# 865| Type = [Struct] PolymorphicDerived
|
||||
# 865| ValueCategory = lvalue
|
||||
# 865| getImplicitDestructorCall(1): [DestructorCall] call to ~PolymorphicBase
|
||||
# 865| Type = [VoidType] void
|
||||
# 865| ValueCategory = prvalue
|
||||
# 865| getQualifier(): [VariableAccess] b
|
||||
# 865| Type = [Struct] PolymorphicBase
|
||||
# 865| ValueCategory = lvalue
|
||||
# 867| [Constructor] void String::String()
|
||||
# 867| <params>:
|
||||
# 867| <initializations>:
|
||||
@@ -8954,6 +9008,18 @@ ir.cpp:
|
||||
# 1055| Value = [CStyleCast] 6.0
|
||||
# 1055| ValueCategory = prvalue
|
||||
# 1056| getStmt(15): [ReturnStmt] return ...
|
||||
# 1056| getImplicitDestructorCall(0): [DestructorCall] call to ~<unnamed>
|
||||
# 1056| Type = [VoidType] void
|
||||
# 1056| ValueCategory = prvalue
|
||||
# 1056| getQualifier(): [VariableAccess] lambda_val_explicit
|
||||
# 1056| Type = [Closure,LocalClass] decltype([...](...){...})
|
||||
# 1056| ValueCategory = lvalue
|
||||
# 1056| getImplicitDestructorCall(1): [DestructorCall] call to ~<unnamed>
|
||||
# 1056| Type = [VoidType] void
|
||||
# 1056| ValueCategory = prvalue
|
||||
# 1056| getQualifier(): [VariableAccess] lambda_val
|
||||
# 1056| Type = [Closure,LocalClass] decltype([...](...){...})
|
||||
# 1056| ValueCategory = lvalue
|
||||
# 1041| [CopyAssignmentOperator] (void Lambda(int, String const&))::(lambda [] type at line 1041, col. 23)& (void Lambda(int, String const&))::(lambda [] type at line 1041, col. 23)::operator=((void Lambda(int, String const&))::(lambda [] type at line 1041, col. 23) const&)
|
||||
# 1041| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -10149,6 +10215,24 @@ ir.cpp:
|
||||
# 1243| Type = [PointerType] const char *
|
||||
# 1243| ValueCategory = prvalue(load)
|
||||
# 1244| getStmt(3): [ReturnStmt] return ...
|
||||
# 1244| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 1244| Type = [VoidType] void
|
||||
# 1244| ValueCategory = prvalue
|
||||
# 1244| getQualifier(): [VariableAccess] c
|
||||
# 1244| Type = [Struct] String
|
||||
# 1244| ValueCategory = lvalue
|
||||
# 1244| getImplicitDestructorCall(1): [DestructorCall] call to ~String
|
||||
# 1244| Type = [VoidType] void
|
||||
# 1244| ValueCategory = prvalue
|
||||
# 1244| getQualifier(): [VariableAccess] b
|
||||
# 1244| Type = [Struct] String
|
||||
# 1244| ValueCategory = lvalue
|
||||
# 1244| getImplicitDestructorCall(2): [DestructorCall] call to ~String
|
||||
# 1244| Type = [VoidType] void
|
||||
# 1244| ValueCategory = prvalue
|
||||
# 1244| getQualifier(): [VariableAccess] a
|
||||
# 1244| Type = [Struct] String
|
||||
# 1244| ValueCategory = lvalue
|
||||
# 1248| [TopLevelFunction] char* strcpy(char*, char const*)
|
||||
# 1248| <params>:
|
||||
# 1248| getParameter(0): [Parameter] destination
|
||||
@@ -10403,6 +10487,12 @@ ir.cpp:
|
||||
# 1286| Type = [PointerType] A *
|
||||
# 1286| ValueCategory = prvalue
|
||||
# 1287| getStmt(12): [ReturnStmt] return ...
|
||||
# 1287| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 1287| Type = [VoidType] void
|
||||
# 1287| ValueCategory = prvalue
|
||||
# 1287| getQualifier(): [VariableAccess] c
|
||||
# 1287| Type = [Class] C
|
||||
# 1287| ValueCategory = lvalue
|
||||
# 1289| [TopLevelFunction] int missingReturnValue(bool, int)
|
||||
# 1289| <params>:
|
||||
# 1289| getParameter(0): [Parameter] b
|
||||
@@ -10957,6 +11047,12 @@ ir.cpp:
|
||||
# 1376| Type = [Struct] String
|
||||
# 1376| ValueCategory = prvalue
|
||||
# 1377| getStmt(9): [ReturnStmt] return ...
|
||||
# 1377| getImplicitDestructorCall(0): [DestructorCall] call to ~String
|
||||
# 1377| Type = [VoidType] void
|
||||
# 1377| ValueCategory = prvalue
|
||||
# 1377| getQualifier(): [VariableAccess] s
|
||||
# 1377| Type = [Struct] String
|
||||
# 1377| ValueCategory = lvalue
|
||||
# 1379| [TopLevelFunction] void temporary_destructor_only()
|
||||
# 1379| <params>:
|
||||
# 1379| getEntryPoint(): [BlockStmt] { ... }
|
||||
@@ -11040,6 +11136,18 @@ ir.cpp:
|
||||
# 1388| Type = [Class] destructor_only
|
||||
# 1388| ValueCategory = prvalue
|
||||
# 1389| getStmt(8): [ReturnStmt] return ...
|
||||
# 1389| getImplicitDestructorCall(0): [DestructorCall] call to ~destructor_only
|
||||
# 1389| Type = [VoidType] void
|
||||
# 1389| ValueCategory = prvalue
|
||||
# 1389| getQualifier(): [VariableAccess] d2
|
||||
# 1389| Type = [Class] destructor_only
|
||||
# 1389| ValueCategory = lvalue
|
||||
# 1389| getImplicitDestructorCall(1): [DestructorCall] call to ~destructor_only
|
||||
# 1389| Type = [VoidType] void
|
||||
# 1389| ValueCategory = prvalue
|
||||
# 1389| getQualifier(): [VariableAccess] d
|
||||
# 1389| Type = [Class] destructor_only
|
||||
# 1389| ValueCategory = lvalue
|
||||
# 1391| [TopLevelFunction] void temporary_copy_constructor()
|
||||
# 1391| <params>:
|
||||
# 1391| getEntryPoint(): [BlockStmt] { ... }
|
||||
@@ -14696,6 +14804,12 @@ ir.cpp:
|
||||
# 1925| Value = [Literal] 10
|
||||
# 1925| ValueCategory = prvalue
|
||||
# 1926| getStmt(7): [ReturnStmt] return ...
|
||||
# 1926| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 1926| Type = [VoidType] void
|
||||
# 1926| ValueCategory = prvalue
|
||||
# 1926| getQualifier(): [VariableAccess] c
|
||||
# 1926| Type = [Class] C
|
||||
# 1926| ValueCategory = lvalue
|
||||
# 1928| [TopLevelFunction] void test_double_assign()
|
||||
# 1928| <params>:
|
||||
# 1928| getEntryPoint(): [BlockStmt] { ... }
|
||||
@@ -15048,6 +15162,12 @@ ir.cpp:
|
||||
# 1993| Type = [Class] C
|
||||
# 1993| ValueCategory = lvalue
|
||||
# 1994| getStmt(3): [ReturnStmt] return ...
|
||||
# 1994| getImplicitDestructorCall(0): [DestructorCall] call to ~C
|
||||
# 1994| Type = [VoidType] void
|
||||
# 1994| ValueCategory = prvalue
|
||||
# 1994| getQualifier(): [VariableAccess] c
|
||||
# 1994| Type = [Class] C
|
||||
# 1994| ValueCategory = lvalue
|
||||
# 1996| [TopLevelFunction] void TernaryTestInt(bool, int, int, int)
|
||||
# 1996| <params>:
|
||||
# 1996| getParameter(0): [Parameter] a
|
||||
@@ -16062,6 +16182,12 @@ smart_ptr.cpp:
|
||||
# 12| Type = [CTypedefType,NestedTypedefType] type
|
||||
# 12| ValueCategory = prvalue(load)
|
||||
# 13| getStmt(2): [ReturnStmt] return ...
|
||||
# 13| getImplicitDestructorCall(0): [DestructorCall] call to ~unique_ptr
|
||||
# 13| Type = [VoidType] void
|
||||
# 13| ValueCategory = prvalue
|
||||
# 13| getQualifier(): [VariableAccess] up
|
||||
# 13| Type = [ClassTemplateInstantiation] unique_ptr<int, default_delete<int>>
|
||||
# 13| ValueCategory = lvalue
|
||||
# 15| [TopLevelFunction] void shared_ptr_arg(std::shared_ptr<float>)
|
||||
# 15| <params>:
|
||||
# 15| getParameter(0): [Parameter] sp
|
||||
@@ -16102,6 +16228,12 @@ smart_ptr.cpp:
|
||||
# 19| Type = [ClassTemplateInstantiation] shared_ptr<float>
|
||||
# 19| ValueCategory = lvalue
|
||||
# 20| getStmt(2): [ReturnStmt] return ...
|
||||
# 20| getImplicitDestructorCall(0): [DestructorCall] call to ~shared_ptr
|
||||
# 20| Type = [VoidType] void
|
||||
# 20| ValueCategory = prvalue
|
||||
# 20| getQualifier(): [VariableAccess] sp
|
||||
# 20| Type = [ClassTemplateInstantiation] shared_ptr<float>
|
||||
# 20| ValueCategory = lvalue
|
||||
# 22| [TopLevelFunction] void shared_ptr_const_int(std::shared_ptr<int const>)
|
||||
# 22| <params>:
|
||||
# 22| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
@@ -16241,6 +16373,36 @@ smart_ptr.cpp:
|
||||
# 47| Type = [ClassTemplateInstantiation] shared_ptr<const shared_ptr<const int>>
|
||||
# 47| ValueCategory = lvalue
|
||||
# 48| getStmt(10): [ReturnStmt] return ...
|
||||
# 48| getImplicitDestructorCall(0): [DestructorCall] call to ~shared_ptr
|
||||
# 48| Type = [VoidType] void
|
||||
# 48| ValueCategory = prvalue
|
||||
# 48| getQualifier(): [VariableAccess] sp_const_sp_const_int
|
||||
# 48| Type = [ClassTemplateInstantiation] shared_ptr<const shared_ptr<const int>>
|
||||
# 48| ValueCategory = lvalue
|
||||
# 48| getImplicitDestructorCall(1): [DestructorCall] call to ~shared_ptr
|
||||
# 48| Type = [VoidType] void
|
||||
# 48| ValueCategory = prvalue
|
||||
# 48| getQualifier(): [VariableAccess] sp_const_sp_int
|
||||
# 48| Type = [ClassTemplateInstantiation] shared_ptr<const shared_ptr<int>>
|
||||
# 48| ValueCategory = lvalue
|
||||
# 48| getImplicitDestructorCall(2): [DestructorCall] call to ~shared_ptr
|
||||
# 48| Type = [VoidType] void
|
||||
# 48| ValueCategory = prvalue
|
||||
# 48| getQualifier(): [VariableAccess] sp_sp_const_int
|
||||
# 48| Type = [ClassTemplateInstantiation] shared_ptr<shared_ptr<const int>>
|
||||
# 48| ValueCategory = lvalue
|
||||
# 48| getImplicitDestructorCall(3): [DestructorCall] call to ~shared_ptr
|
||||
# 48| Type = [VoidType] void
|
||||
# 48| ValueCategory = prvalue
|
||||
# 48| getQualifier(): [VariableAccess] sp_const_int_pointer
|
||||
# 48| Type = [ClassTemplateInstantiation] shared_ptr<int *const>
|
||||
# 48| ValueCategory = lvalue
|
||||
# 48| getImplicitDestructorCall(4): [DestructorCall] call to ~shared_ptr
|
||||
# 48| Type = [VoidType] void
|
||||
# 48| ValueCategory = prvalue
|
||||
# 48| getQualifier(): [VariableAccess] sp_const_int
|
||||
# 48| Type = [ClassTemplateInstantiation] shared_ptr<const int>
|
||||
# 48| ValueCategory = lvalue
|
||||
struct_init.cpp:
|
||||
# 1| [TopLevelFunction] int handler1(void*)
|
||||
# 1| <params>:
|
||||
|
||||
Reference in New Issue
Block a user