]> granicus.if.org Git - clang/commitdiff
When the type-id or new-type-id of a C++ "new" expression is a typedef
authorDouglas Gregor <dgregor@apple.com>
Sun, 16 May 2010 16:01:03 +0000 (16:01 +0000)
committerDouglas Gregor <dgregor@apple.com>
Sun, 16 May 2010 16:01:03 +0000 (16:01 +0000)
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

lib/Sema/SemaExprCXX.cpp
test/SemaCXX/new-delete.cpp

index 48daf84d6b29866465673b84f8d69ba3ee08d778..01da9c1c8ff7d5656ee3ad0f44553a225bb3c6e2 100644 (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."
index 763ed2c7b4d6b440e84192b287bd9bc63dc1b27d..7b9b9d497ff4eb6d042031be0a93e6bb4b0610af 100644 (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 {