On 1/15/21 11:37 AM, Patrick Palka wrote:
On Mon, 11 Jan 2021, Jason Merrill wrote:
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.
D'oh, good point.. We need to also substitute the template arguments of
the current instantiation into the constraint at some point. This is
actually PR96443 / PR96444, which I reported and posted a patch for back
in August: https://gcc.gnu.org/pipermail/gcc-patches/2020-August/551375.html
The approach the August patch used was to substitute into the
PLACEHOLDER_TYPE_CONSTRAINTS during tsubst, which was ruled out. We can
instead do the same substitution during do_auto_deduction, as in the
patch below. Does this approach look better? It seems consistent with
how type_deducible_p substitutes into the return-type-requirement of a
compound-requirement.
Alternatively we could not substitute into PLACEHOLDER_TYPE_CONSTRAINTS
at all and instead pass the targs of the enclosing function directly
into satisfaction, but that seems inconsistent with type_deducible_p.
That sounds better.
I think type_deducible_p is wrong; 7.5.7.3-4 make it clear that this
should work the same as other satisfaction.
-- >8 --
Subject: [PATCH] c++: dependent constraint on placeholder return type
[PR96443]
We're never substituting the template arguments of the enclosing
function into the constraint of a placeholder variable or return type,
which leads to errors during satisfaction when the constraint is
dependent. This patch fixes this issue by doing the appropriate
substitution in do_auto_deduction before checking satisfaction.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK
for trunk? Also tested on cmcstl2 and range-v3.
gcc/cp/ChangeLog:
PR c++/96443
* pt.c (do_auto_deduction): Try checking the placeholder
constraint template parse time. Substitute the template
arguments of the containing function into the placeholder
constraint. If the constraint is still dependent, defer
deduction until instantiation time.
gcc/testsuite/ChangeLog:
PR c++/96443
* g++.dg/concepts/concepts-ts1.C: Add dg-bogus directive to the
call to f15 that we expect to accept.
* g++.dg/cpp2a/concepts-placeholder3.C: New test.
---
gcc/cp/pt.c | 19 ++++++++++++++++++-
.../g++.dg/cpp2a/concepts-placeholder3.C | 16 ++++++++++++++++
gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C | 2 +-
3 files changed, 35 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-placeholder3.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c6b7318b378..b70a9a451e1 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -29455,7 +29455,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
}
/* Check any placeholder constraints against the deduced type. */
- if (flag_concepts && !processing_template_decl)
+ if (flag_concepts)
if (tree check = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (auto_node)))
{
/* Use the deduced type to check the associated constraints. If we
@@ -29475,6 +29475,23 @@ do_auto_deduction (tree type, tree init, tree
auto_node,
else
cargs = targs;
+ if ((context == adc_return_type || context == adc_variable_type)
+ && current_function_decl
+ && DECL_TEMPLATE_INFO (current_function_decl))
+ {
+ /* Substitute the template arguments of the enclosing function. */
+ cargs = tsubst_template_args (cargs,
+ DECL_TI_ARGS (current_function_decl),
+ complain, current_function_decl);
+ if (cargs == error_mark_node)
+ return error_mark_node;
+ }
+
+ if (any_dependent_template_arguments_p (cargs))
+ /* The constraint is dependent, so we can't complete the type
+ deduction ahead of time. */
+ return type;
+
/* Rebuild the check using the deduced arguments. */
check = build_concept_check (cdecl, cargs, tf_none);
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..abf5930e902
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder3.C
@@ -0,0 +1,16 @@
+// PR c++/96443
+// { dg-do compile { target c++20 } }
+
+template <class T, class U> concept same_as = __is_same(T, U);
+
+auto f(auto x) -> same_as<decltype(x)> auto { return 0; }; // { dg-error
"constraints" }
+void g(auto x) { same_as<decltype(x)> auto y = 0; } // { dg-error
"constraints" }
+auto h(auto x) -> same_as<decltype(x.missing)> auto { return 0; } // { dg-error
"missing" }
+
+int main() {
+ f(0); // { dg-bogus "" }
+ f(true); // { dg-message "required from here" }
+ g(0); // { dg-bogus "" }
+ g(true); // { dg-message "required from here" }
+ h(0); // { dg-message "required from here" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
b/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
index 1cefe3b243f..a116cac4ea4 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C
@@ -40,7 +40,7 @@ void driver()
f3('a'); // { dg-error "" }
f4(0, 0);
f4(0, 'a'); // { dg-error "" }
- f15(0);
+ f15(0); // { dg-bogus "" }
f15('a'); // { dg-message "" }
}