diff options
author | Saar Raz <saar@raz.email> | 2020-03-17 01:43:29 +0200 |
---|---|---|
committer | Hans Wennborg <hans@chromium.org> | 2020-03-19 10:19:04 +0100 |
commit | 35627038123b5b391a20e9f4d44a85c7a325027b (patch) | |
tree | cba3d96f5eed35283a6c976c59a02289cf9728ef | |
parent | a36a14b70f18b156cea8552fd4b138487340ba76 (diff) | |
download | llvm-35627038123b5b391a20e9f4d44a85c7a325027b.zip llvm-35627038123b5b391a20e9f4d44a85c7a325027b.tar.gz llvm-35627038123b5b391a20e9f4d44a85c7a325027b.tar.bz2 |
[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.h | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 3 | ||||
-rwxr-xr-x | clang/lib/Sema/SemaTemplate.cpp | 13 | ||||
-rw-r--r-- | clang/test/SemaCXX/invalid-member-expr.cpp | 1 | ||||
-rw-r--r-- | clang/test/SemaCXX/typo-correction.cpp | 5 | ||||
-rw-r--r-- | clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp | 1 |
7 files changed, 25 insertions, 10 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 033f7af..842e496 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 cdc3506..6353e14 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 3bc4e35..6096405 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 4f577a3..c38c724e 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 920d923..e0b4079 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 33dea4d..92a1450 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 a41248e..cb49717 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> |