On 12/14/20 1:07 PM, Patrick Palka wrote:
During satisfaction that's entered through the three-parameter version
of satisfy_declaration_constraints, current_function_decl gets set to
the dependent DECL_TEMPLATE_RESULT for sake of access checking. This
makes the predicate in_template_function return true during satisfaction
from this entrypoint, which in turn makes calls to mark_used exit early
before it does its full processing. This leads to us accepting the
invalid testcase below due to mark_used never attempting to deduce the
return type of A::foo() and detecting failure thereof.
It seems wrong for in_template_function to return true during
instantiation or during satisfaction, so this patch strengthens
in_template_function to additionally check current_instantiation().
This seems like it ought to work, but I also wonder about looking at
cfun->decl (which is less volatile) instead of current_function_decl for
in_template_function.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to
commit?
gcc/cp/ChangeLog:
* pt.c (in_template_function): Return false if
current_instantiation() is non-NULL.
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/concepts-requires23.C: New test.
---
gcc/cp/pt.c | 9 +++++----
gcc/testsuite/g++.dg/cpp2a/concepts-requires23.C | 9 +++++++++
2 files changed, 14 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires23.C
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5b13f125002..5f7bc7000c4 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10805,9 +10805,9 @@ uses_template_parms (tree t)
return dependent_p;
}
-/* Returns true iff current_function_decl is an incompletely instantiated
- template. Useful instead of processing_template_decl because the latter
- is set to 0 during instantiate_non_dependent_expr. */
+/* Returns true iff we're processing an incompletely instantiated template.
+ Useful instead of processing_template_decl because the latter is set to
+ 0 during instantiate_non_dependent_expr. */
bool
in_template_function (void)
@@ -10815,7 +10815,8 @@ in_template_function (void)
tree fn = current_function_decl;
bool ret;
++processing_template_decl;
- ret = (fn && DECL_LANG_SPECIFIC (fn)
+ ret = (!current_instantiation ()
+ && fn && DECL_LANG_SPECIFIC (fn)
&& DECL_TEMPLATE_INFO (fn)
&& any_dependent_template_arguments_p (DECL_TI_ARGS (fn)));
--processing_template_decl;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires23.C
b/gcc/testsuite/g++.dg/cpp2a/concepts-requires23.C
new file mode 100644
index 00000000000..e109beaac4f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires23.C
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++20 } }
+
+// Verify f<A>'s associated constraints evaluate to false due
+// to return type deduction failure for A::foo().
+
+template <class T> concept fooable = requires { T::foo(0); };
+template <fooable T> int f ();
+struct A { static auto *foo(auto); };
+int a = f<A>(); // { dg-error "no match" }