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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |8.3

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Martin Sebor from comment #1)
> Confirmed with the simplified C test case below.  The warning sees a MEM_REF
> (char[4], ...) as the destination of the strncpy call.  Why the type is
> char[4] is a mystery to me.  I guess the type in MEM_REF really can't be
> trusted.
> 
> 
> gcc -O2 -S -Wall -fdump-tree-optimized=/dev/stdout pr87296.c 
> 
> ;; Function g (g, funcdef_no=0, decl_uid=1913, cgraph_uid=1, symbol_order=0)
> 
> g (struct S * p, const char * s)
> {
>   void * _1;
>   char[4] * _2;
> 
>   <bb 2> [local count: 1073741824]:
>   _1 = &MEM[(void *)p_3(D) + 4B];
>   _2 = &p_3(D)->a;
>   f (_2, _1);
>   __builtin_strncpy (_1, s_6(D), 6); [tail call]
>   return;
> 
> }
> 
> 
> pr87296.c: In function ‘g’:
> pr87296.c:11:3: warning: ‘__builtin_strncpy’ writing 6 bytes into a region
> of size 4 overflows the destination [-Wstringop-overflow=]
> 11 |   __builtin_strncpy (p->b, s, sizeof p->b);
>    |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

quite likely because

  char[4] * _1;
  const char * _2;
...
  _1 = &c_8->ids;
  _2 = _1 + 4;

and forwprop combines the address calculation, re-using the type of _1.
For IL consistency if the ADDR_EXPR has type char[4] * then its operand
has to have type char[4].  [that's GENERIC constraints]

        /* Technically there is no longer a need for matching types, but
           gimple hygiene asks for this check.  In LTO we can end up
           combining incompatible units and thus end up with addresses
           of globals that change their type to a common one.  */
        if (!in_lto_p
            && !types_compatible_p (TREE_TYPE (op),
                                    TREE_TYPE (TREE_TYPE (rhs1)))
            && !one_pointer_to_useless_type_conversion_p (TREE_TYPE (rhs1),
                                                          TREE_TYPE (op)))
          {
            error ("type mismatch in address expression");
            debug_generic_stmt (TREE_TYPE (rhs1));
            debug_generic_stmt (TREE_TYPE (op));
            return true;
          }

other than that - types on addresses are random.

Reply via email to