[clang] 2e48be0 - Fix mishandling of invalid-but-non-empty nested name specifiers in name

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 10 17:55:55 PST 2019


Author: Richard Smith
Date: 2019-12-10T17:55:30-08:00
New Revision: 2e48be09b02e6d01b85d31704d768b6d0c751751

URL: https://github.com/llvm/llvm-project/commit/2e48be09b02e6d01b85d31704d768b6d0c751751
DIFF: https://github.com/llvm/llvm-project/commit/2e48be09b02e6d01b85d31704d768b6d0c751751.diff

LOG: Fix mishandling of invalid-but-non-empty nested name specifiers in name
classification.

We were accidentally treating invalid scope specs as being empty,
resulting in our trying to form an ADL-only call with a qualified
callee, which tripped up an assert later on.

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/Parser/cxx-template-decl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 76bf7b034518..1cf87e45a299 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -867,6 +867,9 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
   LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
   LookupParsedName(Result, S, &SS, !CurMethod);
 
+  if (SS.isInvalid())
+    return NameClassification::Error();
+
   // For unqualified lookup in a class template in MSVC mode, look into
   // dependent base classes where the primary class template is known.
   if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) {
@@ -879,7 +882,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
   // synthesized instance variables), if we're in an Objective-C method.
   // FIXME: This lookup really, really needs to be folded in to the normal
   // unqualified lookup mechanism.
-  if (!SS.isSet() && CurMethod && !isResultTypeOrTemplate(Result, NextToken)) {
+  if (SS.isEmpty() && CurMethod && !isResultTypeOrTemplate(Result, NextToken)) {
     DeclResult Ivar = LookupIvarInObjCMethod(Result, S, Name);
     if (Ivar.isInvalid())
       return NameClassification::Error();
@@ -899,7 +902,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
   case LookupResult::NotFound:
     // If an unqualified-id is followed by a '(', then we have a function
     // call.
-    if (!SS.isSet() && NextToken.is(tok::l_paren)) {
+    if (SS.isEmpty() && NextToken.is(tok::l_paren)) {
       // In C++, this is an ADL-only call.
       // FIXME: Reference?
       if (getLangOpts().CPlusPlus)
@@ -921,7 +924,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
         return NameClassification::NonType(D);
     }
 
-    if (getLangOpts().CPlusPlus2a && !SS.isSet() && NextToken.is(tok::less)) {
+    if (getLangOpts().CPlusPlus2a && SS.isEmpty() && NextToken.is(tok::less)) {
       // In C++20 onwards, this could be an ADL-only call to a function
       // template, and we're required to assume that this is a template name.
       //
@@ -1063,7 +1066,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
        hasAnyAcceptableTemplateNames(
            Result, /*AllowFunctionTemplates=*/true,
            /*AllowDependent=*/false,
-           /*AllowNonTemplateFunctions*/ !SS.isSet() &&
+           /*AllowNonTemplateFunctions*/ SS.isEmpty() &&
                getLangOpts().CPlusPlus2a))) {
     // C++ [temp.names]p3:
     //   After name lookup (3.4) finds that a name is a template-name or that
@@ -1092,7 +1095,7 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
       IsFunctionTemplate = isa<FunctionTemplateDecl>(TD);
       IsVarTemplate = isa<VarTemplateDecl>(TD);
 
-      if (SS.isSet() && !SS.isInvalid())
+      if (SS.isNotEmpty())
         Template =
             Context.getQualifiedTemplateName(SS.getScopeRep(),
                                              /*TemplateKeyword=*/false, TD);

diff  --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp
index 07316782a830..cb8a93fdecb1 100644
--- a/clang/test/Parser/cxx-template-decl.cpp
+++ b/clang/test/Parser/cxx-template-decl.cpp
@@ -261,3 +261,11 @@ namespace PR42071 {
   template<int Q::N> struct C; // expected-error {{parameter declarator cannot be qualified}}
   template<int f(int a = 0)> struct D; // expected-error {{default arguments can only be specified for parameters in a function declaration}}
 }
+
+namespace AnnotateAfterInvalidTemplateId {
+  template<int I, int J> struct A { };
+  template<int J> struct A<0, J> { }; // expected-note {{J = 0}}
+  template<int I> struct A<I, 0> { }; // expected-note {{I = 0}}
+
+  void f() { A<0, 0>::f(); } // expected-error {{ambiguous partial specializations}}
+}


        


More information about the cfe-commits mailing list