diff mbox

Improve VRP for stmts that can throw (PR27336)

Message ID alpine.LSU.2.11.1608221145530.26629@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Aug. 22, 2016, 9:47 a.m. UTC
We currently fail to assert that this != NULL at the caller side
because we're chickening out on stmts that could throw.  While
it would be trivial to fix the testcase with only bailing out
for internally throwing stmts the following properly handles those
as well by making sure to infer stuff only on the non-EH outging
edge if the stmt ends the BB.

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-08-22  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/27336
	* tree-vrp.c (infer_value_range): Handle stmts that can throw
	by looking for a non-EH edge.
	(process_assert_insertions_for): Likewise.

	* c-c++-common/pr27336.c: New testcase.
diff mbox

Patch

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 239653)
+++ gcc/tree-vrp.c	(working copy)
@@ -4782,11 +4760,6 @@  infer_value_range (gimple *stmt, tree op
   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
     return false;
 
-  /* Similarly, don't infer anything from statements that may throw
-     exceptions. ??? Relax this requirement?  */
-  if (stmt_could_throw_p (stmt))
-    return false;
-
   /* If STMT is the last statement of a basic block with no normal
      successors, there is no point inferring anything about any of its
      operands.  We would not be able to find a proper insertion point
@@ -4797,7 +4770,7 @@  infer_value_range (gimple *stmt, tree op
       edge e;
 
       FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
-	if (!(e->flags & EDGE_ABNORMAL))
+	if (!(e->flags & (EDGE_ABNORMAL|EDGE_EH)))
 	  break;
       if (e == NULL)
 	return false;
@@ -6370,10 +6343,10 @@  process_assert_insertions_for (tree name
 
   /* If STMT must be the last statement in BB, we can only insert new
      assertions on the non-abnormal edge out of BB.  Note that since
-     STMT is not control flow, there may only be one non-abnormal edge
+     STMT is not control flow, there may only be one non-abnormal/eh edge
      out of BB.  */
   FOR_EACH_EDGE (e, ei, loc->bb->succs)
-    if (!(e->flags & EDGE_ABNORMAL))
+    if (!(e->flags & (EDGE_ABNORMAL|EDGE_EH)))
       {
 	gsi_insert_on_edge (e, assert_stmt);
 	return true;
Index: gcc/testsuite/c-c++-common/pr27336.c
===================================================================
--- gcc/testsuite/c-c++-common/pr27336.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr27336.c	(working copy)
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+struct B { int x; };
+extern void g3(struct B *that)  __attribute__((nonnull));
+int f3(struct B *a)
+{
+  g3(a);
+  return a != (void *)0;
+}
+
+/* { dg-final { scan-tree-dump "return 1;" "vrp1" } } */