From: Douglas Gregor Date: Tue, 22 Dec 2009 17:13:37 +0000 (+0000) Subject: When transforming a C++ "new" expression that was not explicitly given X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b5ad8453c8e79f642c3ddfeeadf162ae67309c0;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91907 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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::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(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(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; template struct New2; // expected-note{{instantiation}} // FIXME: template struct New2; +// PR5833 +struct New3 { + New3(); + + void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}} +}; + +template +void* object_creator() { + return new C(); // expected-error{{call to unavailable function 'operator new[]'}} +} + +template void *object_creator(); // expected-note{{instantiation}} + template struct Delete0 { void f(T t) {