On 6/27/19 11:04 AM, Jakub Jelinek wrote:
On Thu, Jun 27, 2019 at 10:58:25AM -0600, Martin Sebor wrote:
The LHS is unsigned short so handle_char_store would not be called
because of the check in the caller. You would need something like:
MEM <char[2]> [(char *)&x] = { 'a', 'b' };
This is invalid, because the rhs is non-empty CONSTRUCTOR that doesn't have
VECTOR_TYPE - verify_gimple_assign_single has:
case CONSTRUCTOR:
if (TREE_CODE (rhs1_type) == VECTOR_TYPE)
...
else if (CONSTRUCTOR_NELTS (rhs1) != 0)
{
error ("non-vector %qs with elements", code_name);
debug_generic_stmt (rhs1);
return true;
}
But
MEM <char[2]> [(char *)&x] = MEM <char[2]> [(char *)"ab"];
Thanks. A test case that uses this is below. It's handled correctly
because the RHS is not all non-zero bytes (storing_nonzero_p is false.
The block Jeff is concerned about is the one below:
else if (storing_nonzero_p
&& cmp > 0
&& TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
{
gsi_next (gsi);
return false;
so what would be needed to show an outstanding problem even with
the patch applied (i.e., the INTEGER_TYPE check) is a RHS that's
interpreted as all nonzero bytes despite having a nul byte in its
representation. I.e., an integer that initializer_zerop() sets
the second argument to true for, or tree_expr_nonzero_p (RHS)
returns true for.
Both initializer_zerop and tree_expr_nonzero_p give up on this
representation even though they could handle it because it's
a constant. Handling it would be an improvement but it would
still return false. What we need is a scalar for the RHS that
is non-zero with a nul byte in it. That would do it, but I
don't know how to create it or if it's even possible.
Martin
char b[10];
const char a[2] = "4";
int f (const char *s)
{
__builtin_strcpy (b, "123");
int i = __builtin_strcmp (s, b);
// MEM <unsigned char[2]> [(char * {ref-all})&b]
// = MEM <unsigned char[2]> [(char * {ref-all})&a];
__builtin_memcpy (b, a, 2);
if (__builtin_strlen (b) != 1)
__builtin_abort ();
return i;
}