[gcc r13-6897] sanopt: Return TODO_cleanup_cfg if any .{UB, HWA, A}SAN_* calls were lowered [PR106190]

Jakub Jelinek jakub@gcc.gnu.org
Tue Mar 28 08:58:01 GMT 2023


https://gcc.gnu.org/g:39a43dc336561e0eba0de477b16c7355f19d84ee

commit r13-6897-g39a43dc336561e0eba0de477b16c7355f19d84ee
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Mar 28 10:56:44 2023 +0200

    sanopt: Return TODO_cleanup_cfg if any .{UB,HWA,A}SAN_* calls were lowered [PR106190]
    
    The following testcase ICEs, because without optimization eh lowering
    decides not to duplicate finally block of try/finally and so we end up
    with variable guarded cleanup.  The sanopt pass creates a cfg that ought
    to be cleaned up (some IFN_UBSAN_* functions are lowered in this case with
    constant conditions in gcond and when not allowing recovery some bbs which
    end with noreturn calls actually have successor edges), but the cfg cleanup
    is actually (it is -O0) done only during the optimized pass.  We notice
    there that the d[1][a] = 0; statement which has an EH edge is unreachable
    (because ubsan would always abort on the out of bounds d[1] access), remove
    the EH landing pad and block, but because that block just sets a variable
    and jumps to another one which tests that variable and that one is reachable
    from normal control flow, the __builtin_eh_pointer (1) later in there is
    kept in the IL and we ICE during expansion of that statement because the
    EH region has been removed.
    
    The following patch fixes it by doing the cfg cleanup already during
    sanopt pass if we create something that might need it, while the EH
    landing pad is then removed already during sanopt pass, there is ehcleanup
    later and we don't ICE anymore.
    
    2023-03-28  Jakub Jelinek  <jakub@redhat.com>
    
            PR middle-end/106190
            * sanopt.cc (pass_sanopt::execute): Return TODO_cleanup_cfg if any
            of the IFN_{UB,HWA,A}SAN_* internal fns are lowered.
    
            * gcc.dg/asan/pr106190.c: New test.

Diff:
---
 gcc/sanopt.cc                        |  6 +++++-
 gcc/testsuite/gcc.dg/asan/pr106190.c | 15 +++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/sanopt.cc b/gcc/sanopt.cc
index b356a21eca3..85489739507 100644
--- a/gcc/sanopt.cc
+++ b/gcc/sanopt.cc
@@ -1300,6 +1300,7 @@ pass_sanopt::execute (function *fun)
   basic_block bb;
   int asan_num_accesses = 0;
   bool contains_asan_mark = false;
+  int ret = 0;
 
   /* Try to remove redundant checks.  */
   if (optimize
@@ -1352,6 +1353,7 @@ pass_sanopt::execute (function *fun)
 	  if (gimple_call_internal_p (stmt))
 	    {
 	      enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	      int this_ret = TODO_cleanup_cfg;
 	      switch (ifn)
 		{
 		case IFN_UBSAN_NULL:
@@ -1387,8 +1389,10 @@ pass_sanopt::execute (function *fun)
 		  no_next = hwasan_expand_mark_ifn (&gsi);
 		  break;
 		default:
+		  this_ret = 0;
 		  break;
 		}
+	      ret |= this_ret;
 	    }
 	  else if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
 	    {
@@ -1418,7 +1422,7 @@ pass_sanopt::execute (function *fun)
   if (need_commit_edge_insert)
     gsi_commit_edge_inserts ();
 
-  return 0;
+  return ret;
 }
 
 } // anon namespace
diff --git a/gcc/testsuite/gcc.dg/asan/pr106190.c b/gcc/testsuite/gcc.dg/asan/pr106190.c
new file mode 100644
index 00000000000..10eb2789a49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr106190.c
@@ -0,0 +1,15 @@
+/* PR middle-end/106190 */
+/* { dg-do compile } */
+/* { dg-options "-fnon-call-exceptions -fsanitize=address,undefined -fno-sanitize-recover=all" } */
+
+int
+main ()
+{
+  int a;
+  int *b[1];
+  int c[10];
+  int d[1][1];
+  for (a = 0; a < 1; a++)
+    d[1][a] = 0;
+  return 0;
+}


More information about the Gcc-cvs mailing list