summaryrefslogtreecommitdiffstats
path: root/clang/lib
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 /clang/lib
parenta36a14b70f18b156cea8552fd4b138487340ba76 (diff)
downloadbcm5719-llvm-35627038123b5b391a20e9f4d44a85c7a325027b.tar.gz
bcm5719-llvm-35627038123b5b391a20e9f4d44a85c7a325027b.zip
[Concepts] Fix incorrect control flow when TryAnnotateTypeConstraint annotates an invalid template-id
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)
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp6
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp3
-rwxr-xr-xclang/lib/Sema/SemaTemplate.cpp13
3 files changed, 16 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index cdc3506d5c6..6353e14bc41 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 3bc4e3596f1..609640576e9 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 4f577a3cf74..c38c724ed9b 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
OpenPOWER on IntegriCloud