[PATCH] c++: Check constraints before instantiation from mark_used [PR95132]
Patrick Palka
ppalka@redhat.com
Mon Oct 26 21:37:07 GMT 2020
This makes mark_used check constraints of a function _before_ calling
maybe_instantiate_decl, so that we don't try instantiating a function
(as part of return type deduction) with unsatisfied constraints.
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++/95132
* decl2.c (mark_used): Move up the constraints_satisfied_p check
so that it happens before calling maybe_instantiate_decl.
gcc/testsuite/ChangeLog:
PR c++/95132
* g++.dg/cpp2a/concepts-fn7.C: New test.
---
gcc/cp/decl2.c | 30 +++++++++++------------
gcc/testsuite/g++.dg/cpp2a/concepts-fn7.C | 11 +++++++++
2 files changed, 26 insertions(+), 15 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-fn7.C
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 2f0d6370146..de2956aa5f0 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -5604,6 +5604,21 @@ mark_used (tree decl, tsubst_flags_t complain)
if (DECL_ODR_USED (decl))
return true;
+ if (flag_concepts && TREE_CODE (decl) == FUNCTION_DECL
+ && !constraints_satisfied_p (decl))
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error ("use of function %qD with unsatisfied constraints",
+ decl);
+ location_t loc = DECL_SOURCE_LOCATION (decl);
+ inform (loc, "declared here");
+ diagnose_constraints (loc, decl, NULL_TREE);
+ }
+ return false;
+ }
+
/* Normally, we can wait until instantiation-time to synthesize DECL.
However, if DECL is a static data member initialized with a constant
or a constexpr function, we need it right now because a reference to
@@ -5614,21 +5629,6 @@ mark_used (tree decl, tsubst_flags_t complain)
directly. */
maybe_instantiate_decl (decl);
- if (flag_concepts && TREE_CODE (decl) == FUNCTION_DECL
- && !constraints_satisfied_p (decl))
- {
- if (complain & tf_error)
- {
- auto_diagnostic_group d;
- error ("use of function %qD with unsatisfied constraints",
- decl);
- location_t loc = DECL_SOURCE_LOCATION (decl);
- inform (loc, "declared here");
- diagnose_constraints (loc, decl, NULL_TREE);
- }
- return false;
- }
-
if (processing_template_decl || in_template_function ())
return true;
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-fn7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-fn7.C
new file mode 100644
index 00000000000..7fad6f374b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-fn7.C
@@ -0,0 +1,11 @@
+// PR c++/95132
+// { dg-do compile { target c++20 } }
+
+template<typename T> struct A {
+ static auto f() requires false { return T::fail; }
+};
+
+template<typename T>
+constexpr bool v = requires { A<T>::f(); };
+
+static_assert(!v<int>);
--
2.29.0.rc0
More information about the Gcc-patches
mailing list