aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSimon Martin <simon@nasilyan.com>2024-12-09 09:21:25 +0100
committerSimon Martin <simon@nasilyan.com>2024-12-09 09:21:25 +0100
commit3076539544d3e36684cc8eed3374aeff5b44c9b1 (patch)
treed69c81fd5b584bb006480a7cb1eb2cb40a88289e /gcc
parentad94070689b3fadafca14c188c650aad6b8600e7 (diff)
downloadgcc-3076539544d3e36684cc8eed3374aeff5b44c9b1.zip
gcc-3076539544d3e36684cc8eed3374aeff5b44c9b1.tar.gz
gcc-3076539544d3e36684cc8eed3374aeff5b44c9b1.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/testsuite/g++.dg/asan/pr117845-2.C12
-rw-r--r--gcc/testsuite/g++.dg/asan/pr117845.C12
-rw-r--r--gcc/tree-eh.cc5
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 0000000..c055639
--- /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 0000000..d90d351
--- /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 769785f..e8af5fb 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))
{