On Thu, 8 Apr 2021, Marek Polacek via Gcc-patches wrote:

> When we have a member function with auto parameter like this:
> 
>   struct S {
>     void f(auto);
>   };
> 
> cp_parser_member_declaration -> grokfield produces a FUNCTION_DECL
> "void S::foo(auto:1)", and then finish_fully_implicit_template turns
> that FUNCTION_DECL into a TEMPLATE_DECL.  The bug here is that we only
> call cp_parser_save_default_args for a FUNCTION_DECL.  As a consequence,
> abbrev10.C is rejected because we complain that the default argument has
> not been defined, and abbrev11.C ICEs, because we don't re-parse the
> delayed noexcept, so the DEFERRED_PARSE tree leaks into tsubst* where we
> crash.  This patch fixes both issues.
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/10.4?
> 
> gcc/cp/ChangeLog:
> 
>       PR c++/99806
>       * parser.c (cp_parser_member_declaration): Call
>       cp_parser_save_default_args even for function templates.
>       (cp_parser_save_default_args): Extract the function declaration
>       from a function template.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR c++/99806
>       * g++.dg/concepts/abbrev10.C: New test.
>       * g++.dg/concepts/abbrev11.C: New test.
> ---
>  gcc/cp/parser.c                          |  8 +++++---
>  gcc/testsuite/g++.dg/concepts/abbrev10.C | 18 ++++++++++++++++++
>  gcc/testsuite/g++.dg/concepts/abbrev11.C | 10 ++++++++++
>  3 files changed, 33 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev10.C
>  create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev11.C
> 
> diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
> index 59adac4492a..eef6bb3003e 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -26433,7 +26433,8 @@ cp_parser_member_declaration (cp_parser* parser)
>                 || !DECL_DECLARES_FUNCTION_P (decl))
>               finish_member_declaration (decl);
>  
> -           if (TREE_CODE (decl) == FUNCTION_DECL)
> +           if (TREE_CODE (decl) == FUNCTION_DECL
> +               || DECL_FUNCTION_TEMPLATE_P (decl))

I guess you could use DECL_DECLARES_FUNCTION_P here.

>               cp_parser_save_default_args (parser, decl);
>             else if (TREE_CODE (decl) == FIELD_DECL
>                      && DECL_INITIAL (decl))
> @@ -30959,9 +30960,10 @@ cp_parser_late_parsing_for_member (cp_parser* 
> parser, tree member_function)
>  static void
>  cp_parser_save_default_args (cp_parser* parser, tree decl)
>  {
> -  tree probe;
> +  if (DECL_FUNCTION_TEMPLATE_P (decl))
> +    decl = DECL_TEMPLATE_RESULT (decl);

Not sure if it'd be an improvement, but could use STRIP_TEMPLATE here
instead (or perhaps on the caller side).

>  
> -  for (probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
> +  for (tree probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
>         probe;
>         probe = TREE_CHAIN (probe))
>      if (TREE_PURPOSE (probe))
> diff --git a/gcc/testsuite/g++.dg/concepts/abbrev10.C 
> b/gcc/testsuite/g++.dg/concepts/abbrev10.C
> new file mode 100644
> index 00000000000..b611346e926
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/abbrev10.C
> @@ -0,0 +1,18 @@
> +// PR c++/99806
> +// { dg-do compile { target c++14 } }
> +// { dg-additional-options "-fconcepts" }
> +
> +struct S {
> +  void f(auto, auto, int = 3);
> +  void f2(auto, auto, int = 3) { }
> +  template<typename T> static T g(T, auto, int = 3);
> +};
> +
> +void
> +g ()
> +{
> +  S::g(1, 2);
> +  S s;
> +  s.f(1, 2);
> +  s.f2(1, 2);
> +}
> diff --git a/gcc/testsuite/g++.dg/concepts/abbrev11.C 
> b/gcc/testsuite/g++.dg/concepts/abbrev11.C
> new file mode 100644
> index 00000000000..ddb479313df
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/abbrev11.C
> @@ -0,0 +1,10 @@
> +// PR c++/99806
> +// { dg-do compile { target c++14 } }
> +// { dg-additional-options "-fconcepts" }
> +
> +template <typename T> concept C = requires (T a) { a.f(0); };
> +struct S {
> +  void f(auto) noexcept(B);
> +  static constexpr bool B = true;
> +};
> +static_assert(C<S>, "");
> 
> base-commit: 123b3e03c911a43054c1f88f5d3110e1d084dd4e
> -- 
> 2.30.2
> 
> 

Reply via email to