analyzer: restore input_location (PR 93349)

Message ID
State New
Headers show
  • analyzer: restore input_location (PR 93349)
Related show

Commit Message

David Malcolm Jan. 24, 2020, 4:17 p.m.
PR analyzer/93349 reports an ICE in IPA pass: simdclone for
some input files when -fanalyzer is supplied, with:
  error: location references block not in block tree

The root cause is that the analyzer touches input_location in some
places (to make it easier to track down which source construct the
analyzer can't handle in the case of an analyzer ICE) and fails to reset
it.  For the ICE in question, this sets input_location to a location_t
that references some arbitrary block (specifically, that of the last
statement to be analyzed, within the original CFG of whichever is the
last such function to be analyzed).

Later, within omp-simd-clone.c, input_location is used by gimplify_expr
(called via gimplify_and_add), which has:

14492	      if (!gimple_seq_empty_p (*pre_p))
14493		annotate_all_with_location_after (*pre_p, pre_last_gsi, input_location);

thus using whatever the value of input_location is, leading
to statements that reference some arbitrary block in the original CFG.
For the reproducer, this happens to be a block in the CFG for the
original function, rather than that of the clone, but in general it
could be some arbitrary other function in the TU.

This code appears to assume that input_location has some arbitrary
value *not* in the block tree, which is potentially violated by the
analyzer's changes to input_location.

This patch adds a save and restore of input_location at the top-level
function of the analyzer, fixing the ICE.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for master?

	PR analyzer/93349
	* (run_checkers): Save and restore input_location.

	PR analyzer/93349
	* gcc.dg/analyzer/torture/pr93349.c: New test.
 gcc/analyzer/                          | 8 ++++++++
 gcc/testsuite/gcc.dg/analyzer/torture/pr93349.c | 4 ++++
 2 files changed, 12 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/torture/pr93349.c



diff --git a/gcc/analyzer/ b/gcc/analyzer/
index 939401140e7..b881a1d9218 100644
--- a/gcc/analyzer/
+++ b/gcc/analyzer/
@@ -3589,6 +3589,9 @@  impl_run_checkers (logger *logger)
 run_checkers ()
+  /* Save input_location.  */
+  location_t saved_input_location = input_location;
   /* Handle -fdump-analyzer and -fdump-analyzer-stderr.  */
   FILE *dump_fout = NULL;
   /* Track if we're responsible for closing dump_fout.  */
@@ -3619,6 +3622,11 @@  run_checkers ()
   if (owns_dump_fout)
     fclose (dump_fout);
+  /* Restore input_location.  Subsequent passes may assume that input_location
+     is some arbitrary value *not* in the block tree, which might be violated
+     if we didn't restore it.  */
+  input_location = saved_input_location;
 } // namespace ana
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr93349.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr93349.c
new file mode 100644
index 00000000000..a9d06367722
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr93349.c
@@ -0,0 +1,4 @@ 
+__attribute__ ((simd)) void
+test (void)