diff options
author | Jason Merrill <jason@redhat.com> | 2021-04-02 17:07:12 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-04-03 01:54:03 -0400 |
commit | 7c3ba2145ceddb0fd7f85fbf27f8db81896527d1 (patch) | |
tree | f6c3d402642234abfc995eac5aa0e229dc4709dc /gcc | |
parent | 23be03a0f243a084a0fe03d0b96a3d045e1a2b65 (diff) | |
download | gcc-7c3ba2145ceddb0fd7f85fbf27f8db81896527d1.zip gcc-7c3ba2145ceddb0fd7f85fbf27f8db81896527d1.tar.gz gcc-7c3ba2145ceddb0fd7f85fbf27f8db81896527d1.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-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 d105113..f1687e8 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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)) 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 0000000..df16ea7 --- /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)); |