When the type-id or new-type-id of a C++ "new" expression is a typedef

of an array type, use the outermost array bound as the number of
elements to allocate. Fixes PR7147.

llvm-svn: 103908
This commit is contained in:
Douglas Gregor 2010-05-16 16:01:03 +00:00
parent 5ce10a6744
commit cda95f47e5
2 changed files with 22 additions and 3 deletions

View File

@ -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."

View File

@ -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 {