aboutsummaryrefslogtreecommitdiff
path: root/gcc/print-rtl.cc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-19 09:34:10 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-19 09:34:10 +0100
commitacdf8105a7fcead27bd4924bf8dc7f76c9273943 (patch)
tree9f93cec9c9609f9c6903af52b93f36c09f49de21 /gcc/print-rtl.cc
parent3a59a1e1bbc7c16477902149d200ce2d3d6c8df5 (diff)
downloadgcc-acdf8105a7fcead27bd4924bf8dc7f76c9273943.zip
gcc-acdf8105a7fcead27bd4924bf8dc7f76c9273943.tar.gz
gcc-acdf8105a7fcead27bd4924bf8dc7f76c9273943.tar.bz2
c++: Perform immediate invocation evaluation separately from cp_fold_r [PR118068]
The r14-4140 change moved consteval evaluation from build_over_call to cp_fold_r. The following testcase is a regression caused by that change. There is a cast around immediate invocation, (int) foo (0x23) where consteval for returns unsigned char. When the consteval call has been folded early to 0x23 (with unsigned char type), cp_fold sees (int) 0x23 and folds that to 0x23 with int type. But when the immediate invocation is handled only during cp_fold_r, cp_fold_r first calls cp_fold on the NOP_EXPR, which calls cp_fold on its operand, it is CALL_EXPR, nothing is folded at that point. Then cp_fold_r continues to walk the NOP_EXPR's operand, sees it is an immediate function invocation and cp_fold_immediate_r calls cxx_constant_value on it and replaces the CALL_EXPR with the INTEGER_CST 0x23. Nothing comes back to folding the containing NOP_EXPR though. Sure, with optimizations enabled some GIMPLE optimization folds that later, but e.g. with -O0 nothing does that. I think there could be arbitrarily complex expressions on top of the immediate invocation(s) that used to be folded by cp_fold before and aren't folded anymore. One possibility would be to do the immediate invocation evaluation in cp_fold rather than cp_fold_r (or in addition to cp_fold_r). The following patch instead first evaluates all immediate invocations and does cp_fold_r in a separate step. That not only allows the folding of expressions which contain immediate invocations, but also simplifies some of the quirks that had to be done when it was in cp_fold_r. Though, I had to add an extra case to cp_genericize_r RETURN_EXPR handling to avoid a regression where after emitting errors in RETURN_EXPR argument we've emitted a -Wreturn-type false positive. Previously we ended up with RETURN_EXPR with CLEANUP_POINT_EXPR with INIT_EXPR of RESULT_DECL to error_mark_node, now we fold it more and have RETURN_EXPR with error_mark_node operand. The former would result during gimplification into something -Wresult-type was quiet about, the latter doesn't. BTW, r14-4140 changed behavior on consteval bool foo (bool x) { if (x) throw 1; return false; } constexpr void foo () { if constexpr (false) { bool a = foo (true); } } where GCC 13 emitted error: expression ‘<throw-expression>’ is not a constant expression error and GCC 14/trunk including the patch below doesn't reject it. And clang++ trunk rejects it. It isn't immediately clear to me what is right, if immediate invocations in discarded statements should be evaluated or not. 2025-03-19 Jakub Jelinek <jakub@redhat.com> PR target/118068 gcc/cp/ * cp-gimplify.cc (cp_fold_immediate): Use cp_walk_tree rather than cp_walk_tree_without_duplicates. (cp_fold_immediate_r): For IF_STMT_CONSTEVAL_P IF_STMT don't walk into THEN_CLAUSE subtree, only ELSE_CLAUSE. For non-call related stmts call data->pset.add and if it returns true, don't walk subtrees. (cp_fold_r): Don't call cp_fold_immediate_r here. (cp_fold_function): For C++20 or later call cp_walk_tree with cp_fold_immediate_r callback first before calling cp_walk_tree with cp_fold_r callback and call data.pset.empty () in between. (cp_fully_fold_init): Likewise. (cp_genericize_r) <case RETURN_EXPR>: Suppress -Wreturn-type warning if RETURN_EXPR has erroneous argument. gcc/testsuite/ * g++.target/i386/pr118068.C: New test.
Diffstat (limited to 'gcc/print-rtl.cc')
0 files changed, 0 insertions, 0 deletions