Fix -Wstringop-overflow regression

Message ID alpine.LSU.2.21.1804041332300.24055@wotan.suse.de
State New
Headers show
Series
  • Fix -Wstringop-overflow regression
Related show

Commit Message

Michael Matz April 4, 2018, 1:34 p.m.
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)


	* 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.

Comments

Richard Biener April 4, 2018, 2:15 p.m. | #1
On Wed, Apr 4, 2018 at 3:34 PM, Michael Matz <matz@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;

> +}
Michael Matz April 4, 2018, 2:50 p.m. | #2
Hi,

On Wed, 4 Apr 2018, Richard Biener wrote:

> Bootstrapped and tested ...?


Err, yes, on x86-64, with all languages and without regressions.

> OK.


r259083.


Ciao,
Michael.

Patch

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