aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-22 17:13:37 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-22 17:13:37 +0000
commit5b5ad8453c8e79f642c3ddfeeadf162ae67309c0 (patch)
tree3c6a7ffc083fd4f0065a60957c1e25a17f1d5e81
parenta188ff2d8a18140541fcd5884deda4552dac71a7 (diff)
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
-rw-r--r--lib/Sema/TreeTransform.h25
-rw-r--r--test/SemaTemplate/instantiate-expr-4.cpp14
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) {