@@ -932,39 +932,24 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
932932 Expr getExtent ( ) { result = this .getChild ( 2 ) }
933933}
934934
935+ private class TDeleteOrDeleteArrayExpr = @delete_expr or @delete_array_expr;
936+
935937/**
936- * A C++ `delete` (non-array) expression.
937- * ```
938- * delete ptr;
939- * ```
938+ * A C++ `delete` or `delete[]` expression.
940939 */
941- class DeleteExpr extends Expr , @delete_expr {
942- override string toString ( ) { result = "delete" }
943-
944- override string getAPrimaryQlClass ( ) { result = "DeleteExpr" }
945-
940+ class DeleteOrDeleteArrayExpr extends Expr , TDeleteOrDeleteArrayExpr {
946941 override int getPrecedence ( ) { result = 16 }
947942
948- /**
949- * Gets the compile-time type of the object being deleted.
950- */
951- Type getDeletedObjectType ( ) {
952- result =
953- this .getExpr ( )
954- .getFullyConverted ( )
955- .getType ( )
956- .stripTopLevelSpecifiers ( )
957- .( PointerType )
958- .getBaseType ( )
959- }
960-
961943 /**
962944 * Gets the call to a destructor that occurs prior to the object's memory being deallocated, if any.
945+ *
946+ * In the case of `delete[]` at runtime, the destructor will be called once for each element in the array, but the
947+ * destructor call only exists once in the AST.
963948 */
964949 DestructorCall getDestructorCall ( ) { result = this .getChild ( 1 ) }
965950
966951 /**
967- * Gets the destructor to be called to destroy the object, if any.
952+ * Gets the destructor to be called to destroy the object(s) , if any.
968953 */
969954 Destructor getDestructor ( ) { result = this .getDestructorCall ( ) .getTarget ( ) }
970955
@@ -978,6 +963,14 @@ class DeleteExpr extends Expr, @delete_expr {
978963 expr_deallocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
979964 }
980965
966+ /**
967+ * Gets the call to a non-default `operator delete` that deallocates storage, if any.
968+ *
969+ * This will only be present when the type being deleted has a custom `operator delete` and
970+ * is not a class with a virtual destructor.
971+ */
972+ FunctionCall getAllocatorCall ( ) { result = this .getChild ( 0 ) }
973+
981974 /**
982975 * Holds if the deallocation function expects a size argument.
983976 */
@@ -999,16 +992,37 @@ class DeleteExpr extends Expr, @delete_expr {
999992 }
1000993
1001994 /**
1002- * Gets the call to a non-default `operator delete` that deallocates storage, if any.
1003- *
1004- * This will only be present when the type being deleted has a custom `operator delete`.
995+ * Gets the object being deleted.
1005996 */
1006- FunctionCall getAllocatorCall ( ) { result = this .getChild ( 0 ) }
997+ Expr getExpr ( ) {
998+ // If there is a destuctor call, the object being deleted is the qualifier
999+ // otherwise it is the third child.
1000+ result = this .getChild ( 3 ) or result = this .getDestructorCall ( ) .getQualifier ( ) }
1001+ }
1002+
1003+ /**
1004+ * A C++ `delete` (non-array) expression.
1005+ * ```
1006+ * delete ptr;
1007+ * ```
1008+ */
1009+ class DeleteExpr extends DeleteOrDeleteArrayExpr , @delete_expr {
1010+ override string toString ( ) { result = "delete" }
1011+
1012+ override string getAPrimaryQlClass ( ) { result = "DeleteExpr" }
10071013
10081014 /**
1009- * Gets the object being deleted.
1015+ * Gets the compile-time type of the object being deleted.
10101016 */
1011- Expr getExpr ( ) { result = this .getChild ( 3 ) or result = this .getChild ( 1 ) .getChild ( - 1 ) }
1017+ Type getDeletedObjectType ( ) {
1018+ result =
1019+ this .getExpr ( )
1020+ .getFullyConverted ( )
1021+ .getType ( )
1022+ .stripTopLevelSpecifiers ( )
1023+ .( PointerType )
1024+ .getBaseType ( )
1025+ }
10121026}
10131027
10141028/**
@@ -1017,13 +1031,11 @@ class DeleteExpr extends Expr, @delete_expr {
10171031 * delete[] arr;
10181032 * ```
10191033 */
1020- class DeleteArrayExpr extends Expr , @delete_array_expr {
1034+ class DeleteArrayExpr extends DeleteOrDeleteArrayExpr , @delete_array_expr {
10211035 override string toString ( ) { result = "delete[]" }
10221036
10231037 override string getAPrimaryQlClass ( ) { result = "DeleteArrayExpr" }
10241038
1025- override int getPrecedence ( ) { result = 16 }
1026-
10271039 /**
10281040 * Gets the element type of the array being deleted.
10291041 */
@@ -1036,58 +1048,6 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
10361048 .( PointerType )
10371049 .getBaseType ( )
10381050 }
1039-
1040- /**
1041- * Gets the call to a destructor that occurs prior to the array's memory being deallocated, if any.
1042- *
1043- * At runtime, the destructor will be called once for each element in the array, but the
1044- * destructor call only exists once in the AST.
1045- */
1046- DestructorCall getDestructorCall ( ) { result = this .getChild ( 1 ) }
1047-
1048- /**
1049- * Gets the destructor to be called to destroy each element in the array, if any.
1050- */
1051- Destructor getDestructor ( ) { result = this .getDestructorCall ( ) .getTarget ( ) }
1052-
1053- /**
1054- * Gets the `operator delete[]` that deallocates storage.
1055- */
1056- Function getDeallocator ( ) {
1057- expr_deallocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
1058- }
1059-
1060- /**
1061- * Holds if the deallocation function expects a size argument.
1062- */
1063- predicate hasSizedDeallocation ( ) {
1064- exists ( int form |
1065- expr_deallocator ( underlyingElement ( this ) , _, form ) and
1066- form .bitAnd ( 1 ) != 0 // Bit zero is the "size" bit
1067- )
1068- }
1069-
1070- /**
1071- * Holds if the deallocation function expects an alignment argument.
1072- */
1073- predicate hasAlignedDeallocation ( ) {
1074- exists ( int form |
1075- expr_deallocator ( underlyingElement ( this ) , _, form ) and
1076- form .bitAnd ( 2 ) != 0 // Bit one is the "alignment" bit
1077- )
1078- }
1079-
1080- /**
1081- * Gets the call to a non-default `operator delete` that deallocates storage, if any.
1082- *
1083- * This will only be present when the type being deleted has a custom `operator delete`.
1084- */
1085- FunctionCall getAllocatorCall ( ) { result = this .getChild ( 0 ) }
1086-
1087- /**
1088- * Gets the array being deleted.
1089- */
1090- Expr getExpr ( ) { result = this .getChild ( 3 ) or result = this .getChild ( 1 ) .getChild ( - 1 ) }
10911051}
10921052
10931053/**
0 commit comments