diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 48daf84d6b29..01da9c1c8ff7 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/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/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index 763ed2c7b4d6..7b9b9d497ff4 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/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 {