diff options
author | Sam James <sam@gentoo.org> | 2023-02-06 17:32:01 +0000 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2023-02-06 17:32:01 +0000 |
commit | 3f8fa89d582a0d56ab4eac414552aed99cec6751 (patch) | |
tree | c08bf0f281e104bd52217bbc7f000019ccdd8335 | |
parent | 13.1.0: fixup README.history, drop obsolete 50_all_calloc_libgccjit.patch (diff) | |
download | gcc-patches-3f8fa89d582a0d56ab4eac414552aed99cec6751.tar.gz gcc-patches-3f8fa89d582a0d56ab4eac414552aed99cec6751.tar.bz2 gcc-patches-3f8fa89d582a0d56ab4eac414552aed99cec6751.zip |
13.1.0: add 75_all_all_PR107461_cxx_equivalence_non_dependent_calls.patch
Bug: https://bugs.gentoo.org/893410
Signed-off-by: Sam James <sam@gentoo.org>
-rw-r--r-- | 13.1.0/gentoo/75_all_all_PR107461_cxx_equivalence_non_dependent_calls.patch | 174 | ||||
-rw-r--r-- | 13.1.0/gentoo/README.history | 3 |
2 files changed, 177 insertions, 0 deletions
diff --git a/13.1.0/gentoo/75_all_all_PR107461_cxx_equivalence_non_dependent_calls.patch b/13.1.0/gentoo/75_all_all_PR107461_cxx_equivalence_non_dependent_calls.patch new file mode 100644 index 0000000..0a421a1 --- /dev/null +++ b/13.1.0/gentoo/75_all_all_PR107461_cxx_equivalence_non_dependent_calls.patch @@ -0,0 +1,174 @@ +https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=31924665c86d47af6b1f22a74f594f2e1dc0ed2d +(followup to https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=59e0376f607805ef9b67fd7b0a4a3084ab3571a5) +https://bugs.gentoo.org/893410 + +From 31924665c86d47af6b1f22a74f594f2e1dc0ed2d Mon Sep 17 00:00:00 2001 +From: Patrick Palka <ppalka@redhat.com> +Date: Sun, 5 Feb 2023 21:35:33 -0500 +Subject: [PATCH] c++: equivalence of non-dependent calls [PR107461] + +After r13-5684-g59e0376f607805 the (pruned) callee of a non-dependent +CALL_EXPR is a bare FUNCTION_DECL rather than ADDR_EXPR of FUNCTION_DECL. +This innocent change revealed that cp_tree_equal doesn't first check +dependence of a CALL_EXPR before treating a FUNCTION_DECL callee as a +dependent name, which leads to us incorrectly accepting the first two +testcases below and rejecting the third: + + * In the first testcase, cp_tree_equal incorrectly returns true for + the two non-dependent CALL_EXPRs f(0) and f(0) (whose CALL_EXPR_FN + are different FUNCTION_DECLs) which causes us to treat #2 as a + redeclaration of #1. + + * Same issue in the second testcase, for f<int*>() and f<char>(). + + * In the third testcase, cp_tree_equal incorrectly returns true for + f<int>() and f<void(*)(int)>() which causes us to conflate the two + dependent specializations A<decltype(f<int>()(U()))> and + A<decltype(f<void(*)(int)>()(U()))>. + +This patch fixes this by making called_fns_equal treat two callees as +dependent names only if the overall CALL_EXPRs are dependent, via a new +convenience function call_expr_dependent_name that is like dependent_name +but also checks dependence of the overall CALL_EXPR. + + PR c++/107461 + +gcc/cp/ChangeLog: + + * cp-tree.h (call_expr_dependent_name): Declare. + * pt.cc (iterative_hash_template_arg) <case CALL_EXPR>: Use + call_expr_dependent_name instead of dependent_name. + * tree.cc (call_expr_dependent_name): Define. + (called_fns_equal): Adjust to take two CALL_EXPRs instead of + CALL_EXPR_FNs thereof. Use call_expr_dependent_name instead + of dependent_name. + (cp_tree_equal) <case CALL_EXPR>: Adjust call to called_fns_equal. + +gcc/testsuite/ChangeLog: + + * g++.dg/cpp0x/overload5.C: New test. + * g++.dg/cpp0x/overload5a.C: New test. + * g++.dg/cpp0x/overload6.C: New test. +--- a/gcc/cp/cp-tree.h ++++ b/gcc/cp/cp-tree.h +@@ -7902,6 +7902,7 @@ extern tree lookup_maybe_add (tree fns, tree lookup, + extern int is_overloaded_fn (tree) ATTRIBUTE_PURE; + extern bool really_overloaded_fn (tree) ATTRIBUTE_PURE; + extern tree dependent_name (tree); ++extern tree call_expr_dependent_name (tree); + extern tree maybe_get_fns (tree) ATTRIBUTE_PURE; + extern tree get_fns (tree) ATTRIBUTE_PURE; + extern tree get_first_fn (tree) ATTRIBUTE_PURE; +--- a/gcc/cp/pt.cc ++++ b/gcc/cp/pt.cc +@@ -1841,7 +1841,7 @@ iterative_hash_template_arg (tree arg, hashval_t val) + case CALL_EXPR: + { + tree fn = CALL_EXPR_FN (arg); +- if (tree name = dependent_name (fn)) ++ if (tree name = call_expr_dependent_name (arg)) + { + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + val = iterative_hash_template_arg (TREE_OPERAND (fn, 1), val); +--- a/gcc/cp/tree.cc ++++ b/gcc/cp/tree.cc +@@ -2608,6 +2608,18 @@ dependent_name (tree x) + return NULL_TREE; + } + ++/* Like dependent_name, but instead takes a CALL_EXPR and also checks ++ its dependence. */ ++ ++tree ++call_expr_dependent_name (tree x) ++{ ++ if (TREE_TYPE (x) != NULL_TREE) ++ /* X isn't dependent, so its callee isn't a dependent name. */ ++ return NULL_TREE; ++ return dependent_name (CALL_EXPR_FN (x)); ++} ++ + /* Returns true iff X is an expression for an overloaded function + whose type cannot be known without performing overload + resolution. */ +@@ -3870,16 +3882,18 @@ decl_internal_context_p (const_tree decl) + return !TREE_PUBLIC (decl); + } + +-/* Subroutine of cp_tree_equal: t1 and t2 are the CALL_EXPR_FNs of two +- CALL_EXPRS. Return whether they are equivalent. */ ++/* Subroutine of cp_tree_equal: t1 and t2 are two CALL_EXPRs. ++ Return whether their CALL_EXPR_FNs are equivalent. */ + + static bool + called_fns_equal (tree t1, tree t2) + { + /* Core 1321: dependent names are equivalent even if the overload sets + are different. But do compare explicit template arguments. */ +- tree name1 = dependent_name (t1); +- tree name2 = dependent_name (t2); ++ tree name1 = call_expr_dependent_name (t1); ++ tree name2 = call_expr_dependent_name (t2); ++ t1 = CALL_EXPR_FN (t1); ++ t2 = CALL_EXPR_FN (t2); + if (name1 || name2) + { + tree targs1 = NULL_TREE, targs2 = NULL_TREE; +@@ -4037,7 +4051,7 @@ cp_tree_equal (tree t1, tree t2) + if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2)) + return false; + +- if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2))) ++ if (!called_fns_equal (t1, t2)) + return false; + + call_expr_arg_iterator iter1, iter2; +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/overload5.C +@@ -0,0 +1,12 @@ ++// PR c++/107461 ++// { dg-do compile { target c++11 } } ++ ++int f(...); ++template<class T> decltype(T() + f(0)) g(); // #1 ++ ++char f(int); ++template<class T> decltype(T() + f(0)) g(); // #2, distinct from #1 ++ ++int main() { ++ g<int>(); // { dg-error "ambiguous" } ++} +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/overload5a.C +@@ -0,0 +1,10 @@ ++// PR c++/107461 ++// { dg-do compile { target c++11 } } ++ ++template<class T> T f(); ++template<class T> decltype(T() + f<int*>()) g(); // #1 ++template<class T> decltype(T() + f<char>()) g(); // #2, distinct from #1 ++ ++int main() { ++ g<int>(); // { dg-error "ambiguous" } ++} +--- /dev/null ++++ b/gcc/testsuite/g++.dg/cpp0x/overload6.C +@@ -0,0 +1,16 @@ ++// PR c++/107461 ++// { dg-do compile { target c++11 } } ++ ++template<class T> T f(); ++ ++template<class> struct A { }; ++ ++template<class T> struct B { ++ template<class U, class = A<decltype(f<T>()(U()))>> ++ static void g(U); ++}; ++ ++int main() { ++ B<int> b; ++ B<void(*)(int)>::g(0); // { dg-bogus "no match" } ++} +-- +2.31.1 diff --git a/13.1.0/gentoo/README.history b/13.1.0/gentoo/README.history index 1564ee1..3780f77 100644 --- a/13.1.0/gentoo/README.history +++ b/13.1.0/gentoo/README.history @@ -1,3 +1,6 @@ +7 6 Feb 2023 + + 75_all_all_PR107461_cxx_equivalence_non_dependent_calls.patch + 6 30 Jan 2023 U 01_all_default-fortify-source.patch + 15_all_DEF_GENTOO_GLIBCXX_ASSERTIONS.patch |