c++: equivalence of non-dependent calls [PR107461]
commit31924665c86d47af6b1f22a74f594f2e1dc0ed2d
authorPatrick Palka <ppalka@redhat.com>
Mon, 6 Feb 2023 02:35:33 +0000 (5 21:35 -0500)
committerPatrick Palka <ppalka@redhat.com>
Mon, 6 Feb 2023 02:35:33 +0000 (5 21:35 -0500)
tree2b92f40ff91d210b9a3e34b77d7097bc619a5fb5
parente4421a770d42477736a6598ee2cf61c6c737cc37
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.
gcc/cp/cp-tree.h
gcc/cp/pt.cc
gcc/cp/tree.cc
gcc/testsuite/g++.dg/cpp0x/overload5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/overload5a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/overload6.C [new file with mode: 0644]