We are currently restricting loop crossing paths in the generic copier used by the back threader, but we should be able to handle them after loop_done has completed.
This fixes the PR at -O2, though the problem remains at -O1 because we have no threaders smart enough to elide the undefined read. DOM3 could be a candidate when it is converted to either a hybrid threader or replaced with the backward threader (when ranger can handle floats). Tested on x86-64 Linux. OK for trunk? PR tree-optimization/80548 gcc/ChangeLog: * attribs.c (sorted_attr_string): Add assert for -Wstringop-overread. * tree-ssa-threadupdate.c (back_jt_path_registry::duplicate_thread_path): Allow paths that cross loops after loop_done. (back_jt_path_registry::update_cfg): Diagnose dropped threads after duplicate_thread_path. gcc/testsuite/ChangeLog: * gcc.dg/pr80548.c: New test. --- gcc/attribs.c | 1 + gcc/testsuite/gcc.dg/pr80548.c | 23 +++++++++++++++++++++++ gcc/tree-ssa-threadupdate.c | 19 +++++++++++-------- 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr80548.c diff --git a/gcc/attribs.c b/gcc/attribs.c index c252f5af07b..9a079b8405a 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -1035,6 +1035,7 @@ sorted_attr_string (tree arglist) attr_str[str_len_sum + len] = TREE_CHAIN (arg) ? ',' : '\0'; str_len_sum += len + 1; } + gcc_assert (arglist); /* Replace "=,-" with "_". */ for (i = 0; i < strlen (attr_str); i++) diff --git a/gcc/testsuite/gcc.dg/pr80548.c b/gcc/testsuite/gcc.dg/pr80548.c new file mode 100644 index 00000000000..2327111143e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr80548.c @@ -0,0 +1,23 @@ +// { dg-do compile } +// { dg-options "-O2 -Wuninitialized" } + +int g (void); +void h (int, int); + +void f (int b) +{ + int x, y; + + if (b) + { + x = g (); + y = g (); + } + + while (g ()) + if (b) + { + h (x, y); // { dg-bogus "uninit" } + y = g (); + } +} diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 8aac733ac25..b194c11e23d 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -2410,13 +2410,14 @@ back_jt_path_registry::duplicate_thread_path (edge entry, missuses of the functions. I.e. if you ask to copy something weird, it will work, but the state of structures probably will not be correct. */ - for (i = 0; i < n_region; i++) - { - /* We do not handle subloops, i.e. all the blocks must belong to the - same loop. */ - if (region[i]->loop_father != loop) - return false; - } + if (!(cfun->curr_properties & PROP_loop_opts_done)) + for (i = 0; i < n_region; i++) + { + /* We do not handle subloops, i.e. all the blocks must belong to the + same loop. */ + if (region[i]->loop_father != loop) + return false; + } initialize_original_copy_tables (); @@ -2651,9 +2652,11 @@ back_jt_path_registry::update_cfg (bool /*peel_loop_headers*/) visited_starting_edges.add (entry); retval = true; m_num_threaded_edges++; + path->release (); } + else + cancel_thread (path, "Failure in duplicate_thread_path"); - path->release (); m_paths.unordered_remove (0); free (region); } -- 2.31.1