public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix ubsan_type_descriptor
@ 2017-07-31  7:49 Jakub Jelinek
  2017-07-31  8:09 ` Richard Biener
  0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2017-07-31  7:49 UTC (permalink / raw)
  To: Richard Biener, Marek Polacek; +Cc: gcc-patches

Hi!

Last week I've finally decided to find time to look into sometimes very
weird signed-integer-overflow runtime messages, which report that say
signed integer overflow: 1234567890123456 \\* 1234567890123456 cannot be represented in type 'long int[10]'
Obviously the integer overflow is not happening in an array type.

The problem is that ubsan_type_descriptor needs for a couple of spots the
element type and changes the type parameter to the element type, but then
it adds the result into the hash table using that type, instead of the
TYPE_MAIN_VARIANT of the type with which the function has been originally
called, so if we first record say bounds violation on long int[10],
we actually create "long int[10]" object and record it for long int type,
and then when we look up long int, we get this (and lookup for long int[10]
next time isn't successful and creates another object).

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk and release branches?

2017-07-31  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/81604
	* ubsan.c (ubsan_type_descriptor): For UBSAN_PRINT_ARRAY don't
	change type to the element type, instead add eltype variable and
	use it where we are interested in the element type.

	* c-c++-common/ubsan/pr81604.c: New test.

--- gcc/ubsan.c.jj	2017-07-28 12:35:27.000000000 +0200
+++ gcc/ubsan.c	2017-07-28 18:11:21.686219421 +0200
@@ -402,6 +402,7 @@ ubsan_type_descriptor (tree type, enum u
     /* We weren't able to determine the type name.  */
     tname = "<unknown>";
 
+  tree eltype = type;
   if (pstyle == UBSAN_PRINT_POINTER)
     {
       pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
@@ -452,12 +453,12 @@ ubsan_type_descriptor (tree type, enum u
       pp_quote (&pretty_name);
 
       /* Save the tree with stripped types.  */
-      type = t;
+      eltype = t;
     }
   else
     pp_printf (&pretty_name, "'%s'", tname);
 
-  switch (TREE_CODE (type))
+  switch (TREE_CODE (eltype))
     {
     case BOOLEAN_TYPE:
     case ENUMERAL_TYPE:
@@ -467,9 +468,9 @@ ubsan_type_descriptor (tree type, enum u
     case REAL_TYPE:
       /* FIXME: libubsan right now only supports float, double and
 	 long double type formats.  */
-      if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
-	  || TYPE_MODE (type) == TYPE_MODE (double_type_node)
-	  || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
+      if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
+	  || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
+	  || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
 	tkind = 0x0001;
       else
 	tkind = 0xffff;
@@ -478,7 +479,7 @@ ubsan_type_descriptor (tree type, enum u
       tkind = 0xffff;
       break;
     }
-  tinfo = get_ubsan_type_info_for_type (type);
+  tinfo = get_ubsan_type_info_for_type (eltype);
 
   /* Create a new VAR_DECL of type descriptor.  */
   const char *tmp = pp_formatted_text (&pretty_name);
--- gcc/testsuite/c-c++-common/ubsan/pr81604.c.jj	2017-07-28 18:20:52.471352034 +0200
+++ gcc/testsuite/c-c++-common/ubsan/pr81604.c	2017-07-28 18:25:54.398733100 +0200
@@ -0,0 +1,31 @@
+/* PR sanitizer/81604 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds,signed-integer-overflow" } */
+
+long a[10];
+
+__attribute__((noinline, noclone)) long *
+foo (int i)
+{
+  return &a[i];
+}
+
+__attribute__((noinline, noclone)) long
+bar (long x, long y)
+{
+  return x * y;
+}
+
+int
+main ()
+{
+  volatile int i = -1;
+  volatile long l = __LONG_MAX__;
+  long *volatile p;
+  p = foo (i);
+  l = bar (l, l);
+  return 0;
+}
+
+/* { dg-output "index -1 out of bounds for type 'long int \\\[10\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*signed integer overflow: \[0-9]+ \\* \[0-9]+ cannot be represented in type 'long int'" } */

	Jakub

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] Fix ubsan_type_descriptor
  2017-07-31  7:49 [PATCH] Fix ubsan_type_descriptor Jakub Jelinek
@ 2017-07-31  8:09 ` Richard Biener
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2017-07-31  8:09 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Marek Polacek, gcc-patches

On Mon, 31 Jul 2017, Jakub Jelinek wrote:

> Hi!
> 
> Last week I've finally decided to find time to look into sometimes very
> weird signed-integer-overflow runtime messages, which report that say
> signed integer overflow: 1234567890123456 \\* 1234567890123456 cannot be represented in type 'long int[10]'
> Obviously the integer overflow is not happening in an array type.
> 
> The problem is that ubsan_type_descriptor needs for a couple of spots the
> element type and changes the type parameter to the element type, but then
> it adds the result into the hash table using that type, instead of the
> TYPE_MAIN_VARIANT of the type with which the function has been originally
> called, so if we first record say bounds violation on long int[10],
> we actually create "long int[10]" object and record it for long int type,
> and then when we look up long int, we get this (and lookup for long int[10]
> next time isn't successful and creates another object).
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk and release branches?

Ok.

Thanks,
Richard.

> 2017-07-31  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR sanitizer/81604
> 	* ubsan.c (ubsan_type_descriptor): For UBSAN_PRINT_ARRAY don't
> 	change type to the element type, instead add eltype variable and
> 	use it where we are interested in the element type.
> 
> 	* c-c++-common/ubsan/pr81604.c: New test.
> 
> --- gcc/ubsan.c.jj	2017-07-28 12:35:27.000000000 +0200
> +++ gcc/ubsan.c	2017-07-28 18:11:21.686219421 +0200
> @@ -402,6 +402,7 @@ ubsan_type_descriptor (tree type, enum u
>      /* We weren't able to determine the type name.  */
>      tname = "<unknown>";
>  
> +  tree eltype = type;
>    if (pstyle == UBSAN_PRINT_POINTER)
>      {
>        pp_printf (&pretty_name, "'%s%s%s%s%s%s%s",
> @@ -452,12 +453,12 @@ ubsan_type_descriptor (tree type, enum u
>        pp_quote (&pretty_name);
>  
>        /* Save the tree with stripped types.  */
> -      type = t;
> +      eltype = t;
>      }
>    else
>      pp_printf (&pretty_name, "'%s'", tname);
>  
> -  switch (TREE_CODE (type))
> +  switch (TREE_CODE (eltype))
>      {
>      case BOOLEAN_TYPE:
>      case ENUMERAL_TYPE:
> @@ -467,9 +468,9 @@ ubsan_type_descriptor (tree type, enum u
>      case REAL_TYPE:
>        /* FIXME: libubsan right now only supports float, double and
>  	 long double type formats.  */
> -      if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
> -	  || TYPE_MODE (type) == TYPE_MODE (double_type_node)
> -	  || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
> +      if (TYPE_MODE (eltype) == TYPE_MODE (float_type_node)
> +	  || TYPE_MODE (eltype) == TYPE_MODE (double_type_node)
> +	  || TYPE_MODE (eltype) == TYPE_MODE (long_double_type_node))
>  	tkind = 0x0001;
>        else
>  	tkind = 0xffff;
> @@ -478,7 +479,7 @@ ubsan_type_descriptor (tree type, enum u
>        tkind = 0xffff;
>        break;
>      }
> -  tinfo = get_ubsan_type_info_for_type (type);
> +  tinfo = get_ubsan_type_info_for_type (eltype);
>  
>    /* Create a new VAR_DECL of type descriptor.  */
>    const char *tmp = pp_formatted_text (&pretty_name);
> --- gcc/testsuite/c-c++-common/ubsan/pr81604.c.jj	2017-07-28 18:20:52.471352034 +0200
> +++ gcc/testsuite/c-c++-common/ubsan/pr81604.c	2017-07-28 18:25:54.398733100 +0200
> @@ -0,0 +1,31 @@
> +/* PR sanitizer/81604 */
> +/* { dg-do run } */
> +/* { dg-options "-fsanitize=bounds,signed-integer-overflow" } */
> +
> +long a[10];
> +
> +__attribute__((noinline, noclone)) long *
> +foo (int i)
> +{
> +  return &a[i];
> +}
> +
> +__attribute__((noinline, noclone)) long
> +bar (long x, long y)
> +{
> +  return x * y;
> +}
> +
> +int
> +main ()
> +{
> +  volatile int i = -1;
> +  volatile long l = __LONG_MAX__;
> +  long *volatile p;
> +  p = foo (i);
> +  l = bar (l, l);
> +  return 0;
> +}
> +
> +/* { dg-output "index -1 out of bounds for type 'long int \\\[10\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
> +/* { dg-output "\[^\n\r]*signed integer overflow: \[0-9]+ \\* \[0-9]+ cannot be represented in type 'long int'" } */
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-07-31  8:09 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-07-31  7:49 [PATCH] Fix ubsan_type_descriptor Jakub Jelinek
2017-07-31  8:09 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).