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

            Bug ID: 128376
           Summary: bogus -Wstringop-truncation for strncpy into a
                    nonstring struct member at a non-zero offset
           Product: gcc
           Version: 16.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 220245569 at seu dot edu.cn
                CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
  Target Milestone: ---
            Target: *-*-*

Reproducer
----------
$ cat trigger.c
struct S { char a[16] __attribute__ ((nonstring)); };
struct S s;
char arr[16] __attribute__ ((nonstring));

void f_member (const char *p)
{
  __builtin_strncpy (s.a + 4, p, 12);   /* bogus -Wstringop-truncation */
}

void f_array (const char *p)
{
  __builtin_strncpy (arr + 4, p, 12);   /* control: no warning */
}

Compile flag: x86_64-linux-gnu-gcc -O2 -Wall -c trigger.c

trigger.c: In function 'f_member':
trigger.c:7:3: warning: '__builtin_strncpy' specified bound 12 equals
destination size [-Wstringop-truncation]
    7 |   __builtin_strncpy (s.a + 4, p, 12);   /* bogus -Wstringop-truncation
*/
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# f_array (nonstring array, same offset): no warning

# -fdump-tree-strlen1
  __builtin_strncpy (&MEM <char[16]> [(void *)&s + 4B], p_2(D), 12);    #
member lost
  __builtin_strncpy (&MEM <char[16]> [(void *)&arr + 4B], p_2(D), 12);  # decl
has attribute

Root cause
----------
get_attr_nonstring_decl (gcc/tree.cc:15486) handles a MEM_REF by
recursing on TREE_OPERAND (decl, 0) (tree.cc:15523-15524).  For a member
at a non-zero offset the operand is &s, so the lookup ends at the VAR_DECL
's', which has no nonstring attribute, while the FIELD_DECL 'a' that has it
is no longer in the tree.  PR 85643 fixed the same symptom for plain arrays
(where the base decl itself carries the attribute) but not for members.
Still warns on GCC trunk (Compiler Explorer, 2026-11-01).  Related but
different: PR 118212 (variable index into an array of structs).

Suggested Fix
-------------
For a MEM_REF over &VAR with a constant offset, look up the FIELD_DECL
covering that offset in VAR's type (as get_ref_base_and_extent / the
-Wstringop-overflow component lookup does) and check its attributes.

Reply via email to