summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2019-12-10 17:53:15 -0800
committerRichard Smith <richard@metafoo.co.uk>2019-12-10 17:55:30 -0800
commit2e48be09b02e6d01b85d31704d768b6d0c751751 (patch)
treef770b0e1d7af2fca397c2eba6db1a1f78a9f488c /clang
parent4d53b99c5df2c83172d23521d1b1ab8361d6de92 (diff)
downloadbcm5719-llvm-2e48be09b02e6d01b85d31704d768b6d0c751751.tar.gz
bcm5719-llvm-2e48be09b02e6d01b85d31704d768b6d0c751751.zip
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.
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp13
-rw-r--r--clang/test/Parser/cxx-template-decl.cpp8
2 files changed, 16 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 76bf7b03451..1cf87e45a29 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 @@ Corrected:
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 @@ Corrected:
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 @@ Corrected:
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 @@ Corrected:
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 07316782a83..cb8a93fdecb 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}}
+}
OpenPOWER on IntegriCloud