diff mbox series

[v2] eh: ICE with std::initializer_list and ASan [PR115865]

Message ID Zpg7jAuLdU7UVz3T@redhat.com
State New
Headers show
Series [v2] eh: ICE with std::initializer_list and ASan [PR115865] | expand

Commit Message

Marek Polacek July 17, 2024, 9:45 p.m. UTC
On Wed, Jul 17, 2024 at 01:37:23PM +0200, Jakub Jelinek wrote:
> On Thu, Jul 11, 2024 at 04:08:20PM -0400, Marek Polacek wrote:
> > and we ICE on the empty finally in lower_try_finally_onedest while
> > getting get_eh_else.
> > 
> > Rather than checking everywhere that a GIMPLE_TRY_FINALLY is not empty,
> > I thought we could process it as if it were unreachable.
> 
> I'm not sure we need to check everywhere, the only spot is get_eh_else
> from what I can see and IMHO that should be fixed with something like:

[...]

Okay, here's a v2 which does what you suggest:

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
Here we ICE with -fsanitize=address on

  std::initializer_list x = { 1, 2, 3 };

since r14-8681, which removed .ASAN_MARK calls on TREE_STATIC variables.
That means that lower_try_finally now instead of

  try
    {
      .ASAN_MARK (UNPOISON, &C.0, 12);
      x = {};
      x._M_len = 3;
      x._M_array = &C.0;
    }
  finally
    {
      .ASAN_MARK (POISON, &C.0, 12);
    }

gets:

  try
    {
      x = {};
      x._M_len = 3;
      x._M_array = &C.0;
    }
  finally
    {

    }

and we ICE on the empty finally in lower_try_finally_onedest while
getting get_eh_else.

	PR c++/115865

gcc/ChangeLog:

	* tree-eh.cc (get_eh_else): Check that the result of
	gimple_seq_first_stmt is non-null.

gcc/testsuite/ChangeLog:

	* g++.dg/asan/initlist2.C: New test.

Co-authored-by: Jakub Jelinek  <jakub@redhat.com>
---
 gcc/testsuite/g++.dg/asan/initlist2.C | 16 ++++++++++++++++
 gcc/tree-eh.cc                        |  2 +-
 2 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/asan/initlist2.C


base-commit: ec64666f97be24595ae0bc9055c19dabbe68a14c

Comments

Jakub Jelinek July 17, 2024, 9:48 p.m. UTC | #1
On Wed, Jul 17, 2024 at 05:45:48PM -0400, Marek Polacek wrote:
> On Wed, Jul 17, 2024 at 01:37:23PM +0200, Jakub Jelinek wrote:
> > On Thu, Jul 11, 2024 at 04:08:20PM -0400, Marek Polacek wrote:
> > > and we ICE on the empty finally in lower_try_finally_onedest while
> > > getting get_eh_else.
> > > 
> > > Rather than checking everywhere that a GIMPLE_TRY_FINALLY is not empty,
> > > I thought we could process it as if it were unreachable.
> > 
> > I'm not sure we need to check everywhere, the only spot is get_eh_else
> > from what I can see and IMHO that should be fixed with something like:
> 
> [...]
> 
> Okay, here's a v2 which does what you suggest:
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> -- >8 --
> Here we ICE with -fsanitize=address on
> 
>   std::initializer_list x = { 1, 2, 3 };
> 
> since r14-8681, which removed .ASAN_MARK calls on TREE_STATIC variables.
> That means that lower_try_finally now instead of
> 
>   try
>     {
>       .ASAN_MARK (UNPOISON, &C.0, 12);
>       x = {};
>       x._M_len = 3;
>       x._M_array = &C.0;
>     }
>   finally
>     {
>       .ASAN_MARK (POISON, &C.0, 12);
>     }
> 
> gets:
> 
>   try
>     {
>       x = {};
>       x._M_len = 3;
>       x._M_array = &C.0;
>     }
>   finally
>     {
> 
>     }
> 
> and we ICE on the empty finally in lower_try_finally_onedest while
> getting get_eh_else.
> 
> 	PR c++/115865
> 
> gcc/ChangeLog:
> 
> 	* tree-eh.cc (get_eh_else): Check that the result of
> 	gimple_seq_first_stmt is non-null.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/asan/initlist2.C: New test.

LGTM, thanks.

	Jakub
diff mbox series

Patch

diff --git a/gcc/testsuite/g++.dg/asan/initlist2.C b/gcc/testsuite/g++.dg/asan/initlist2.C
new file mode 100644
index 00000000000..bce5410be33
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/initlist2.C
@@ -0,0 +1,16 @@ 
+// PR c++/115865
+// { dg-do compile }
+// { dg-options "-fsanitize=address" }
+
+typedef decltype(sizeof(char)) size_t;
+
+namespace std {
+template <class> class initializer_list {
+  int *_M_array;
+  size_t _M_len;
+};
+}
+
+int main() {
+  std::initializer_list x = { 1, 2, 3 };
+}
diff --git a/gcc/tree-eh.cc b/gcc/tree-eh.cc
index a776ad5c92b..9609bdc0d9b 100644
--- a/gcc/tree-eh.cc
+++ b/gcc/tree-eh.cc
@@ -950,7 +950,7 @@  static inline geh_else *
 get_eh_else (gimple_seq finally)
 {
   gimple *x = gimple_seq_first_stmt (finally);
-  if (gimple_code (x) == GIMPLE_EH_ELSE)
+  if (x && gimple_code (x) == GIMPLE_EH_ELSE)
     {
       gcc_assert (gimple_seq_singleton_p (finally));
       return as_a <geh_else *> (x);