diff options
author | Patrick Palka <ppalka@redhat.com> | 2023-02-05 21:35:33 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2023-02-05 21:35:33 -0500 |
commit | 31924665c86d47af6b1f22a74f594f2e1dc0ed2d (patch) | |
tree | 2b92f40ff91d210b9a3e34b77d7097bc619a5fb5 /gcc/cp/pt.cc | |
parent | e4421a770d42477736a6598ee2cf61c6c737cc37 (diff) | |
download | gcc-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.cc | 2 |
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); |