Skip to content

Commit 07c08f8

Browse files
Create common base class for NewExpr and NewArrayExpr
1 parent 44ae7b6 commit 07c08f8

File tree

1 file changed

+44
-68
lines changed
  • cpp/ql/src/semmle/code/cpp/exprs

1 file changed

+44
-68
lines changed

cpp/ql/src/semmle/code/cpp/exprs/Expr.qll

Lines changed: 44 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)