aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2023-03-30 11:07:17 -0400
committerJason Merrill <jason@redhat.com>2023-03-30 18:25:04 -0400
commit85131af0603c0af2aa6b40de6cc929905f22bd50 (patch)
treeb4a74b14b933f1008cd0cbfb0cf6f6f8dda2d2f8 /gcc
parent83d2b1ccd17d394d546a38562815ef83daa05e85 (diff)
downloadgcc-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.cc33
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/noexcept-type27.C8
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) {};
+}