aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-02-05 21:35:33 -0500
committerPatrick Palka <ppalka@redhat.com>2023-02-05 21:35:33 -0500
commit31924665c86d47af6b1f22a74f594f2e1dc0ed2d (patch)
tree2b92f40ff91d210b9a3e34b77d7097bc619a5fb5 /gcc/cp/pt.cc
parente4421a770d42477736a6598ee2cf61c6c737cc37 (diff)
downloadgcc-31924665c86d47af6b1f22a74f594f2e1dc0ed2d.zip
gcc-31924665c86d47af6b1f22a74f594f2e1dc0ed2d.tar.gz
gcc-31924665c86d47af6b1f22a74f594f2e1dc0ed2d.tar.bz2
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.
Diffstat (limited to 'gcc/cp/pt.cc')
-rw-r--r--gcc/cp/pt.cc2
1 files changed, 1 insertions, 1 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 51fc246..e89dbf4 100644
--- 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);