@@ -581,24 +581,13 @@ class ReferenceDereferenceExpr extends Conversion, @ref_indirect {
581
581
}
582
582
583
583
/**
584
- * A C++ `new` (non-array) expression.
584
+ * A C++ `new` or `new[]` expression.
585
585
*/
586
- class NewExpr extends Expr , @new_expr {
587
- override string toString ( ) { result = "new" }
588
-
586
+ class NewOrNewArrayExpr extends Expr , @any_new_expr {
589
587
override int getPrecedence ( ) { result = 15 }
590
588
591
589
/**
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.
602
591
*/
603
592
Function getAllocator ( ) {
604
593
expr_allocator ( underlyingElement ( this ) , unresolveElement ( result ) , _)
@@ -612,6 +601,21 @@ class NewExpr extends Expr, @new_expr {
612
601
expr_allocator ( underlyingElement ( this ) , _, 1 )
613
602
}
614
603
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
+
615
619
/**
616
620
* Gets the call to a non-default `operator new` that allocates storage, if any.
617
621
*
@@ -652,6 +656,30 @@ class NewExpr extends Expr, @new_expr {
652
656
)
653
657
}
654
658
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
+
655
683
/**
656
684
* Gets the call or expression that initializes the allocated object, if any.
657
685
*
@@ -664,17 +692,15 @@ class NewExpr extends Expr, @new_expr {
664
692
/**
665
693
* A C++ `new[]` (array) expression.
666
694
*/
667
- class NewArrayExpr extends Expr , @new_array_expr {
695
+ class NewArrayExpr extends NewOrNewArrayExpr , @new_array_expr {
668
696
override string toString ( ) { result = "new[]" }
669
697
670
- override int getPrecedence ( ) { result = 15 }
671
-
672
698
/**
673
699
* Gets the type that is being allocated.
674
700
*
675
701
* For example, for `new int[5]` the result is `int[5]`.
676
702
*/
677
- Type getAllocatedType ( ) {
703
+ override Type getAllocatedType ( ) {
678
704
new_array_allocated_type ( underlyingElement ( this ) , unresolveElement ( result ) )
679
705
}
680
706
@@ -685,56 +711,6 @@ class NewArrayExpr extends Expr, @new_array_expr {
685
711
result = getType ( ) .getUnderlyingType ( ) .( PointerType ) .getBaseType ( )
686
712
}
687
713
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
-
738
714
/**
739
715
* Gets the call or expression that initializes the first element of the array, if any.
740
716
*
0 commit comments