diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-05-16 16:01:03 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-05-16 16:01:03 +0000 |
commit | 3caf04ea0c01ff6822209c4621c3fa64a48029a4 (patch) | |
tree | 33146b47b21a339e79d09143bc79b40e258c38fe | |
parent | 16565aa95b086fb239baf82335dccc1b1ec93942 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103908 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 15 | ||||
-rw-r--r-- | test/SemaCXX/new-delete.cpp | 10 |
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 { |