[cfe-commits] r90156 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/SemaCXX/new-delete.cpp

Anders Carlsson andersca at mac.com
Mon Nov 30 13:24:50 PST 2009


Author: andersca
Date: Mon Nov 30 15:24:50 2009
New Revision: 90156

URL: http://llvm.org/viewvc/llvm-project?rev=90156&view=rev
Log:
When we're trying to define an implicit virtual destructor, make sure that we have a valid delete operator.

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

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=90156&r1=90155&r2=90156&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Nov 30 15:24:50 2009
@@ -443,8 +443,9 @@
 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 "

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=90156&r1=90155&r2=90156&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Nov 30 15:24:50 2009
@@ -2135,7 +2135,7 @@
   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);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=90156&r1=90155&r2=90156&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 30 15:24:50 2009
@@ -2367,9 +2367,9 @@
   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 @@
     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 @@
   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 @@
       }
     }
   }
+  
+  // 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();
 }
 

Modified: cfe/trunk/test/SemaCXX/new-delete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete.cpp?rev=90156&r1=90155&r2=90156&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete.cpp Mon Nov 30 15:24:50 2009
@@ -190,3 +190,15 @@
 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}}
+}





More information about the cfe-commits mailing list