[gcc(refs/users/marxin/heads/marxin-gcc-benchmark-branch)] c++: Fix a -fcompare-debug issue with DEBUG_BEGIN_STMT stmts in STATEMENT_LISTs [PR94272]

Martin Liska marxin@gcc.gnu.org
Mon Mar 30 11:07:54 GMT 2020


https://gcc.gnu.org/g:5a1706f63a2024a5c2d878f2efeb8d198214542f

commit 5a1706f63a2024a5c2d878f2efeb8d198214542f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Mar 26 09:18:35 2020 +0100

    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  <jakub@redhat.com>
    
            PR c++/94272
            * cp-gimplify.c (cp_genericize_r): Handle STATEMENT_LIST.
    
            * g++.dg/debug/pr94272.C: New test.

Diff:
---
 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(+)

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  <jakub@redhat.com>
+
+	PR c++/94272
+	* cp-gimplify.c (cp_genericize_r): Handle STATEMENT_LIST.
+
 2020-03-25  Patrick Palka  <ppalka@redhat.com>
 
 	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  <jakub@redhat.com>
+
+	PR c++/94272
+	* g++.dg/debug/pr94272.C: New test.
+
 2020-03-26  Felix Yang  <felix.yang@huawei.com>
 
 	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)
+    ;
+}


More information about the Gcc-cvs mailing list