@@ -581,24 +581,13 @@ class ReferenceDereferenceExpr extends Conversion, @ref_indirect {
581581}
582582
583583/**
584- * A C++ `new` (non-array) expression.
584+ * A C++ `new` or `new[]` expression.
585585 */
586- class NewExpr extends Expr , @new_expr {
587- override string toString ( ) { result = "new" }
588-
586+ class NewOrNewArrayExpr extends Expr , @any_new_expr {
589587 override int getPrecedence ( ) { result = 15 }
590588
591589 /**
592- * Gets the type that is being allocated.
593- *
594- * For example, for `new int` the result is `int`.
595- */
596- Type getAllocatedType ( ) {
597- new_allocated_type ( underlyingElement ( this ) , unresolveElement ( result ) )
598- }
599-
600- /**
601- * Gets the `operator new` that allocates storage.
590+ * Gets the `operator new` or `operator new[]` that allocates storage.
602591 */
603592 Function getAllocator ( ) {
604593 expr_allocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
@@ -612,6 +601,21 @@ class NewExpr extends Expr, @new_expr {
612601 expr_allocator ( underlyingElement ( this ) , _, 1 )
613602 }
614603
604+ /**
605+ * Gets the alignment argument passed to the allocation function, if any.
606+ */
607+ Expr getAlignmentArgument ( ) {
608+ hasAlignedAllocation ( ) and
609+ (
610+ // If we have an allocator call, the alignment is the second argument to
611+ // that call.
612+ result = getAllocatorCall ( ) .getArgument ( 1 ) or
613+ // Otherwise, the alignment winds up as child number 3 of the `new`
614+ // itself.
615+ result = getChild ( 3 )
616+ )
617+ }
618+
615619 /**
616620 * Gets the call to a non-default `operator new` that allocates storage, if any.
617621 *
@@ -652,6 +656,30 @@ class NewExpr extends Expr, @new_expr {
652656 )
653657 }
654658
659+ /**
660+ * Gets the type that is being allocated.
661+ *
662+ * For example, for `new int` the result is `int`.
663+ * For `new int[5]` the result is `int[5]`.
664+ */
665+ abstract Type getAllocatedType ( ) ;
666+ }
667+
668+ /**
669+ * A C++ `new` (non-array) expression.
670+ */
671+ class NewExpr extends NewOrNewArrayExpr , @new_expr {
672+ override string toString ( ) { result = "new" }
673+
674+ /**
675+ * Gets the type that is being allocated.
676+ *
677+ * For example, for `new int` the result is `int`.
678+ */
679+ override Type getAllocatedType ( ) {
680+ new_allocated_type ( underlyingElement ( this ) , unresolveElement ( result ) )
681+ }
682+
655683 /**
656684 * Gets the call or expression that initializes the allocated object, if any.
657685 *
@@ -664,17 +692,15 @@ class NewExpr extends Expr, @new_expr {
664692/**
665693 * A C++ `new[]` (array) expression.
666694 */
667- class NewArrayExpr extends Expr , @new_array_expr {
695+ class NewArrayExpr extends NewOrNewArrayExpr , @new_array_expr {
668696 override string toString ( ) { result = "new[]" }
669697
670- override int getPrecedence ( ) { result = 15 }
671-
672698 /**
673699 * Gets the type that is being allocated.
674700 *
675701 * For example, for `new int[5]` the result is `int[5]`.
676702 */
677- Type getAllocatedType ( ) {
703+ override Type getAllocatedType ( ) {
678704 new_array_allocated_type ( underlyingElement ( this ) , unresolveElement ( result ) )
679705 }
680706
@@ -685,56 +711,6 @@ class NewArrayExpr extends Expr, @new_array_expr {
685711 result = getType ( ) .getUnderlyingType ( ) .( PointerType ) .getBaseType ( )
686712 }
687713
688- /**
689- * Gets the `operator new[]` that allocates storage.
690- */
691- Function getAllocator ( ) {
692- expr_allocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
693- }
694-
695- /**
696- * Holds if the allocation function is the version that expects an alignment
697- * argument of type `std::align_val_t`.
698- */
699- predicate hasAlignedAllocation ( ) {
700- expr_allocator ( underlyingElement ( this ) , _, 1 )
701- }
702-
703- /**
704- * Gets the call to a non-default `operator new[]` that allocates storage for the array, if any.
705- *
706- * If the default `operator new[]` is used, then there will be no call.
707- */
708- FunctionCall getAllocatorCall ( ) { result = this .getChild ( 0 ) }
709-
710- /**
711- * Gets the `operator delete` that deallocates storage if the initialization
712- * throws an exception, if any.
713- */
714- Function getDeallocator ( ) {
715- expr_deallocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
716- }
717-
718- /**
719- * Holds if the deallocation function expects a size argument.
720- */
721- predicate hasSizedDeallocation ( ) {
722- exists ( int form |
723- expr_deallocator ( underlyingElement ( this ) , _, form ) and
724- form .bitAnd ( 1 ) != 0 // Bit zero is the "size" bit
725- )
726- }
727-
728- /**
729- * Holds if the deallocation function expects an alignment argument.
730- */
731- predicate hasAlignedDeallocation ( ) {
732- exists ( int form |
733- expr_deallocator ( underlyingElement ( this ) , _, form ) and
734- form .bitAnd ( 2 ) != 0 // Bit one is the "alignment" bit
735- )
736- }
737-
738714 /**
739715 * Gets the call or expression that initializes the first element of the array, if any.
740716 *
0 commit comments