[clang] Exclude invalid destructors from lookups.

This fixes a crash when declaring a destructor with a wrong name, then
writing result to pch file and loading it again. The PCH storage uses
DeclarationNameKey as key and it is the same key for both the invalid
destructor and the implicit one that was created because the other one
was invalid. When querying for the Foo::~Foo we end up getting
Foo::~Bar, which is then rejected and we end up with nullptr in
CXXRecordDecl::GetDestructor().

Fixes https://bugs.llvm.org/show_bug.cgi?id=47270

Differential Revision: https://reviews.llvm.org/D86624
This commit is contained in:
Adam Czachorowski 2020-08-26 16:20:01 +02:00
parent 95848ea101
commit eed0af6179
3 changed files with 18 additions and 0 deletions

View File

@ -1487,6 +1487,13 @@ static bool shouldBeHidden(NamedDecl *D) {
if (FD->isFunctionTemplateSpecialization())
return true;
// Hide destructors that are invalid. There should always be one destructor,
// but if it is an invalid decl, another one is created. We need to hide the
// invalid one from places that expect exactly one destructor, like the
// serialization code.
if (isa<CXXDestructorDecl>(D) && D->isInvalidDecl())
return true;
return false;
}

View File

@ -0,0 +1,4 @@
// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t %S/cxx-invalid-destructor.h -fallow-pch-with-compiler-errors
// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t %S/cxx-invalid-destructor.cpp -fsyntax-only -fno-validate-pch
Foo f;

View File

@ -0,0 +1,7 @@
struct Base {
~Base();
};
struct Foo : public Base {
~Base();
};