diff options
author | Jason Merrill <jason@redhat.com> | 2021-04-02 17:07:12 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-05-13 13:39:30 -0400 |
commit | 45fb36bf93a7cc6506c2a12f9c4aa3981f4e6b44 (patch) | |
tree | 7d951b4154a6dd7efd8d12341294fdd6f2bf4f04 | |
parent | cf475f6e23581b1766e508dba81171de8f81b180 (diff) |
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.
-rw-r--r-- | gcc/cp/cvt.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/noexcept-type24.C | 22 |
2 files changed, 27 insertions, 0 deletions
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 3b8656c2a6b..c2bad5eb43d 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -1960,6 +1960,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)) diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type24.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type24.C new file mode 100644 index 00000000000..df16ea78641 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type24.C @@ -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)); |