Skip to content

Commit

Permalink
[Concepts] Fix incorrect control flow when TryAnnotateTypeConstraint …
Browse files Browse the repository at this point in the history
…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 19fccc5)
  • Loading branch information
saarraz authored and zmodem committed Mar 19, 2020
1 parent a36a14b commit 3562703
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 10 deletions.
6 changes: 4 additions & 2 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -6885,7 +6885,8 @@ class Sema final {
QualType ObjectType, bool EnteringContext,
bool &MemberOfUnknownSpecialization,
SourceLocation TemplateKWLoc = SourceLocation(),
AssumedTemplateKind *ATK = nullptr);
AssumedTemplateKind *ATK = nullptr,
bool Disambiguation = false);

TemplateNameKind isTemplateName(Scope *S,
CXXScopeSpec &SS,
Expand All @@ -6894,7 +6895,8 @@ class Sema final {
ParsedType ObjectType,
bool EnteringContext,
TemplateTy &Template,
bool &MemberOfUnknownSpecialization);
bool &MemberOfUnknownSpecialization,
bool Disambiguation = false);

/// Try to resolve an undeclared template name as a type template.
///
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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()) {
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Parse/ParseTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/Sema/SemaTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions clang/test/SemaCXX/invalid-member-expr.cpp
Original file line number Diff line number Diff line change
@@ -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 {};

Expand Down
5 changes: 3 additions & 2 deletions clang/test/SemaCXX/typo-correction.cpp
Original file line number Diff line number Diff line change
@@ -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'?}}
Expand Down Expand Up @@ -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'?}}
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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>
Expand Down

0 comments on commit 3562703

Please sign in to comment.