@@ -932,52 +932,50 @@ 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 or array , if any.
968953 */
969954 Destructor getDestructor ( ) { result = this .getDestructorCall ( ) .getTarget ( ) }
970955
971956 /**
972- * Gets the `operator delete` that deallocates storage. Does not hold
973- * if the type being destroyed has a virtual destructor. In that case, the
957+ * Gets the `operator delete` or `operator delete[]` that deallocates storage.
958+ * Does not hold if the type being destroyed has a virtual destructor. In that case, the
974959 * `operator delete` that will be called is determined at runtime based on the
975960 * dynamic type of the object.
976961 */
977962 Function getDeallocator ( ) {
978963 expr_deallocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
979964 }
980965
966+ /**
967+ * DEPRECATED: use `getDeallocatorCall` instead.
968+ */
969+ deprecated FunctionCall getAllocatorCall ( ) { result = this .getChild ( 0 ) }
970+
971+ /**
972+ * Gets the call to a non-default `operator delete`/`delete[]` that deallocates storage, if any.
973+ *
974+ * This will only be present when the type being deleted has a custom `operator delete` and
975+ * does not have a virtual destructor.
976+ */
977+ FunctionCall getDeallocatorCall ( ) { result = this .getChild ( 0 ) }
978+
981979 /**
982980 * Holds if the deallocation function expects a size argument.
983981 */
@@ -999,16 +997,38 @@ class DeleteExpr extends Expr, @delete_expr {
999997 }
1000998
1001999 /**
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`.
1000+ * Gets the object or array being deleted.
10051001 */
1006- FunctionCall getAllocatorCall ( ) { result = this .getChild ( 0 ) }
1002+ Expr getExpr ( ) {
1003+ // If there is a destructor call, the object being deleted is the qualifier
1004+ // otherwise it is the third child.
1005+ result = this .getChild ( 3 ) or result = this .getDestructorCall ( ) .getQualifier ( )
1006+ }
1007+ }
1008+
1009+ /**
1010+ * A C++ `delete` (non-array) expression.
1011+ * ```
1012+ * delete ptr;
1013+ * ```
1014+ */
1015+ class DeleteExpr extends DeleteOrDeleteArrayExpr , @delete_expr {
1016+ override string toString ( ) { result = "delete" }
1017+
1018+ override string getAPrimaryQlClass ( ) { result = "DeleteExpr" }
10071019
10081020 /**
1009- * Gets the object being deleted.
1021+ * Gets the compile-time type of the object being deleted.
10101022 */
1011- Expr getExpr ( ) { result = this .getChild ( 3 ) or result = this .getChild ( 1 ) .getChild ( - 1 ) }
1023+ Type getDeletedObjectType ( ) {
1024+ result =
1025+ this .getExpr ( )
1026+ .getFullyConverted ( )
1027+ .getType ( )
1028+ .stripTopLevelSpecifiers ( )
1029+ .( PointerType )
1030+ .getBaseType ( )
1031+ }
10121032}
10131033
10141034/**
@@ -1017,13 +1037,11 @@ class DeleteExpr extends Expr, @delete_expr {
10171037 * delete[] arr;
10181038 * ```
10191039 */
1020- class DeleteArrayExpr extends Expr , @delete_array_expr {
1040+ class DeleteArrayExpr extends DeleteOrDeleteArrayExpr , @delete_array_expr {
10211041 override string toString ( ) { result = "delete[]" }
10221042
10231043 override string getAPrimaryQlClass ( ) { result = "DeleteArrayExpr" }
10241044
1025- override int getPrecedence ( ) { result = 16 }
1026-
10271045 /**
10281046 * Gets the element type of the array being deleted.
10291047 */
@@ -1036,58 +1054,6 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
10361054 .( PointerType )
10371055 .getBaseType ( )
10381056 }
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 ) }
10911057}
10921058
10931059/**
0 commit comments