kadircet created this revision. kadircet added a reviewer: hokein. Herald added a project: All. kadircet requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
LookupSpecialMember might fail, so changes the cast to cast_or_null. Inside Sema, skip a particular base, similar to other cases, rather than asserting on dtor showing up. Other option would be to mark classes with invalid destructors as invalid, but that seems like a lot more invasive and we do lose lots of diagnostics that currently work on classes with broken members. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D135254 Files: clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaLookup.cpp clang/test/SemaCXX/destructor.cpp Index: clang/test/SemaCXX/destructor.cpp =================================================================== --- clang/test/SemaCXX/destructor.cpp +++ clang/test/SemaCXX/destructor.cpp @@ -550,4 +550,20 @@ template<typename T> void f(T *p) { p->~U(); } // expected-error {{ambiguous}} } +namespace crash_on_invalid_base_dtor { +struct Test { + virtual ~Test(); +}; +struct Baz : public Test { // expected-warning {{non-virtual destructor}} + Baz() {} + ~Baz() = defaul; // expected-error {{undeclared identifier 'defaul'}} \ + // expected-error {{initializer on function}} \ + // expected-note {{overridden virtual function is here}} +}; +struct Foo : public Baz { // expected-error {{cannot override a non-deleted function}} \ + // expected-note {{destructor of 'Foo' is implicitly deleted}} + Foo() {} +}; +} + #endif // BE_THE_HEADER Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -40,6 +40,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/edit_distance.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <iterator> @@ -3616,9 +3617,10 @@ /// /// \returns The destructor for this class. CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) { - return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor, - false, false, false, - false, false).getMethod()); + return llvm::cast_or_null<CXXDestructorDecl>( + LookupSpecialMember(Class, CXXDestructor, false, false, false, false, + false) + .getMethod()); } /// LookupLiteralOperator - Determine which literal operator should be used for Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -5696,7 +5696,9 @@ continue; CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl); - assert(Dtor && "No dtor found for BaseClassDecl!"); + // Dtor might still be missing, e.g because it's invalid. + if (!Dtor) + continue; // FIXME: caret should be on the start of the class name CheckDestructorAccess(Base.getBeginLoc(), Dtor,
Index: clang/test/SemaCXX/destructor.cpp =================================================================== --- clang/test/SemaCXX/destructor.cpp +++ clang/test/SemaCXX/destructor.cpp @@ -550,4 +550,20 @@ template<typename T> void f(T *p) { p->~U(); } // expected-error {{ambiguous}} } +namespace crash_on_invalid_base_dtor { +struct Test { + virtual ~Test(); +}; +struct Baz : public Test { // expected-warning {{non-virtual destructor}} + Baz() {} + ~Baz() = defaul; // expected-error {{undeclared identifier 'defaul'}} \ + // expected-error {{initializer on function}} \ + // expected-note {{overridden virtual function is here}} +}; +struct Foo : public Baz { // expected-error {{cannot override a non-deleted function}} \ + // expected-note {{destructor of 'Foo' is implicitly deleted}} + Foo() {} +}; +} + #endif // BE_THE_HEADER Index: clang/lib/Sema/SemaLookup.cpp =================================================================== --- clang/lib/Sema/SemaLookup.cpp +++ clang/lib/Sema/SemaLookup.cpp @@ -40,6 +40,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/edit_distance.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <iterator> @@ -3616,9 +3617,10 @@ /// /// \returns The destructor for this class. CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) { - return cast<CXXDestructorDecl>(LookupSpecialMember(Class, CXXDestructor, - false, false, false, - false, false).getMethod()); + return llvm::cast_or_null<CXXDestructorDecl>( + LookupSpecialMember(Class, CXXDestructor, false, false, false, false, + false) + .getMethod()); } /// LookupLiteralOperator - Determine which literal operator should be used for Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -5696,7 +5696,9 @@ continue; CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl); - assert(Dtor && "No dtor found for BaseClassDecl!"); + // Dtor might still be missing, e.g because it's invalid. + if (!Dtor) + continue; // FIXME: caret should be on the start of the class name CheckDestructorAccess(Base.getBeginLoc(), Dtor,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits