]> granicus.if.org Git - clang/commitdiff
When transforming a C++ "new" expression that was not explicitly given
authorDouglas Gregor <dgregor@apple.com>
Tue, 22 Dec 2009 17:13:37 +0000 (17:13 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 22 Dec 2009 17:13:37 +0000 (17:13 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91907 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/TreeTransform.h
test/SemaTemplate/instantiate-expr-4.cpp

index 8c84d4a95ac89f4b547f1c638cfe7265d3bd44a1..5152a2975560ce5529645cd5cb5dc6a7a87f9793 100644 (file)
@@ -4481,6 +4481,31 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
       !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(),
index e0042de50e63d4f9386a97a54445d5a43f6ba0a4..99bbbf7a162c0f8229e65d0264453a770287af87 100644 (file)
@@ -84,6 +84,20 @@ template struct New2<X, int, float>;
 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) {