c++: Check constraints before instantiation from mark_used [PR95132]

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.

gcc/cp/ChangeLog:

	PR c++/95132
	* decl2.c (mark_used): Move up the constraints_satisfied_p check
	so that we check constraints before calling maybe_instantiate_decl.

gcc/testsuite/ChangeLog:

	PR c++/95132
	* g++.dg/cpp2a/concepts-fn7.C: New test.
This commit is contained in:
Patrick Palka 2020-10-28 11:47:26 -04:00
parent 7d5f38e49e
commit 9ccc349576
2 changed files with 21 additions and 10 deletions

View File

@ -5588,16 +5588,6 @@ mark_used (tree decl, tsubst_flags_t complain)
if (DECL_ODR_USED (decl))
return true;
/* 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
such a data member or a call to such function is not value-dependent.
For a function that uses auto in the return type, we need to instantiate
it to find out its type. For OpenMP user defined reductions, we need
them instantiated for reduction clauses which inline them by hand
directly. */
maybe_instantiate_decl (decl);
if (flag_concepts && TREE_CODE (decl) == FUNCTION_DECL
&& !constraints_satisfied_p (decl))
{
@ -5613,6 +5603,16 @@ mark_used (tree decl, tsubst_flags_t complain)
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
such a data member or a call to such function is not value-dependent.
For a function that uses auto in the return type, we need to instantiate
it to find out its type. For OpenMP user defined reductions, we need
them instantiated for reduction clauses which inline them by hand
directly. */
maybe_instantiate_decl (decl);
if (processing_template_decl || in_template_function ())
return true;

View File

@ -0,0 +1,11 @@
// PR c++/95132
// { dg-do compile { target c++20 } }
template <class T> struct A {
static auto f() requires false { return T::fail; }
};
template <class T>
concept C = requires { A<T>::f(); };
static_assert(!C<int>);