PR 63748 reports a false-positive uninitialized warning under the presence of abnormal edges. The statements for which the uninitialized warnings are emitted all look like:
buf_117(ab) = buf_317(D)(ab); This PR is similar to PR 57287 which also reports false-positive uninitialized warnings under the presence of abnormal edges. That PR fixed the reported issue by allowing to propagate default definitions which appear in abnormal PHI nodes. That is, it allowed propagating the following kinds of copies: buf_24 = buf_16(D)(ab); But it still did not allow propagating copies whose destination operand occurs in an abnormal PHI node. To fix PR 63748, this patch extends the fix to PR 57287 to allow propagating such copies too. Full bootstrap + regtesting on x86_64-unknown-linux-gnu is in progress. Is this patch OK if testing succeeds with no new regressions? 2014-11-10 Patrick Palka <ppa...@gcc.gnu.org> gcc/ PR middle-end/63748 * tree-ssa-propagate.c (may_propagate_copy): Allow propagating SSA copies whose source and destination names both occur in abnormal edges. gcc/testsuite/ PR middle-end/63748 * gcc.dg/pr63748.c: New testcase. --- gcc/testsuite/gcc.dg/pr63748.c | 36 ++++++++++++++++++++++++++++++++++++ gcc/tree-ssa-propagate.c | 27 +++++++++++++++------------ 2 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr63748.c diff --git a/gcc/testsuite/gcc.dg/pr63748.c b/gcc/testsuite/gcc.dg/pr63748.c new file mode 100644 index 0000000..2e50445 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr63748.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ + +#include <setjmp.h> + +jmp_buf *alloc_jmp_buf (); +int foo (void *); + +int +test (int op, int noside) +{ + void *argvec = 0; + + if (op) + { + jmp_buf *buf = alloc_jmp_buf (); /* { dg-bogus "uninitialized" } */ + setjmp (*buf); + + if (noside) + goto nosideret; + + do_call_it: + + if (noside) + goto nosideret; + + return foo (argvec); + } + + argvec = __builtin_alloca (1); + goto do_call_it; + +nosideret: + return 1; +} + diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 9f4d381..9e61baf 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -1275,21 +1275,24 @@ may_propagate_copy (tree dest, tree orig) tree type_d = TREE_TYPE (dest); tree type_o = TREE_TYPE (orig); - /* If ORIG flows in from an abnormal edge, it cannot be propagated. */ + /* If ORIG is a default definition which flows in from an abnormal edge + then the copy can be propagated. It is important that we do so to avoid + uninitialized regular copies. */ if (TREE_CODE (orig) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig) - /* If it is the default definition and an automatic variable then - we can though and it is important that we do to avoid - uninitialized regular copies. */ - && !(SSA_NAME_IS_DEFAULT_DEF (orig) - && (SSA_NAME_VAR (orig) == NULL_TREE - || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL))) + && SSA_NAME_IS_DEFAULT_DEF (orig) + && (SSA_NAME_VAR (orig) == NULL_TREE + || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL)) + ; + /* Otherwise if ORIG just flows in from an abnormal edge then the copy cannot + be propagated. */ + else if (TREE_CODE (orig) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)) return false; - - /* If DEST is an SSA_NAME that flows from an abnormal edge, then it - cannot be replaced. */ - if (TREE_CODE (dest) == SSA_NAME - && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)) + /* Similarly if DEST flows in from an abnormal edge then the copy cannot be + propagated. */ + else if (TREE_CODE (dest) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)) return false; /* Do not copy between types for which we *do* need a conversion. */ -- 2.2.0.rc0.18.ga1ad247