On Wed, Apr 4, 2018 at 3:34 PM, Michael Matz <m...@suse.de> wrote: > Hi, > > we shouldn't claim string overflows for character arrays at > end of structures; the code that tries to avoid these > accidentally passed the address of the accessed member to > array_at_struct_end_p(), but that one wants the component_ref > or array_ref itself. Needs updating of one testcase that > incorrectly expected warning to occur in this situation. > (The regression is that we warn about the testcase now, where we > didn't warn before)
Bootstrapped and tested ...? OK. Thanks, Richard. > > * builtins.c (compute_objsize): Pass correct operand > to array_at_struct_end_p. > > testsuite/ > * gcc.dg/Wstringop-overflow-4.c: New test. > * c-c++-common/Wstringop-truncation-4.c: Adjust. > > diff --git a/gcc/builtins.c b/gcc/builtins.c > index 487d9d5..3554cdb 100644 > --- a/gcc/builtins.c > +++ b/gcc/builtins.c > @@ -3379,7 +3379,7 @@ compute_objsize (tree dest, int ostype) > type = TYPE_MAIN_VARIANT (type); > > if (TREE_CODE (type) == ARRAY_TYPE > - && !array_at_struct_end_p (dest)) > + && !array_at_struct_end_p (TREE_OPERAND (dest, 0))) > { > /* Return the constant size unless it's zero (that's a zero-length > array likely at the end of a struct). */ > diff --git a/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c > b/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c > index c4ad4d6..c76f282 100644 > --- a/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c > +++ b/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c > @@ -23,7 +23,7 @@ void test_arrays (struct Arrays *p, const char *s) > { > strncpy (p->a, s, sizeof p->a); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > strncpy ((char*)p->b, s, sizeof p->b); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > - strncpy ((char*)p->c, s, sizeof p->c); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > + strncpy ((char*)p->c, s, sizeof p->c); /* { dg-bogus > "\\\[-Wstringop-truncation" } */ > } > > struct Pointers > @@ -51,7 +51,7 @@ void test_const_arrays (struct ConstArrays *p, const char > *s) > { > strncpy ((char*)p->a, s, sizeof p->a); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > strncpy ((char*)p->b, s, sizeof p->b); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > - strncpy ((char*)p->c, s, sizeof p->c); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > + strncpy ((char*)p->c, s, sizeof p->c); /* { dg-bogus > "\\\[-Wstringop-truncation" } */ > } > > struct ConstPointers > @@ -79,7 +79,7 @@ void test_volatile_arrays (struct VolatileArrays *p, const > char *s) > { > strncpy ((char*)p->a, s, sizeof p->a); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > strncpy ((char*)p->b, s, sizeof p->b); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > - strncpy ((char*)p->c, s, sizeof p->c); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > + strncpy ((char*)p->c, s, sizeof p->c); /* { dg-bogus > "\\\[-Wstringop-truncation" } */ > } > > struct VolatilePointers > @@ -107,7 +107,7 @@ void test_const_volatile_arrays (struct > ConstVolatileArrays *p, const char *s) > { > strncpy ((char*)p->a, s, sizeof p->a); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > strncpy ((char*)p->b, s, sizeof p->b); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > - strncpy ((char*)p->c, s, sizeof p->c); /* { dg-warning > "\\\[-Wstringop-truncation" } */ > + strncpy ((char*)p->c, s, sizeof p->c); /* { dg-bogus > "\\\[-Wstringop-truncation" } */ > } > > struct ConstVolatilePointers > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-4.c > b/gcc/testsuite/gcc.dg/Wstringop-overflow-4.c > new file mode 100644 > index 0000000..5905b26 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-4.c > @@ -0,0 +1,28 @@ > +/* { dg-do compile } > + { dg-options "-O2 -Wstringop-overflow" } */ > + > +extern char* strchr (const char*, int); > +extern char* strcpy (char*, const char*); > +extern void* malloc (__SIZE_TYPE__); > +extern __SIZE_TYPE__ strlen (const char *); > +struct define_item { > + int len; > + char value[1]; > +}; > + > +struct define_item * foo(char *name) > +{ > + char * p; > + char * value; > + struct define_item * ptr; > + > + p = strchr (name, '='); > + if (1 && p) { > + value = p+1; > + } else > + value = "1"; > + > + ptr = malloc(sizeof(struct define_item) + strlen(value)); > + strcpy(ptr->value, value); /* { dg-bogus "bytes into a region" } */ > + return ptr; > +}