Commit 19fccc52 authored by Saar Raz's avatar Saar Raz
Browse files

[Concepts] Fix incorrect control flow when TryAnnotateTypeConstraint annotates...

[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).
parent 2a3723ef
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -6986,7 +6986,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,
@@ -6995,7 +6996,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.
  ///
+6 −0
Original line number Diff line number Diff line
@@ -3253,6 +3253,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);
@@ -3406,6 +3409,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()) {
+2 −1
Original line number Diff line number Diff line
@@ -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())
+8 −5
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
// 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 {};

Loading