From 5a1706f63a2024a5c2d878f2efeb8d198214542f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 26 Mar 2020 09:18:35 +0100 Subject: [PATCH] c++: Fix a -fcompare-debug issue with DEBUG_BEGIN_STMT stmts in STATEMENT_LISTs [PR94272] The following testcase FAILs with -fcompare-debug. The problem is that the C++ FE initially uses IF_STMTs, tcc_statement which default to TREE_SIDE_EFFECTS set, but later on is genericized into COND_EXPRs, tcc_expression which default to TREE_SIDE_EFFECTS ored from all 3 operands. Furthermore, with -g we emit by default DEBUG_BEGIN_STMTs (TREE_SIDE_EFFECTS clear) and so end up with a STATEMENT_LIST containing DEBUG_BEGIN_STMT + e.g. the IF_STMT, while with -g0 we would end up with just the IF_STMT alone and in that case there is no STATEMENT_LIST wrapping it. Now, the STATEMENT_LIST has TREE_SIDE_EFFECTS set to match the IF_STMT, but if none of the 3 operands (condition and both branches) have TREE_SIDE_EFFECTS, genericize_if_stmt will replace the IF_STMT with COND_EXPR without TREE_SIDE_EFFECTS, but with -g only STATEMENT_LIST wrapping it will keep TREE_SIDE_EFFECTS. Then during gimplification, shortcut_cond_expr checks TREE_SIDE_EFFECTS of the operands and as it is differennt between -g and -g0, will generate different code. The following patch attempts to fix this by clearing TREE_SIDE_EFFECTS on STATEMENT_LISTs that initially have it set and contain only DEBUG_BEGIN_STMT or at most one other statement that lost TREE_SIDE_EFFECTS during the genericization. 2020-03-26 Jakub Jelinek PR c++/94272 * cp-gimplify.c (cp_genericize_r): Handle STATEMENT_LIST. * g++.dg/debug/pr94272.C: New test. --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/cp-gimplify.c | 29 ++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/debug/pr94272.C | 14 ++++++++++++++ 4 files changed, 53 insertions(+) create mode 100644 gcc/testsuite/g++.dg/debug/pr94272.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 34ccb9fa4c0..9ff2525f83d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2020-03-26 Jakub Jelinek + + PR c++/94272 + * cp-gimplify.c (cp_genericize_r): Handle STATEMENT_LIST. + 2020-03-25 Patrick Palka PR c++/94265 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index aa80384e1a4..d003f5b7825 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1754,6 +1754,35 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) walk_subtrees = 0; break; + case STATEMENT_LIST: + if (TREE_SIDE_EFFECTS (stmt)) + { + tree_stmt_iterator i; + int nondebug_stmts = 0; + bool clear_side_effects = true; + /* Genericization can clear TREE_SIDE_EFFECTS, e.g. when + transforming an IF_STMT into COND_EXPR. If such stmt + appears in a STATEMENT_LIST that contains only that + stmt and some DEBUG_BEGIN_STMTs, without -g where the + STATEMENT_LIST wouldn't be present at all the resulting + expression wouldn't have TREE_SIDE_EFFECTS set, so make sure + to clear it even on the STATEMENT_LIST in such cases. */ + for (i = tsi_start (stmt); !tsi_end_p (i); tsi_next (&i)) + { + tree t = tsi_stmt (i); + if (TREE_CODE (t) != DEBUG_BEGIN_STMT && nondebug_stmts < 2) + nondebug_stmts++; + cp_walk_tree (tsi_stmt_ptr (i), cp_genericize_r, data, NULL); + if (TREE_CODE (t) != DEBUG_BEGIN_STMT + && (nondebug_stmts > 1 || TREE_SIDE_EFFECTS (tsi_stmt (i)))) + clear_side_effects = false; + } + if (clear_side_effects) + TREE_SIDE_EFFECTS (stmt) = 0; + *walk_subtrees = 0; + } + break; + default: if (IS_TYPE_OR_DECL_P (stmt)) *walk_subtrees = 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f8512d3fb32..6d5c12f20a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-26 Jakub Jelinek + + PR c++/94272 + * g++.dg/debug/pr94272.C: New test. + 2020-03-26 Felix Yang PR tree-optimization/94269 diff --git a/gcc/testsuite/g++.dg/debug/pr94272.C b/gcc/testsuite/g++.dg/debug/pr94272.C new file mode 100644 index 00000000000..78522e00472 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/pr94272.C @@ -0,0 +1,14 @@ +// PR c++/94272 +// { dg-do compile } +// { dg-options "-O2 -fnon-call-exceptions -fcompare-debug" } + +int *c, d, *e; + +void +foo () +{ + if (c && d) + ; + else if (*e) + ; +} -- 2.30.2