On 1/7/21 4:06 PM, Patrick Palka wrote:
This is essentially a followup to r11-3714 -- we ICEing from another
"unguarded" call to build_concept_check, this time in do_auto_deduction,
due to the presence of templated trees when !processing_template_decl.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk and perhaps the 10 branch?
gcc/cp/ChangeLog:
PR c++/98346
* pt.c (do_auto_deduction): Temporarily increment
processing_template_decl before calling build_concept_check.
gcc/testsuite/ChangeLog:
PR c++/98346
* g++.dg/cpp2a/concepts-placeholder3.C: New test.
---
gcc/cp/pt.c | 2 ++
.../g++.dg/cpp2a/concepts-placeholder3.C | 15 +++++++++++++++
2 files changed, 17 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder3.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index beabcc4b027..111a694e0c5 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -29464,7 +29464,9 @@ do_auto_deduction (tree type, tree init, tree auto_node,
cargs = targs;
/* Rebuild the check using the deduced arguments. */
+ ++processing_template_decl;
check = build_concept_check (cdecl, cargs, tf_none);
+ --processing_template_decl;
This shouldn't be necessary; if processing_template_decl is 0, we should
have non-dependent args.
I think your patch only works for this testcase because the concept is
trivial and doesn't actually try to to do anything with the arguments.
Handling of PLACEHOLDER_TYPE_CONSTRAINTS is overly complex, partly
because the 'auto' is represented as an argument in its own constraints.
A constrained auto variable declaration has the same problem.
if (!constraints_satisfied_p (check))
{
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder3.C
b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder3.C
new file mode 100644
index 00000000000..a5d0b1e1d0f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder3.C
@@ -0,0 +1,15 @@
+// PR c++/98346
+// { dg-do compile { target c++20 } }
+
+template <class, class...>
+concept always_satisfied = true;
+
+using arg_alias = int;
+
+template <always_satisfied F>
+using result_of = decltype(F{}(arg_alias{}));
+
+template <class F>
+always_satisfied<result_of<F>> auto foo(F) {}
+
+void bar() { foo(0); }