Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
Here we ICE with -fsanitize=address on

  std::initializer_list x = { 1, 2, 3 };

since r14-8681, which removed .ASAN_MARK calls on TREE_STATIC variables.
That means that lower_try_finally now instead of

  try
    {
      .ASAN_MARK (UNPOISON, &C.0, 12);
      x = {};
      x._M_len = 3;
      x._M_array = &C.0;
    }
  finally
    {
      .ASAN_MARK (POISON, &C.0, 12);
    }

gets:

  try
    {
      x = {};
      x._M_len = 3;
      x._M_array = &C.0;
    }
  finally
    {

    }

and we ICE on the empty finally in lower_try_finally_onedest while
getting get_eh_else.

Rather than checking everywhere that a GIMPLE_TRY_FINALLY is not empty,
I thought we could process it as if it were unreachable.

        PR c++/115865

gcc/ChangeLog:

        * tree-eh.cc (lower_try_finally): If the FINALLY block is empty, treat
        it as if it were not reachable.

gcc/testsuite/ChangeLog:

        * g++.dg/asan/initlist2.C: New test.
---
 gcc/testsuite/g++.dg/asan/initlist2.C | 16 ++++++++++++++++
 gcc/tree-eh.cc                        |  4 ++--
 2 files changed, 18 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/asan/initlist2.C

diff --git a/gcc/testsuite/g++.dg/asan/initlist2.C 
b/gcc/testsuite/g++.dg/asan/initlist2.C
new file mode 100644
index 00000000000..bce5410be33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/initlist2.C
@@ -0,0 +1,16 @@
+// PR c++/115865
+// { dg-do compile }
+// { dg-options "-fsanitize=address" }
+
+typedef decltype(sizeof(char)) size_t;
+
+namespace std {
+template <class> class initializer_list {
+  int *_M_array;
+  size_t _M_len;
+};
+}
+
+int main() {
+  std::initializer_list x = { 1, 2, 3 };
+}
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index a776ad5c92b..6ae6dab223e 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -1703,8 +1703,8 @@ lower_try_finally (struct leh_state *state, gtry *tp)
   ndests += this_tf.may_return;
   ndests += this_tf.may_throw;
 
-  /* If the FINALLY block is not reachable, dike it out.  */
-  if (ndests == 0)
+  /* If the FINALLY block is not reachable or empty, dike it out.  */
+  if (ndests == 0 || gimple_seq_empty_p (gimple_try_cleanup (tp)))
     {
       gimple_seq_add_seq (&this_tf.top_p_seq, gimple_try_eval (tp));
       gimple_try_set_cleanup (tp, NULL);

base-commit: 74d8accaf88f83bfcab1150bf9be5140e7ac0e94
-- 
2.45.2

Reply via email to