https://gcc.gnu.org/g:3076539544d3e36684cc8eed3374aeff5b44c9b1

commit r15-6022-g3076539544d3e36684cc8eed3374aeff5b44c9b1
Author: Simon Martin <si...@nasilyan.com>
Date:   Mon Dec 9 09:21:25 2024 +0100

    tree-eh: Don't crash on GIMPLE_TRY_FINALLY with empty cleanup sequence 
[PR117845]
    
    The following valid code triggers an ICE with -fsanitize=address
    
    === cut here ===
    void l() {
        auto const ints = {0,1,2,3,4,5};
        for (auto i : { 3 } ) {
            __builtin_printf("%d ", i);
        }
    }
    === cut here ===
    
    The problem is that honor_protect_cleanup_actions does not expect the
    cleanup sequence of a GIMPLE_TRY_FINALLY to be empty. It is however the
    case here since r14-8681-gceb242f5302027, because lower_stmt removes the
    only statement in the sequence: a ASAN_MARK statement for the array that
    backs the initializer_list).
    
    This patch simply checks that the finally block is not 0 before
    accessing it in honor_protect_cleanup_actions.
    
            PR c++/117845
    
    gcc/ChangeLog:
    
            * tree-eh.cc (honor_protect_cleanup_actions): Support empty
            finally sequences.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/asan/pr117845-2.C: New test.
            * g++.dg/asan/pr117845.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/asan/pr117845-2.C | 12 ++++++++++++
 gcc/testsuite/g++.dg/asan/pr117845.C   | 12 ++++++++++++
 gcc/tree-eh.cc                         |  5 +++--
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/g++.dg/asan/pr117845-2.C 
b/gcc/testsuite/g++.dg/asan/pr117845-2.C
new file mode 100644
index 000000000000..c05563970091
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr117845-2.C
@@ -0,0 +1,12 @@
+// PR c++/117845 - Actually valid variant
+// { dg-do "compile" }
+// { dg-options "-fsanitize=address" }
+
+#include <initializer_list>
+
+void l() {
+    auto const ints = {0,1,2,3,4,5};
+    for (auto i : { 3 } ) {
+        __builtin_printf("%d ", i);
+    }
+}
diff --git a/gcc/testsuite/g++.dg/asan/pr117845.C 
b/gcc/testsuite/g++.dg/asan/pr117845.C
new file mode 100644
index 000000000000..d90d351e2701
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr117845.C
@@ -0,0 +1,12 @@
+// PR c++/117845 - Initially reported case.
+// { dg-do "compile" }
+// { dg-options "-fsanitize=address" }
+
+#include <initializer_list>
+
+void l() {
+    auto const ints = {0,1,2,3,4,5};
+    for (int i : ints | h) { // { dg-error "was not declared" }
+        __builtin_printf("%d ", i);
+    }
+}
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index 769785fad2b9..e8af5fb8989b 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -1025,8 +1025,9 @@ honor_protect_cleanup_actions (struct leh_state 
*outer_state,
         terminate before we get to it, so strip it away before adding the
         MUST_NOT_THROW filter.  */
       gimple_stmt_iterator gsi = gsi_start (finally);
-      gimple *x = gsi_stmt (gsi);
-      if (gimple_code (x) == GIMPLE_TRY
+      gimple *x = !gsi_end_p (gsi) ? gsi_stmt (gsi) : NULL;
+      if (x
+         && gimple_code (x) == GIMPLE_TRY
          && gimple_try_kind (x) == GIMPLE_TRY_CATCH
          && gimple_try_catch_is_cleanup (x))
        {

Reply via email to