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 <ja...@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 <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)