https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83185

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, the ICE is because without -fsanitize=address we have:
  struct [0:D.1901][1] * aps.0;
  struct [1] * _7;
  aps.0_10 = __builtin_alloca_with_align (_8, 64);
  _7 = &*aps.0_10[4];
  __builtin_va_start (_7, 0);
but with -fsanitize=address
  struct [1] * _7;
  struct [0:D.2257][1] * _17;
  struct [0:D.2257][1] * _18;
  _17 = __builtin_alloca_with_align (_16, 256);
  _18 = _17 + 32;
  __builtin___asan_alloca_poison (_18, _8);
  _7 = &MEM[(struct [0:D.2257][1] *)_17 + 32B][4];
  __builtin_va_start (_7, 0);
Now, tree-cfg.c verification is happy about this, in both
&*aps.0_10[4]
as well as
&MEM[(struct [0:D.2257][1] *)_17 + 32B][4]
but when the backend feeds that to build_simple_mem_ref_loc we reach:
4687      /* For convenience allow addresses that collapse to a simple base
4688         and offset.  */
4689      if (TREE_CODE (ptr) == ADDR_EXPR
4690          && (handled_component_p (TREE_OPERAND (ptr, 0))
4691              || TREE_CODE (TREE_OPERAND (ptr, 0)) == MEM_REF))
4692        {
4693          ptr = get_addr_base_and_unit_offset (TREE_OPERAND (ptr, 0),
&offset);
4694          gcc_assert (ptr);
4695          ptr = build_fold_addr_expr (ptr);
4696          gcc_assert (is_gimple_reg (ptr) || is_gimple_min_invariant
(ptr));
4697        }
which ICEs in the -fsanitize=address case, in the former case ptr after
build_fold_addr_expr is a SSA_NAME, but in the latter &MEM_REF[SSA_NAME + 32],
and because the base is SSA_NAME, not ADDR_EXPR, we don't really merge the two
offsets together.

So, is this a forwprop bug + checking bug that it created such ADDR_EXPR -
in cddce3 we still had:
  _17 = __builtin_alloca_with_align (_16, 256);
  _18 = _17 + 32;
  __builtin___asan_alloca_poison (_18, _8);
  _7 = &*_18[4];
  __builtin_va_start (_7, 0);
and then forwprop4 turns that into:
  _17 = __builtin_alloca_with_align (_16, 256);
  _18 = _17 + 32;
  __builtin___asan_alloca_poison (_18, _8);
  _7 = &MEM[(struct [0:D.2257][1] *)_17 + 32B][4];
  __builtin_va_start (_7, 0);
Or should build_simple_mem_ref_loc deal also with this case (such as seeing
that if ptr fails the above assert, but is ADDR_EXPR of a MEM_REF with SSA_NAME
base and constant, use the ptr base as the constant and add the offset to
offset)?  Or should all the backends and other spots that call
build_simple_mem_ref_loc gimplify the address instead?

Reply via email to