diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 29 | ||||
-rw-r--r-- | clang/test/SemaCXX/new-delete.cpp | 12 |
4 files changed, 38 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fed2cffc0db..c55d0bef3f6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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 " diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 5577cbd7d74..232b502bf9c 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 34ab7429588..f161cb5546a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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(); } diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index ededfc0900d..f2fe0a78e38 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -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}} +} |