[cfe-commits] r91907 - in /cfe/trunk: lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-expr-4.cpp

Douglas Gregor dgregor at apple.com
Tue Dec 22 09:13:38 PST 2009


Author: dgregor
Date: Tue Dec 22 11:13:37 2009
New Revision: 91907

URL: http://llvm.org/viewvc/llvm-project?rev=91907&view=rev
Log:
When transforming a C++ "new" expression that was not explicitly given
a size, check whether the transformed type is itself an array type. If
so, take the major array bound as the size to allocate. Fixes PR5833.

Modified:
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=91907&r1=91906&r2=91907&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Dec 22 11:13:37 2009
@@ -4481,6 +4481,31 @@
       !ArgumentChanged)
     return SemaRef.Owned(E->Retain());
 
+  if (!ArraySize.get()) {
+    // If no array size was specified, but the new expression was
+    // instantiated with an array type (e.g., "new T" where T is
+    // instantiated with "int[4]"), extract the outer bound from the
+    // array type as our array size. We do this with constant and
+    // dependently-sized array types.
+    const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
+    if (!ArrayT) {
+      // Do nothing
+    } else if (const ConstantArrayType *ConsArrayT
+                                     = dyn_cast<ConstantArrayType>(ArrayT)) {
+      ArraySize 
+        = SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
+                                                  ConsArrayT->getSize(), 
+                                                  SemaRef.Context.getSizeType(),
+                                                  /*FIXME:*/E->getLocStart()));
+      AllocType = ConsArrayT->getElementType();
+    } else if (const DependentSizedArrayType *DepArrayT
+                              = dyn_cast<DependentSizedArrayType>(ArrayT)) {
+      if (DepArrayT->getSizeExpr()) {
+        ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr()->Retain());
+        AllocType = DepArrayT->getElementType();
+      }
+    }
+  }
   return getDerived().RebuildCXXNewExpr(E->getLocStart(),
                                         E->isGlobalNew(),
                                         /*FIXME:*/E->getLocStart(),

Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp?rev=91907&r1=91906&r2=91907&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-4.cpp Tue Dec 22 11:13:37 2009
@@ -84,6 +84,20 @@
 template struct New2<X, int, int*>; // expected-note{{instantiation}}
 // FIXME: template struct New2<int, int, float>;
 
+// PR5833
+struct New3 {
+  New3();
+
+  void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}}
+};
+
+template<class C>
+void* object_creator() {
+  return new C(); // expected-error{{call to unavailable function 'operator new[]'}}
+}
+
+template void *object_creator<New3[4]>(); // expected-note{{instantiation}}
+
 template<typename T>
 struct Delete0 {
   void f(T t) {





More information about the cfe-commits mailing list