diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8229368eb98..860d5d36cf6f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-04-04 Jason Merrill + + PR c++/67825 + * constraint.cc (tsubst_valid_expression_requirement): Call + convert_to_void. + 2020-04-04 Jason Merrill PR c++/94453 diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index 9c21ce80256d..e53084148798 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 000000000000..30d2b2d4a485 --- /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 +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 95698e99978a..fff414b8eb24 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C @@ -15,6 +15,6 @@ template concept bool C() { } int main() { - static_assert(C()); + static_assert(!C()); return 0; }