https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84526
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org,
| |law at gcc dot gnu.org
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Slightly cleaned up testcase:
struct S { int a; char b[10]; } d;
__SIZE_TYPE__ s;
void
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));
return;
}
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.