PR analyzer/96949 reports an ICE within -fanalyzer on a Fortran test case with --param analyzer-max-svalue-depth=0, where that param value leads to INTEGER_CST values in a RANGE_EXPR being treated as unknown symbolic values.
This patch replaces implicit assumptions that these values are concrete (and thus have concrete bit offsets), adding error-handling for symbolic cases instead of assertions, fixing the ICE. I'm taking the liberty of adding the reproducer for this to gfortran.dg/analyzer as a regression test; hope that's OK. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to master as r11-3052-g34d926dba097c4965917d09a3eedec11242c5457. gcc/analyzer/ChangeLog: PR analyzer/96949 * store.cc (binding_map::apply_ctor_val_to_range): Add error-handling for the cases where we have symbolic offsets. gcc/testsuite/ChangeLog: PR analyzer/96949 * gfortran.dg/analyzer/pr96949.f90: New test. --- gcc/analyzer/store.cc | 8 ++++++-- .../gfortran.dg/analyzer/pr96949.f90 | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/analyzer/pr96949.f90 diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 94bcbecce88..1348895e5c7 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -466,11 +466,14 @@ binding_map::apply_ctor_val_to_range (const region *parent_reg, const region *max_element = get_subregion_within_ctor (parent_reg, max_index, mgr); region_offset min_offset = min_element->get_offset (); + if (min_offset.symbolic_p ()) + return false; bit_offset_t start_bit_offset = min_offset.get_bit_offset (); store_manager *smgr = mgr->get_store_manager (); const binding_key *max_element_key = binding_key::make (smgr, max_element, BK_direct); - gcc_assert (max_element_key->concrete_p ()); + if (max_element_key->symbolic_p ()) + return false; const concrete_binding *max_element_ckey = max_element_key->dyn_cast_concrete_binding (); bit_size_t range_size_in_bits @@ -478,7 +481,8 @@ binding_map::apply_ctor_val_to_range (const region *parent_reg, const concrete_binding *range_key = smgr->get_concrete_binding (start_bit_offset, range_size_in_bits, BK_direct); - gcc_assert (range_key->concrete_p ()); + if (range_key->symbolic_p ()) + return false; /* Get the value. */ if (TREE_CODE (val) == CONSTRUCTOR) diff --git a/gcc/testsuite/gfortran.dg/analyzer/pr96949.f90 b/gcc/testsuite/gfortran.dg/analyzer/pr96949.f90 new file mode 100644 index 00000000000..4af96bb9676 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/analyzer/pr96949.f90 @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-additional-options "-Wno-analyzer-too-complex --param analyzer-max-svalue-depth=0" } + +program n6 + integer :: ck(2,2) + integer :: ac + + data ck /4 * 1/ + + call x9() + +contains + subroutine x9() + if (ck(2, 1) == 1) then + ac = 1 + else + ac = 0 + end if + end subroutine x9 +end program n6 -- 2.26.2