[clang] b7ce85a - [Concepts] Fix isDeclarationSpecifier to detect type-constraints correctly

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 31 10:21:03 PST 2020


On Fri, 31 Jan 2020, 10:08 Saar Raz via cfe-commits, <
cfe-commits at lists.llvm.org> wrote:

>
> Author: Saar Raz
> Date: 2020-01-31T20:08:13+02:00
> New Revision: b7ce85a130789d23c69156f4b899962458d1f05d
>
> URL:
> https://github.com/llvm/llvm-project/commit/b7ce85a130789d23c69156f4b899962458d1f05d
> DIFF:
> https://github.com/llvm/llvm-project/commit/b7ce85a130789d23c69156f4b899962458d1f05d.diff
>
> LOG: [Concepts] Fix isDeclarationSpecifier to detect type-constraints
> correctly
>
> isDeclarationSpecifiers did not handle some cases of
> placeholder-type-specifiers with
> type-constraints, causing parsing bugs in abbreviated constructor
> templates.
>
> Add comprehensive handling of type-constraints to isDeclarationSpecifier.
>
> Added:
>
>
> Modified:
>     clang/lib/Parse/ParseDecl.cpp
>     clang/test/Parser/cxx2a-abbreviated-templates.cpp
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
> index 871ca2512598..af6e105ca61f 100644
> --- a/clang/lib/Parse/ParseDecl.cpp
> +++ b/clang/lib/Parse/ParseDecl.cpp
> @@ -5061,6 +5061,8 @@ bool Parser::isDeclarationSpecifier(bool
> DisambiguatingWithExpression) {
>      // recurse to handle whatever we get.
>      if (TryAnnotateTypeOrScopeToken())
>        return true;
> +    if (TryAnnotateTypeConstraint())
> +      return true;
>      if (Tok.is(tok::identifier))
>        return false;
>
> @@ -5193,11 +5195,14 @@ bool Parser::isDeclarationSpecifier(bool
> DisambiguatingWithExpression) {
>
>      // placeholder-type-specifier
>    case tok::annot_template_id: {
> -    TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
> -    return TemplateId->Kind == TNK_Concept_template &&
> +    return isTypeConstraintAnnotation() &&
>          (NextToken().is(tok::kw_auto) ||
> NextToken().is(tok::kw_decltype));
>    }
> -
> +  case tok::annot_cxxscope:
> +    if (NextToken().is(tok::identifier) && TryAnnotateTypeConstraint())
> +      return true;
>

Our behaviour here (on invalid code) depends on whether we've already
annotated the type constraint (if not, we don't require the next token to
be auto/decltype). It'd be good to be consistent here.

Incidentally, if we see any kind of (possibly-qualified) identifier or
template-id followed by auto/decltype, I think we should classify it as a
decl-specifier to improve error recovery when there's a typo in a concept
name.

+    return isTypeConstraintAnnotation() &&
> +        GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype);
>    case tok::kw___declspec:
>    case tok::kw___cdecl:
>    case tok::kw___stdcall:
>
> diff  --git a/clang/test/Parser/cxx2a-abbreviated-templates.cpp
> b/clang/test/Parser/cxx2a-abbreviated-templates.cpp
> index e2b3803c807e..6562389f7676 100644
> --- a/clang/test/Parser/cxx2a-abbreviated-templates.cpp
> +++ b/clang/test/Parser/cxx2a-abbreviated-templates.cpp
> @@ -9,11 +9,36 @@ namespace ns {
>    concept D = true;
>  }
>
> -void foo(C auto a,
> -         C<int> auto b,
> -         ns::D auto c,
> -         ns::D<int> auto d,
> -         const C auto e,
> -         const C<int> auto f,
> -         const ns::D auto g,
> -         const ns::D<int> auto h);
> \ No newline at end of file
> +void foo1(C auto a,
> +          C<int> auto b,
> +          ns::D auto c,
> +          ns::D<int> auto d,
> +          const C auto e,
> +          const C<int> auto f,
> +          const ns::D auto g,
> +          const ns::D<int> auto h);
> +void foo2(C auto a);
> +void foo3(C<int> auto b);
> +void foo4(ns::D auto c);
> +void foo5(ns::D<int> auto d);
> +void foo6(const C auto e);
> +void foo7(const C<int> auto f);
> +void foo8(const ns::D auto g);
> +void foo9(const ns::D<int> auto h);
> +
> +struct S1 { S1(C auto a,
> +               C<int> auto b,
> +               ns::D auto c,
> +               ns::D<int> auto d,
> +               const C auto e,
> +               const C<int> auto f,
> +               const ns::D auto g,
> +               const ns::D<int> auto h); };
> +struct S2 { S2(C auto a); };
> +struct S3 { S3(C<int> auto b); };
> +struct S4 { S4(ns::D auto c); };
> +struct S5 { S5(ns::D<int> auto d); };
> +struct S6 { S6(const C auto e); };
> +struct S7 { S7(const C<int> auto f); };
> +struct S8 { S8(const ns::D auto g); };
> +struct S9 { S9(const ns::D<int> auto h); };
> \ No newline at end of file
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200131/4429fc45/attachment.html>


More information about the cfe-commits mailing list