aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaExprCXX.cpp15
-rw-r--r--test/SemaCXX/new-delete.cpp10
2 files changed, 22 insertions, 3 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 48daf84d6b..01da9c1c8f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -680,10 +680,19 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (CheckAllocatedType(AllocType, TypeLoc, TypeRange))
return ExprError();
- QualType ResultType = Context.getPointerType(AllocType);
+ // Per C++0x [expr.new]p5, the type being constructed may be a
+ // typedef of an array type.
+ if (!ArraySizeE.get()) {
+ if (const ConstantArrayType *Array
+ = Context.getAsConstantArrayType(AllocType)) {
+ ArraySizeE = Owned(new (Context) IntegerLiteral(Array->getSize(),
+ Context.getSizeType(),
+ TypeRange.getEnd()));
+ AllocType = Array->getElementType();
+ }
+ }
- // That every array dimension except the first is constant was already
- // checked by the type check above.
+ QualType ResultType = Context.getPointerType(AllocType);
// C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral
// or enumeration type with a non-negative value."
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 763ed2c7b4..7b9b9d497f 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -24,6 +24,8 @@ void* operator new(size_t, int*); // expected-note 3 {{candidate}}
void* operator new(size_t, float*); // expected-note 3 {{candidate}}
void* operator new(size_t, S); // expected-note 2 {{candidate}}
+struct foo { };
+
void good_news()
{
int *pi = new int;
@@ -43,6 +45,14 @@ void good_news()
pi = new (S(1.0f, 2)) int;
(void)new int[true];
+
+ // PR7147
+ typedef int a[2];
+ foo* f1 = new foo;
+ foo* f2 = new foo[2];
+ typedef foo x[2];
+ typedef foo y[2][2];
+ x* f3 = new y;
}
struct abstract {