Jakub Jelinek <jakub at gcc dot> changed:

           What    |Removed                     |Added
                 CC|                            |jakub at gcc dot,
                   |                            |law at gcc dot

--- Comment #5 from Jakub Jelinek <jakub at gcc dot> ---
Slightly cleaned up testcase:

struct S { int a; char b[10]; } d;
__SIZE_TYPE__ s;

foo (void)
  __builtin_strncpy (d.b, (char *) &d, s);

This code is a ticking bomb.
What is the base set builtin_memref::set_base_and_offset ?
Seems it is called with expr that is a pointer to something (i.e. arguments of
some strncpy-like function), but sometimes it sets base to the passed expr
(i.e. pointer to that memory), at other times to what it points to, at other
times to the get_inner_reference of what it points to.  Without a clear
agreement of what it is obviously spots like the new:
tree basetype = TREE_TYPE (TREE_TYPE (dstref->base));
are wrong, because it doesn't know if base is the pointer pointing to something
(the TREE_TYPE (TREE_TYPE (dstref->base)) assumes that and assumes it is a
POINTER_TYPE_P), or not.
If you sometimes need the pointer and sometimes what it points to, then either
you should have a flag that determines what base is, or better use different
members for pointer and base of what it points to.

What is the TREE_OPERAND (expr, 0) in:
  base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
                              &mode, &sign, &reverse, &vol);

  poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);

  HOST_WIDE_INT const_off;
  if (!base || !bytepos.is_constant (&const_off))
      base = get_base_address (TREE_OPERAND (expr, 0));
doing?  It doesn't seem you've checked what expr actually is before using
TREE_OPERAND (expr, 0) on it.  The cases that fall through into this code are
either that expr is an operand of ADDR_EXPR, or SSA_NAME, or in theory some
constant.  I don't think get_inner_reference ever returns NULL though.

Reply via email to