mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 22:51:06 +08:00
c++: Fix invalid pointer-to-member in requires [PR67825]
A recent change to cmcstl2 led to two tests failing due to this bug: our valid expression checking in the context of a requires-expression wasn't catching that an expression of member function type can only appear as the function operand of a call expression. Fixed by using convert_to_void to do the same checking as a discarded-value expression. This patch also fixes 67825, which already had a testcase, but the testcase was testing for the wrong behavior. gcc/cp/ChangeLog 2020-04-04 Jason Merrill <jason@redhat.com> PR c++/67825 * constraint.cc (tsubst_valid_expression_requirement): Call convert_to_void.
This commit is contained in:
parent
9f143008c7
commit
f1ad7bac76
@ -1,3 +1,9 @@
|
||||
2020-04-04 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/67825
|
||||
* constraint.cc (tsubst_valid_expression_requirement): Call
|
||||
convert_to_void.
|
||||
|
||||
2020-04-04 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/94453
|
||||
|
@ -1864,7 +1864,10 @@ hash_placeholder_constraint (tree c)
|
||||
static tree
|
||||
tsubst_valid_expression_requirement (tree t, tree args, subst_info info)
|
||||
{
|
||||
return tsubst_expr (t, args, info.complain, info.in_decl, false);
|
||||
tree r = tsubst_expr (t, args, info.complain, info.in_decl, false);
|
||||
if (convert_to_void (r, ICV_STATEMENT, info.complain) == error_mark_node)
|
||||
return error_mark_node;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
22
gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C
Normal file
22
gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C
Normal file
@ -0,0 +1,22 @@
|
||||
// Make sure that the requirement fails because a .* expression of function
|
||||
// type can only be used in a call.
|
||||
|
||||
// { dg-do compile { target concepts } }
|
||||
|
||||
template<class D, class T>
|
||||
constexpr decltype(auto) invoke(D (T::*pmd), T&& t)
|
||||
noexcept(noexcept(t.*pmd))
|
||||
requires requires { t.*pmd; }
|
||||
{ return t.*pmd; }
|
||||
|
||||
char invoke(...);
|
||||
|
||||
struct A
|
||||
{
|
||||
int f();
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
static_assert(sizeof(invoke (&A::f, A())) == 1);
|
||||
}
|
@ -15,6 +15,6 @@ template <class X> concept bool C() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
static_assert(C<A>());
|
||||
static_assert(!C<A>());
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user