diff options
author | Simon Martin <simon@nasilyan.com> | 2024-12-09 09:21:25 +0100 |
---|---|---|
committer | Simon Martin <simon@nasilyan.com> | 2024-12-09 09:21:25 +0100 |
commit | 3076539544d3e36684cc8eed3374aeff5b44c9b1 (patch) | |
tree | d69c81fd5b584bb006480a7cb1eb2cb40a88289e /gcc | |
parent | ad94070689b3fadafca14c188c650aad6b8600e7 (diff) | |
download | gcc-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.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/asan/pr117845.C | 12 | ||||
-rw-r--r-- | 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 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)) { |