diff options
author | Jason Merrill <jason@redhat.com> | 2020-04-04 11:04:55 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-04-04 11:06:31 -0400 |
commit | f1ad7bac76b662577e3bde78c530954099361a66 (patch) | |
tree | 004cc66d52a4f6c00c0f39cfce25b563cb6a8421 | |
parent | 9f143008c73c60e02634d6b433139a035ef7bb65 (diff) | |
download | gcc-f1ad7bac76b662577e3bde78c530954099361a66.zip gcc-f1ad7bac76b662577e3bde78c530954099361a66.tar.gz gcc-f1ad7bac76b662577e3bde78c530954099361a66.tar.bz2 |
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.
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constraint.cc | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C | 22 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C | 2 |
4 files changed, 33 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f822936..860d5d3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 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 * constexpr.c (maybe_constant_value): Use break_out_target_exprs. * expr.c (mark_use) [VIEW_CONVERT_EXPR]: Don't wrap a TARGET_EXPR in diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 9c21ce8..e530841 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C new file mode 100644 index 0000000..30d2b2d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pmf1.C @@ -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); +} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C index 95698e9..fff414b 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C @@ -15,6 +15,6 @@ template <class X> concept bool C() { } int main() { - static_assert(C<A>()); + static_assert(!C<A>()); return 0; } |