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.
--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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);
+ }
+}
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))
{