diff options
-rw-r--r-- | lib/Sema/TreeTransform.h | 25 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-expr-4.cpp | 14 |
2 files changed, 39 insertions, 0 deletions
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 8c84d4a95a..5152a29755 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -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(), diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp index e0042de50e..99bbbf7a16 100644 --- a/test/SemaTemplate/instantiate-expr-4.cpp +++ b/test/SemaTemplate/instantiate-expr-4.cpp @@ -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) { |