diff options
author | Jason Merrill <jason@redhat.com> | 2023-03-30 11:07:17 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-03-30 18:25:04 -0400 |
commit | 85131af0603c0af2aa6b40de6cc929905f22bd50 (patch) | |
tree | b4a74b14b933f1008cd0cbfb0cf6f6f8dda2d2f8 /gcc | |
parent | 83d2b1ccd17d394d546a38562815ef83daa05e85 (diff) | |
download | gcc-85131af0603c0af2aa6b40de6cc929905f22bd50.zip gcc-85131af0603c0af2aa6b40de6cc929905f22bd50.tar.gz gcc-85131af0603c0af2aa6b40de6cc929905f22bd50.tar.bz2 |
c++: generic lambda and function ptr conv [PR105221]
We weren't properly considering the function pointer conversions in
deduction between FUNCTION_TYPE; we just hardcoded the
UNIFY_ALLOW_MORE_CV_QUAL semantics, which are backwards when deducing for a
template conversion function like the one in a generic lambda. And when I
started checking the ALLOW flags, I needed to make sure they stay set to
avoid breaking trailing13.C.
PR c++/105221
gcc/cp/ChangeLog:
* pt.cc (unify) [FUNCTION_TYPE]: Handle function pointer
conversions.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/noexcept-type27.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/pt.cc | 33 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/noexcept-type27.C | 8 |
2 files changed, 38 insertions, 3 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index e514a27..dd7f0db 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -24472,9 +24472,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, return unify_cv_qual_mismatch (explain_p, parm, arg); if (!(strict & UNIFY_ALLOW_OUTER_LEVEL) - && TYPE_P (parm) && !CP_TYPE_CONST_P (parm)) + && TYPE_P (parm) && !CP_TYPE_CONST_P (parm) + && !FUNC_OR_METHOD_TYPE_P (parm)) strict &= ~UNIFY_ALLOW_MORE_CV_QUAL; - strict &= ~UNIFY_ALLOW_OUTER_LEVEL; + /* PMFs recurse at the same level, so don't strip this yet. */ + if (!TYPE_PTRMEMFUNC_P (parm)) + strict &= ~UNIFY_ALLOW_OUTER_LEVEL; strict &= ~UNIFY_ALLOW_DERIVED; strict &= ~UNIFY_ALLOW_OUTER_MORE_CV_QUAL; strict &= ~UNIFY_ALLOW_OUTER_LESS_CV_QUAL; @@ -25022,7 +25025,31 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_PURPOSE (pspec), TREE_PURPOSE (aspec), UNIFY_ALLOW_NONE, explain_p); - else if (nothrow_spec_p (pspec) && !nothrow_spec_p (aspec)) + else + { + bool pn = nothrow_spec_p (pspec); + bool an = nothrow_spec_p (aspec); + /* Here "less cv-qual" means the deduced arg (i.e. parm) has + /more/ noexcept, since function pointer conversions are the + reverse of qualification conversions. */ + if (an == pn + || (an < pn && (strict & UNIFY_ALLOW_LESS_CV_QUAL)) + || (an > pn && (strict & UNIFY_ALLOW_MORE_CV_QUAL))) + /* OK. */; + else + return unify_type_mismatch (explain_p, parm, arg); + } + } + if (flag_tm) + { + /* As for noexcept. */ + bool pn = tx_safe_fn_type_p (parm); + bool an = tx_safe_fn_type_p (arg); + if (an == pn + || (an < pn && (strict & UNIFY_ALLOW_LESS_CV_QUAL)) + || (an > pn && (strict & UNIFY_ALLOW_MORE_CV_QUAL))) + /* OK. */; + else return unify_type_mismatch (explain_p, parm, arg); } diff --git a/gcc/testsuite/g++.dg/cpp1z/noexcept-type27.C b/gcc/testsuite/g++.dg/cpp1z/noexcept-type27.C new file mode 100644 index 0000000..a691f69 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/noexcept-type27.C @@ -0,0 +1,8 @@ +// PR c++/105221 +// { dg-do compile { target c++14 } } + +void (*p)(int) = [](auto) noexcept {}; + +int main() { + true ? [](auto) noexcept {} : [](int) {}; +} |