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

            Bug ID: 91848
           Summary: missing warning on strcpy past the end of a member of
                    an array with variable index
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

With pr91631 resolved, GCC 10 diagnoses past-the-end writes into character
arrays of members of arrays structs, whether they are declared objects or
accessed by reference, provided the index into the struct array is constant (as
in the arr_cst and ptr_cst functions below).  But when the index into the
struct array is not a constant (as in the arr_var and ptr_var functions below)
the warning doesn't trigger.

$ cat z.c && gcc -O2 -S -Wno-unused -Wall -Wextra z.c
extern char* strcpy (char*, const char*);

struct A { char a[3]; int i; };
struct B { int j; struct A a; };

extern struct B b[];

void arr_cst (void)
{
  struct A *q = &b[7].a;
  const char a[] = "0123456789";
  strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
}

void ptr_cst (struct B *p)
{
  struct A *q = &p[7].a;
  const char a[] = "0123456789";
  strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
}

void arr_var (int i)
{
  struct A *q = &b[i].a;
  const char a[] = "0123456789";
  strcpy (q->a, a + sizeof a - 4 - 1);   // missing warning
}

void ptr_var (struct B *p, int i)
{
  struct A *q = &p[i].a;
  const char a[] = "0123456789";
  strcpy (q->a, a + sizeof a - 4 - 1);   // missing warning
}


z.c: In function ‘arr_cst’:
z.c:12:3: warning: ‘strcpy’ offset [91, 92] from the object at ‘b’ is out of
the bounds of referenced subobject ‘a’ with type ‘char[3]’ at offset 88
[-Warray-bounds]
   12 |   strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
z.c:3:17: note: subobject ‘a’ declared here
    3 | struct A { char a[3]; int i; };
      |                 ^
z.c: In function ‘ptr_cst’:
z.c:19:3: warning: ‘strcpy’ offset 88 from the object at ‘p’ is out of the
bounds of referenced subobject ‘a’ with type ‘char[3]’ at offset 84
[-Warray-bounds]
   19 |   strcpy (q->a, a + sizeof a - 4 - 1);   // warning (good)
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
z.c:3:17: note: subobject ‘a’ declared here
    3 | struct A { char a[3]; int i; };
      |                 ^

Reply via email to