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. Successfully tested on x86_64-pc-linux-gnu. OK for trunk and gcc-14? 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. --- gcc/testsuite/g++.dg/asan/pr117845-2.C | 12 ++++++++++++ gcc/testsuite/g++.dg/asan/pr117845.C | 12 ++++++++++++ gcc/tree-eh.cc | 3 ++- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/asan/pr117845-2.C create mode 100644 gcc/testsuite/g++.dg/asan/pr117845.C 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 00000000000..c0556397009 --- /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 00000000000..d90d351e270 --- /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 769785fad2b..dc920de9b38 100644 --- a/gcc/tree-eh.cc +++ b/gcc/tree-eh.cc @@ -1026,7 +1026,8 @@ honor_protect_cleanup_actions (struct leh_state *outer_state, MUST_NOT_THROW filter. */ gimple_stmt_iterator gsi = gsi_start (finally); gimple *x = gsi_stmt (gsi); - if (gimple_code (x) == GIMPLE_TRY + if (x + && gimple_code (x) == GIMPLE_TRY && gimple_try_kind (x) == GIMPLE_TRY_CATCH && gimple_try_catch_is_cleanup (x)) { -- 2.44.0