summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2020-03-17 01:43:29 +0200
committerHans Wennborg <hans@chromium.org>2020-03-19 10:19:04 +0100
commit35627038123b5b391a20e9f4d44a85c7a325027b (patch)
treecba3d96f5eed35283a6c976c59a02289cf9728ef
parenta36a14b70f18b156cea8552fd4b138487340ba76 (diff)
downloadllvm-35627038123b5b391a20e9f4d44a85c7a325027b.tar.gz
[Concepts] Fix incorrect control flow when TryAnnotateTypeConstraint annotates an invalid template-idllvmorg-10.0.0-rc5
TryAnnotateTypeConstraint could annotate a template-id which doesn't end up being a type-constraint, in which case control flow would incorrectly flow into ParseImplicitInt. Reenter the loop in this case. Enable relevant tests for C++20. This required disabling typo-correction during TryAnnotateTypeConstraint and changing a test case which is broken due to a separate bug (will be reported and handled separately). (cherry picked from commit 19fccc52ff2c1da1f93d9317c34769bd9bab8ac8)
-rw-r--r--clang/include/clang/Sema/Sema.h6
-rw-r--r--clang/lib/Parse/ParseDecl.cpp6
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp3
-rwxr-xr-xclang/lib/Sema/SemaTemplate.cpp13
-rw-r--r--clang/test/SemaCXX/invalid-member-expr.cpp1
-rw-r--r--clang/test/SemaCXX/typo-correction.cpp5
-rw-r--r--clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp1
7 files changed, 25 insertions, 10 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 033f7af6f2f3..842e49602274 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6885,7 +6885,8 @@ public:
QualType ObjectType, bool EnteringContext,
bool &MemberOfUnknownSpecialization,
SourceLocation TemplateKWLoc = SourceLocation(),
- AssumedTemplateKind *ATK = nullptr);
+ AssumedTemplateKind *ATK = nullptr,
+ bool Disambiguation = false);
TemplateNameKind isTemplateName(Scope *S,
CXXScopeSpec &SS,
@@ -6894,7 +6895,8 @@ public:
ParsedType ObjectType,
bool EnteringContext,
TemplateTy &Template,
- bool &MemberOfUnknownSpecialization);
+ bool &MemberOfUnknownSpecialization,
+ bool Disambiguation = false);
/// Try to resolve an undeclared template name as a type template.
///
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index cdc3506d5c68..6353e14bc41a 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3252,6 +3252,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
goto DoneWithDeclSpec;
if (isTypeConstraintAnnotation())
continue;
+ if (NextToken().is(tok::annot_template_id))
+ // Might have been annotated by TryAnnotateTypeConstraint.
+ continue;
// Eat the scope spec so the identifier is current.
ConsumeAnnotationToken();
ParsedAttributesWithRange Attrs(AttrFactory);
@@ -3405,6 +3408,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
goto DoneWithDeclSpec;
if (isTypeConstraintAnnotation())
continue;
+ if (Tok.is(tok::annot_template_id))
+ // Might have been annotated by TryAnnotateTypeConstraint.
+ continue;
ParsedAttributesWithRange Attrs(AttrFactory);
if (ParseImplicitInt(DS, nullptr, TemplateInfo, AS, DSContext, Attrs)) {
if (!Attrs.empty()) {
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 3bc4e3596f12..609640576e9e 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -710,7 +710,8 @@ bool Parser::TryAnnotateTypeConstraint() {
/*ObjectType=*/ParsedType(),
/*EnteringContext=*/false,
PossibleConcept,
- MemberOfUnknownSpecialization);
+ MemberOfUnknownSpecialization,
+ /*Disambiguation=*/true);
if (MemberOfUnknownSpecialization || !PossibleConcept ||
TNK != TNK_Concept_template) {
if (SS.isNotEmpty())
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4f577a3cf748..c38c724ed9b0 100755
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -174,7 +174,8 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
ParsedType ObjectTypePtr,
bool EnteringContext,
TemplateTy &TemplateResult,
- bool &MemberOfUnknownSpecialization) {
+ bool &MemberOfUnknownSpecialization,
+ bool Disambiguation) {
assert(getLangOpts().CPlusPlus && "No template names in C!");
DeclarationName TName;
@@ -204,7 +205,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
LookupResult R(*this, TName, Name.getBeginLoc(), LookupOrdinaryName);
if (LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
MemberOfUnknownSpecialization, SourceLocation(),
- &AssumedTemplate))
+ &AssumedTemplate, Disambiguation))
return TNK_Non_template;
if (AssumedTemplate != AssumedTemplateKind::None) {
@@ -371,7 +372,8 @@ bool Sema::LookupTemplateName(LookupResult &Found,
bool EnteringContext,
bool &MemberOfUnknownSpecialization,
SourceLocation TemplateKWLoc,
- AssumedTemplateKind *ATK) {
+ AssumedTemplateKind *ATK,
+ bool Disambiguation) {
if (ATK)
*ATK = AssumedTemplateKind::None;
@@ -494,8 +496,9 @@ bool Sema::LookupTemplateName(LookupResult &Found,
}
}
- if (Found.empty() && !IsDependent) {
- // If we did not find any names, attempt to correct any typos.
+ if (Found.empty() && !IsDependent && !Disambiguation) {
+ // If we did not find any names, and this is not a disambiguation, attempt
+ // to correct any typos.
DeclarationName Name = Found.getLookupName();
Found.clear();
// Simple filter callback that, for keywords, only accepts the C++ *_cast
diff --git a/clang/test/SemaCXX/invalid-member-expr.cpp b/clang/test/SemaCXX/invalid-member-expr.cpp
index 920d92380e69..e0b40794a0ce 100644
--- a/clang/test/SemaCXX/invalid-member-expr.cpp
+++ b/clang/test/SemaCXX/invalid-member-expr.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
class X {};
diff --git a/clang/test/SemaCXX/typo-correction.cpp b/clang/test/SemaCXX/typo-correction.cpp
index 33dea4d36b3e..92a145074e72 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fspell-checking-limit 0 -verify -Wno-c++11-extensions %s
+// RUN: %clang_cc1 -fspell-checking-limit 0 -verify -Wno-c++11-extensions -std=c++20 %s
namespace PR21817{
int a(-rsing[2]); // expected-error {{undeclared identifier 'rsing'; did you mean 'using'?}}
@@ -523,8 +524,8 @@ PR18685::BitVector Map; // expected-error-re {{no type named 'BitVector' in nam
namespace shadowed_template {
template <typename T> class Fizbin {}; // expected-note {{'::shadowed_template::Fizbin' declared here}}
class Baz {
- int Fizbin();
- Fizbin<int> qux; // expected-error {{no template named 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}}
+ int Fizbin;
+ Fizbin<int> qux; // expected-error {{no template named 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}}
};
}
diff --git a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index a41248ee1b8e..cb497176ff0e 100644
--- a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++1y -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++20 -fms-compatibility -fno-spell-checking -fsyntax-only -verify %s
template <class T>