CPP: Add parent class for delete and delete[]

This commit is contained in:
Alex Eyers-Taylor
2023-08-22 19:30:43 +01:00
parent 6573b1f772
commit 4ca98bd6fd

View File

@@ -932,39 +932,24 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
Expr getExtent() { result = this.getChild(2) }
}
private class TDeleteOrDeleteArrayExpr = @delete_expr or @delete_array_expr;
/**
* A C++ `delete` (non-array) expression.
* ```
* delete ptr;
* ```
* A C++ `delete` or `delete[]` expression.
*/
class DeleteExpr extends Expr, @delete_expr {
override string toString() { result = "delete" }
override string getAPrimaryQlClass() { result = "DeleteExpr" }
class DeleteOrDeleteArrayExpr extends Expr, TDeleteOrDeleteArrayExpr {
override int getPrecedence() { result = 16 }
/**
* Gets the compile-time type of the object being deleted.
*/
Type getDeletedObjectType() {
result =
this.getExpr()
.getFullyConverted()
.getType()
.stripTopLevelSpecifiers()
.(PointerType)
.getBaseType()
}
/**
* Gets the call to a destructor that occurs prior to the object's memory being deallocated, if any.
*
* In the case of `delete[]` at runtime, the destructor will be called once for each element in the array, but the
* destructor call only exists once in the AST.
*/
DestructorCall getDestructorCall() { result = this.getChild(1) }
/**
* Gets the destructor to be called to destroy the object, if any.
* Gets the destructor to be called to destroy the object(s), if any.
*/
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
@@ -978,6 +963,14 @@ class DeleteExpr extends Expr, @delete_expr {
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
}
/**
* Gets the call to a non-default `operator delete` that deallocates storage, if any.
*
* This will only be present when the type being deleted has a custom `operator delete` and
* is not a class with a virtual destructor.
*/
FunctionCall getAllocatorCall() { result = this.getChild(0) }
/**
* Holds if the deallocation function expects a size argument.
*/
@@ -998,17 +991,38 @@ class DeleteExpr extends Expr, @delete_expr {
)
}
/**
* Gets the call to a non-default `operator delete` that deallocates storage, if any.
*
* This will only be present when the type being deleted has a custom `operator delete`.
*/
FunctionCall getAllocatorCall() { result = this.getChild(0) }
/**
* Gets the object being deleted.
*/
Expr getExpr() { result = this.getChild(3) or result = this.getChild(1).getChild(-1) }
Expr getExpr() {
// If there is a destuctor call, the object being deleted is the qualifier
// otherwise it is the third child.
result = this.getChild(3) or result = this.getDestructorCall().getQualifier() }
}
/**
* A C++ `delete` (non-array) expression.
* ```
* delete ptr;
* ```
*/
class DeleteExpr extends DeleteOrDeleteArrayExpr, @delete_expr {
override string toString() { result = "delete" }
override string getAPrimaryQlClass() { result = "DeleteExpr" }
/**
* Gets the compile-time type of the object being deleted.
*/
Type getDeletedObjectType() {
result =
this.getExpr()
.getFullyConverted()
.getType()
.stripTopLevelSpecifiers()
.(PointerType)
.getBaseType()
}
}
/**
@@ -1017,13 +1031,11 @@ class DeleteExpr extends Expr, @delete_expr {
* delete[] arr;
* ```
*/
class DeleteArrayExpr extends Expr, @delete_array_expr {
class DeleteArrayExpr extends DeleteOrDeleteArrayExpr, @delete_array_expr {
override string toString() { result = "delete[]" }
override string getAPrimaryQlClass() { result = "DeleteArrayExpr" }
override int getPrecedence() { result = 16 }
/**
* Gets the element type of the array being deleted.
*/
@@ -1036,58 +1048,6 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
.(PointerType)
.getBaseType()
}
/**
* Gets the call to a destructor that occurs prior to the array's memory being deallocated, if any.
*
* At runtime, the destructor will be called once for each element in the array, but the
* destructor call only exists once in the AST.
*/
DestructorCall getDestructorCall() { result = this.getChild(1) }
/**
* Gets the destructor to be called to destroy each element in the array, if any.
*/
Destructor getDestructor() { result = this.getDestructorCall().getTarget() }
/**
* Gets the `operator delete[]` that deallocates storage.
*/
Function getDeallocator() {
expr_deallocator(underlyingElement(this), unresolveElement(result), _)
}
/**
* Holds if the deallocation function expects a size argument.
*/
predicate hasSizedDeallocation() {
exists(int form |
expr_deallocator(underlyingElement(this), _, form) and
form.bitAnd(1) != 0 // Bit zero is the "size" bit
)
}
/**
* Holds if the deallocation function expects an alignment argument.
*/
predicate hasAlignedDeallocation() {
exists(int form |
expr_deallocator(underlyingElement(this), _, form) and
form.bitAnd(2) != 0 // Bit one is the "alignment" bit
)
}
/**
* Gets the call to a non-default `operator delete` that deallocates storage, if any.
*
* This will only be present when the type being deleted has a custom `operator delete`.
*/
FunctionCall getAllocatorCall() { result = this.getChild(0) }
/**
* Gets the array being deleted.
*/
Expr getExpr() { result = this.getChild(3) or result = this.getChild(1).getChild(-1) }
}
/**