On 10/5/20 4:30 PM, Patrick Palka wrote:
On Wed, 30 Sep 2020, Jason Merrill wrote:

On 9/29/20 5:01 PM, Patrick Palka wrote:
This patch fixes an "unguarded" call to coerce_template_parms in
build_standard_check: processing_template_decl could be zero if we
we get here during processing of the first 'auto' parameter of an
abbreviated function template.  In the testcase below, this leads to an
ICE when coerce_template_parms substitutes into C's dependent default
template argument.

Bootstrapped and regtested on x86_64-pc-linux-gnu and tested by building
cmcstl2 and range-v3.  Does this look OK for trunk?

This looks OK, but is there a place higher in the call stack where we should
have already set processing_template_decl?

The call stack at that point is:

   build_variable_check
   build_concept_check
   build_type_constraint
   finish_type_constraints
   cp_parser_placeholder_type_specifier
   cp_parser_simple_type_specifier
   ...

So it seems the most natural place to set processing_template_decl would
be in build_type_constraint, around the call to build_concept_check,
since that's where we create the WILDCARD_DECL that eventually reaches
coerce_template_parms.

And in order to additionally avoid a similar ICE when processing the
type constraint of a non-templated variable, we also need to guard the
call to build_concept check in make_constrained_placeholder_type.  The
testcase below now contains such an example.

Setting the flag in cp_parser_placeholder_type_specifier would cover both of those, right?

So something like this perhaps:

-- >8 --

Subject: [PATCH] c++: ICE in dependent_type_p with constrained auto [PR97052]

This patch fixes an "unguarded" call to coerce_template_parms in
build_standard_check: processing_template_decl could be zero if we
get here during processing of the first 'auto' parameter of an
abbreviated function template, or if we're processing the type
constraint of a non-templated variable.  In the testcase below, this
leads to an ICE when coerce_template_parms instantiates C's dependent
default template argument.

gcc/cp/ChangeLog:

        PR c++/97052
        * constraint.cc (build_type_constraint): Temporarily increment
        processing_template_decl before calling build_concept_check.
        * pt.c (make_constrained_placeholder_type): Likewise.

gcc/testsuite/ChangeLog:

        PR c++/97052
        * g++.dg/cpp2a/concepts-defarg2: New test.
---
  gcc/cp/constraint.cc                          |  2 ++
  gcc/cp/pt.c                                   |  2 ++
  gcc/testsuite/g++.dg/cpp2a/concepts-defarg2.C | 13 +++++++++++++
  3 files changed, 17 insertions(+)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-defarg2.C

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index d49957a6c4a..050b55ce092 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1427,7 +1427,9 @@ tree
  build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
  {
    tree wildcard = build_nt (WILDCARD_DECL);
+  ++processing_template_decl;
    tree check = build_concept_check (decl, wildcard, args, complain);
+  --processing_template_decl;
    if (check == error_mark_node)
      return error_mark_node;
    return unpack_concept_check (check);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 72efecff37f..efdd017a4d5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -27914,7 +27914,9 @@ make_constrained_placeholder_type (tree type, tree con, 
tree args)
    tree expr = tmpl;
    if (TREE_CODE (con) == FUNCTION_DECL)
      expr = ovl_make (tmpl);
+  ++processing_template_decl;
    expr = build_concept_check (expr, type, args, tf_warning_or_error);
+  --processing_template_decl;
PLACEHOLDER_TYPE_CONSTRAINTS (type) = expr; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-defarg2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-defarg2.C
new file mode 100644
index 00000000000..a63ca4e133d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-defarg2.C
@@ -0,0 +1,13 @@
+// PR c++/97052
+// { dg-do compile { target c++20 } }
+
+template<typename T, typename U = typename T::type>
+concept C = true;
+
+constexpr bool f(C auto) {
+  return true;
+}
+
+static_assert(f(0));
+
+C auto x = 0;


Reply via email to