]> granicus.if.org Git - clang/commitdiff
When we decide not to rebuild an instantiated C++ 'new' expression
authorDouglas Gregor <dgregor@apple.com>
Tue, 26 Jul 2011 15:11:03 +0000 (15:11 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 26 Jul 2011 15:11:03 +0000 (15:11 +0000)
that allocates an array of objects with a non-trivial destructor, be
sure to mark the destructor is "used". Fixes PR10480 /
<rdar://problem/9834317>.

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

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

index c75665bfc010bd5a90a7095c7964409c8fda472c..2221fc0c2117617ca2103abd6bdaff8023558416 100644 (file)
@@ -6902,6 +6902,19 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
       SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorNew);
     if (OperatorDelete)
       SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete);
+    
+    if (E->isArray() && Constructor && 
+        !E->getAllocatedType()->isDependentType()) {
+      QualType ElementType
+        = SemaRef.Context.getBaseElementType(E->getAllocatedType());
+      if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
+        CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
+        if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
+          SemaRef.MarkDeclarationReferenced(E->getLocStart(), Destructor);
+        }
+      }
+    }
+    
     return SemaRef.Owned(E);
   }
 
index 521d2180d7ab9013dd1bbca7c7ac81499e92224b..9483f9b2836613771c51e90fc6b6d4e5c0352afa 100644 (file)
@@ -135,6 +135,23 @@ namespace PR5755 {
   }
 }
 
+namespace PR10480 {
+  template<typename T>
+  struct X {
+    X();
+    ~X() {
+      T *ptr = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+    }
+  };
+
+  template<typename T>
+  void f() {
+    new X<int>[1]; // expected-note{{in instantiation of member function 'PR10480::X<int>::~X' requested here}}
+  }
+
+  template void f<int>();
+}
+
 // ---------------------------------------------------------------------
 // throw expressions
 // ---------------------------------------------------------------------