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;
  }

Reply via email to