c++: PMF template parm and noexcept [PR90664]

The constexpr code only wants to preserve PTRMEM_CST in conversions if the
conversions are only qualification conversions; dropping noexcept counts as
a qualification adjustment in overload resolution, so let's include it here.

gcc/cp/ChangeLog:

	PR c++/90664
	* cvt.c (can_convert_qual): Check fnptr_conv_p.

gcc/testsuite/ChangeLog:

	PR c++/90664
	* g++.dg/cpp1z/noexcept-type24.C: New test.
This commit is contained in:
Jason Merrill 2021-04-02 17:07:12 -04:00
parent 23be03a0f2
commit 7c3ba2145c
2 changed files with 27 additions and 0 deletions

View File

@ -2013,6 +2013,11 @@ can_convert_qual (tree type, tree expr)
tree expr_type = TREE_TYPE (expr);
gcc_assert (!same_type_p (type, expr_type));
/* A function pointer conversion also counts as a Qualification Adjustment
under [over.ics.scs]. */
if (fnptr_conv_p (type, expr_type))
return true;
if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type))
return comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type));
else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (expr_type))

View File

@ -0,0 +1,22 @@
// PR c++/90664
// { dg-do compile { target c++11 } }
template <typename TT, typename MFP, MFP> struct OpM;
template <typename TR, typename TT, TR (TT::*f)()>
struct OpM<TT, TR (TT::*)(), f>
{};
class Class {
public:
int address() noexcept { return 0; }
void address(int) noexcept {}
};
struct Sk {
template <class C, typename R> Sk(R (C::*p)()) {
typedef OpM<C, R (C::*)() /* noexcept */, &Class::address> OP;
}
};
Sk sk(static_cast<int (Class::*)()>(&Class::address));