https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80959

--- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> ---
So there's explanation what happens:

1) w/o -fsanitize=address:

decide_copy_try_finally returns true and so that we copy BB that contains
finally statement:

foo ()
{
  int n;
  int D.1806;

  bar (&n);
  i.0_1 = i;
  switch (i.0_1) <default: <D.1804>, case 1: <D.1801>>
  <D.1801>:
  i.1_2 = i;
  switch (i.1_2) <default: <D.1802>>
  <D.1802>:
  D.1806 = 0;
  goto <D.1809>;
  goto <D.1803>;
  <D.1804>:
  D.1806 = 0;
  goto <D.1809>;
  <D.1803>:
  n = {CLOBBER};
  goto <D.1808>;
  <D.1809>:
  n = {CLOBBER};
  goto <D.1807>;
  <D.1808>:
  return;
  <D.1807>:
  return D.1806;
}

then CFG pass removes the dead BBs. All works fine.

2) w/ -fsanitize=address the decide_copy_try_finally returns false and thus we
create switch to dispatch
from the finally statement:

foo ()
{
  int finally_tmp.2;
  int n;
  int D.2128;

  ASAN_MARK (UNPOISON, &n, 4);
  bar (&n);
  i.0_1 = i;
  switch (i.0_1) <default: <D.2126>, case 1: <D.2123>>
  <D.2123>:
  i.1_2 = i;
  switch (i.1_2) <default: <D.2124>>
  <D.2124>:
  D.2128 = 0;
  finally_tmp.2 = 0;
  goto <D.2131>;
  goto <D.2125>;
  <D.2126>:
  D.2128 = 0;
  finally_tmp.2 = 0;
  goto <D.2131>;
  <D.2125>:
  finally_tmp.2 = 1;
  <D.2131>:
  ASAN_MARK (POISON, &n, 4);
  switch (finally_tmp.2) <default: <D.2134>, case 1: <D.2132>>
  <D.2132>:
  goto <D.2133>;
  <D.2134>:
  goto <D.2129>;
  <D.2133>:
  return;
  <D.2129>:
  return D.2128;
}

Then CFG removes:

Removing basic block 7
;; basic block 7, loop depth 0
;;  pred:       5
finally_tmp.2 = 1;
;;  succ:       8

now   finally_tmp.2 can have only one value, but the switch statement,
as well as the problematic return BB are not removed.

Reply via email to