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

Reply via email to