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 <rguent...@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. 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" } } */