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)) {