@@ -824,7 +824,7 @@ instrument_mem_region_access (tree base,
access to the last byte of the argument; it uses the result of the
call to deduce the offset of that last byte. */
-static void
+static bool
instrument_strlen_call (gimple_stmt_iterator *iter)
{
gimple call = gsi_stmt (*iter);
@@ -839,7 +839,7 @@ instrument_strlen_call (gimple_stmt_iter
if (len == NULL)
/* Some passes might clear the return value of the strlen call;
bail out in that case. */
- return;
+ return false;
gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (len)));
location_t loc = gimple_location (call);
@@ -881,13 +881,20 @@ instrument_strlen_call (gimple_stmt_iter
/*before_p=*/false, /*is_store=*/false, 1);
/* Ensure that iter points to the statement logically following the
- one it was initially pointing to. */
+ one it was initially pointing to. Return true to inform
+ transform_statements that it shouldn't do gsi_next (&i) in that
+ case, that statement is the first statement in a block that would
+ be otherwise skipped (too high block number), by doing gsi_next (&i)
+ either that statement wouldn't be instrumented or, if there are no
+ statement, transform_statements could crash in gsi_next (&i). */
*iter = gsi;
+ return true;
}
-/* if the statement pointed to by the iterator iter is a call to a
- builtin memory access function, instrument it and return true.
- otherwise, return false. */
+/* If the statement pointed to by the iterator iter is a call to a
+ builtin memory access function, instrument it. Return true
+ if *ITER should be processed next, false if gsi_next should
+ be done on it first. */
static bool
maybe_instrument_builtin_call (gimple_stmt_iterator *iter)
@@ -951,8 +958,7 @@ maybe_instrument_builtin_call (gimple_st
break;
case BUILT_IN_STRLEN:
- instrument_strlen_call (iter);
- return true;
+ return instrument_strlen_call (iter);
/* And now the __atomic* and __sync builtins.
These are handled differently from the classical memory memory
@@ -1170,7 +1176,7 @@ maybe_instrument_builtin_call (gimple_st
gcc_unreachable ();
instrument_derefs (iter, dest, loc, is_store);
- return true;
+ return false;
}
default:
@@ -1191,7 +1197,8 @@ maybe_instrument_builtin_call (gimple_st
else if (dest != NULL_TREE)
instrument_mem_region_access (dest, len, iter,
loc, /*is_store=*/true);
- return true;
+ *iter = gsi_for_stmt (call);
+ return false;
}
return false;
}
@@ -1217,10 +1224,10 @@ instrument_assignment (gimple_stmt_itera
calls that are instrumented are some built-in functions that access
memory. Look at maybe_instrument_builtin_call to learn more. */
-static void
+static bool
maybe_instrument_call (gimple_stmt_iterator *iter)
{
- maybe_instrument_builtin_call (iter);
+ return maybe_instrument_builtin_call (iter);
}
/* asan: this looks too complex. Can this be done simpler? */
@@ -1239,14 +1246,19 @@ transform_statements (void)
FOR_EACH_BB (bb)
{
if (bb->index >= saved_last_basic_block) continue;
- for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); )
{
gimple s = gsi_stmt (i);
if (gimple_assign_single_p (s))
instrument_assignment (&i);
else if (is_gimple_call (s))
- maybe_instrument_call (&i);
+ {
+ if (maybe_instrument_call (&i))
+ /* Avoid gsi_next (&i). */
+ continue;
+ }
+ gsi_next (&i);
}
}
}