]> granicus.if.org Git - clang/commitdiff
When we're trying to define an implicit virtual destructor, make sure that we have...
authorAnders Carlsson <andersca@mac.com>
Mon, 30 Nov 2009 21:24:50 +0000 (21:24 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 30 Nov 2009 21:24:50 +0000 (21:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90156 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/new-delete.cpp

index fed2cffc0dbe675fe1ead8f3069a2f1f75ae2c1b..c55d0bef3f6df4b4c2cdd74eb9eb4633ee7096dc 100644 (file)
@@ -443,8 +443,9 @@ def err_implicit_object_parameter_init : Error<
 def note_field_decl : Note<"member is declared here">;
 def note_previous_class_decl : Note<
   "%0 declared here">;
-def note_ctor_synthesized_at : Note<
-  "implicit default constructor for %0 first required here">;
+def note_member_synthesized_at : Note<
+  "implicit default %select{constructor|copy constructor|"
+  "copy assignment operator|destructor}0 for %1 first required here">;
 def err_missing_default_ctor : Error<
   "%select{|implicit default }0constructor for %1 must explicitly initialize "
   "the %select{base class|member}2 %3 which does not have a default "
index 5577cbd7d744a31c88ca180273bd66b4ead5bcba..232b502bf9c3c5b5cd5a16313b94b3f2688f4500 100644 (file)
@@ -2135,7 +2135,7 @@ public:
   void CheckConstructor(CXXConstructorDecl *Constructor);
   QualType CheckDestructorDeclarator(Declarator &D,
                                      FunctionDecl::StorageClass& SC);
-  void CheckDestructor(CXXDestructorDecl *Destructor);
+  bool CheckDestructor(CXXDestructorDecl *Destructor);
   void CheckConversionDeclarator(Declarator &D, QualType &R,
                                  FunctionDecl::StorageClass& SC);
   DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
index 34ab74295888a501f266159d90d62a76bab3f258..f161cb5546a2abf699622aab7bcd29eb5bcd593c 100644 (file)
@@ -2367,9 +2367,9 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
   ClassDecl->addedConstructor(Context, Constructor);
 }
 
-/// CheckDestructor - Checks a fully-formed destructor for
-/// well-formedness, issuing any diagnostics required. 
-void Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
+/// CheckDestructor - Checks a fully-formed destructor for well-formedness, 
+/// issuing any diagnostics required. Returns true on error.
+bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
   CXXRecordDecl *RD = Destructor->getParent();
   
   if (Destructor->isVirtual()) {
@@ -2384,9 +2384,13 @@ void Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
     FunctionDecl *OperatorDelete = 0;
     DeclarationName Name = 
     Context.DeclarationNames.getCXXOperatorName(OO_Delete);
-    if (!FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
-      Destructor->setOperatorDelete(OperatorDelete);
+    if (FindDeallocationFunction(Loc, RD, Name, OperatorDelete))
+      return true;
+    
+    Destructor->setOperatorDelete(OperatorDelete);
   }
+  
+  return false;
 }
 
 static inline bool
@@ -3071,8 +3075,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
   assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
 
   if (SetBaseOrMemberInitializers(Constructor, 0, 0, true)) {
-    Diag(CurrentLocation, diag::note_ctor_synthesized_at)
-      << Context.getTagDeclType(ClassDecl);
+    Diag(CurrentLocation, diag::note_member_synthesized_at) 
+      << CXXDefaultConstructor << Context.getTagDeclType(ClassDecl);
     Constructor->setInvalidDecl();
   } else {
     Constructor->setUsed();
@@ -3124,6 +3128,17 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
       }
     }
   }
+  
+  // FIXME: If CheckDestructor fails, we should emit a note about where the
+  // implicit destructor was needed.
+  if (CheckDestructor(Destructor)) {
+    Diag(CurrentLocation, diag::note_member_synthesized_at) 
+      << CXXDestructor << Context.getTagDeclType(ClassDecl);
+
+    Destructor->setInvalidDecl();
+    return;
+  }
+
   Destructor->setUsed();
 }
 
index ededfc0900def9541684591ee5d29e03137aecde..f2fe0a78e388ac772a2391ebbb609245d0c68ce8 100644 (file)
@@ -190,3 +190,15 @@ class X9 {
 void f(X9 *x9) {
   delete x9; // expected-error {{no suitable member 'operator delete' in 'X9'}}
 }
+
+struct X10 {
+  virtual ~X10();
+};
+
+struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in 'X11'}}
+  void operator delete(void*, int); // expected-note {{'operator delete' declared here}}
+};
+
+void f() {
+  X11 x11; // expected-note {{implicit default destructor for 'struct X11' first required here}}
+}