shafik created this revision. shafik added reviewers: rsmith, aaron.ballman, erichkeane. Herald added a project: All. shafik requested review of this revision.
Currently in `Sema::getDestructorName` we call `SS.getScopeRep()->getPrefix()` but `SS.getScopeRep()` can return `nullptr` because `LookupInNestedNameSpec(...)` called a little before can invalidate `SS`. This fixes: https://github.com/llvm/llvm-project/issues/59446 https://reviews.llvm.org/D140598 Files: clang/lib/Sema/SemaExprCXX.cpp clang/test/SemaCXX/GH59446.cpp Index: clang/test/SemaCXX/GH59446.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/GH59446.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +namespace GH59446 { // expected-note {{to match this '{'}} +namespace N { + template <typename T> struct X ; // expected-note 2 {{template is declared here}} + // expected-note@-1 {{'N::X' declared here}} + // expected-note@-2 {{non-type declaration found by destructor name lookup}} + } + void f(X<int> *x) { // expected-error {{no template named 'X'; did you mean 'N::X'}} + x->N::X<int>::~X(); // expected-error 2 {{implicit instantiation of undefined template 'GH59446::N::X<int>'}} + // expected-error@-1 {{identifier 'X' after '~' in destructor name does not name a type}} +} // expected-error {{expected '}'}} Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -390,7 +390,7 @@ // // also looks for type-name in the scope. Unfortunately, we can't // reasonably apply this fallback for dependent nested-name-specifiers. - if (SS.getScopeRep()->getPrefix()) { + if (SS.isSet() && SS.getScopeRep()->getPrefix()) { if (ParsedType T = LookupInScope()) { Diag(SS.getEndLoc(), diag::ext_qualified_dtor_named_in_lexical_scope) << FixItHint::CreateRemoval(SS.getRange());
Index: clang/test/SemaCXX/GH59446.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/GH59446.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +namespace GH59446 { // expected-note {{to match this '{'}} +namespace N { + template <typename T> struct X ; // expected-note 2 {{template is declared here}} + // expected-note@-1 {{'N::X' declared here}} + // expected-note@-2 {{non-type declaration found by destructor name lookup}} + } + void f(X<int> *x) { // expected-error {{no template named 'X'; did you mean 'N::X'}} + x->N::X<int>::~X(); // expected-error 2 {{implicit instantiation of undefined template 'GH59446::N::X<int>'}} + // expected-error@-1 {{identifier 'X' after '~' in destructor name does not name a type}} +} // expected-error {{expected '}'}} Index: clang/lib/Sema/SemaExprCXX.cpp =================================================================== --- clang/lib/Sema/SemaExprCXX.cpp +++ clang/lib/Sema/SemaExprCXX.cpp @@ -390,7 +390,7 @@ // // also looks for type-name in the scope. Unfortunately, we can't // reasonably apply this fallback for dependent nested-name-specifiers. - if (SS.getScopeRep()->getPrefix()) { + if (SS.isSet() && SS.getScopeRep()->getPrefix()) { if (ParsedType T = LookupInScope()) { Diag(SS.getEndLoc(), diag::ext_qualified_dtor_named_in_lexical_scope) << FixItHint::CreateRemoval(SS.getRange());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits