Mercurial > hg > CbC > CbC_gcc
diff gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-16.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-16.c Fri Oct 27 22:46:09 2017 +0900 @@ -0,0 +1,255 @@ +/* PR middle-end/80364 - sanitizer detects signed integer overflow + in gimple-ssa-sprintf.c + { dg-do compile } + { dg-options "-O2 -Wall -Wformat-overflow=1 -ftrack-macro-expansion=0" } + { dg-require-effective-target int32plus } */ + +typedef __SIZE_TYPE__ size_t; +typedef __WCHAR_TYPE__ wchar_t; + +void sink (void*); +void* get_value (void); + +/* Return a random width as type T. */ +#define W(T) *(T*)get_value () + +/* Return a random precision as type T. */ +#define P(T) *(T*)get_value () + +/* Return a random value as type T. */ +#define V(T) *(T*)get_value () + +extern char buf[1]; + +/* Test convenience macro. */ +#define T(fmt, ...) \ + __builtin_sprintf (buf + 1, fmt, __VA_ARGS__); \ + sink (buf) + +typedef signed char schar_t; +typedef unsigned char uchar_t; +typedef signed short sshort_t; +typedef unsigned short ushort_t; +typedef signed int sint_t; +typedef unsigned int uint_t; +typedef signed long slong_t; +typedef unsigned long ulong_t; +typedef signed long long sllong_t; +typedef unsigned long long ullong_t; + +#if __SIZEOF_INT128__ +typedef __int128_t sint128_t; +typedef __uint128_t uint128_t; +#else +/* When __int128_t is not available, repeat the same tests with long long. + This is to avoid having to guard the tests below and to avoid making + the dg-warning directives conditional. */ +typedef signed long long sint128_t; +typedef unsigned long long uint128_t; +#endif + +const sint128_t sint128_max + = (sint128_t)1 << (sizeof sint128_max * __CHAR_BIT__ - 2); +const sint128_t uint128_max = (uint128_t)-1; + +void test_width_cst (void) +{ + T ("%*i", W (schar_t), 1); /* { dg-warning "between 1 and 128 " } */ + T ("%*i", W (uchar_t), 12); /* { dg-warning "between 2 and 255 " } */ + + T ("%*i", W (sshort_t), 123); /* { dg-warning "between 3 and 32768 " } */ + T ("%*i", W (ushort_t), 1234); /* { dg-warning "between 4 and 65535 " } */ + + T ("%*i", W (sint_t), 12345); /* { dg-warning "between 5 and 2147483648 " } */ + T ("%*i", W (uint_t), 123456); /* { dg-warning "between 6 and 2147483648 " } */ + + /* Exercise calls with invalid arguments (to verify there is no ICE). */ + T ("%*li", W (slong_t), 1234567L); /* { dg-warning "between 7 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*li", W (ulong_t), 12345678L); /* { dg-warning "between 8 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%*lli", W (sllong_t), 123456789LL); /* { dg-warning "between 9 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*lli", W (ullong_t), 1234567890LL); /* { dg-warning "between 10 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%*i", W (sint128_t), 0); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*i", W (uint128_t), 1); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + { + extern sint128_t si128; + if (si128 < sint128_max / 2 || sint128_max - 8 < si128) + si128 = sint128_max / 2; + + T ("%*i", si128, 0); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + extern uint128_t ui128; + if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128) + ui128 = uint128_max / 2; + + T ("%*i", ui128, 0); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + } + + T ("%*i", W (float), 2); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*i", W (double), 3); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ +} + +void test_width_var (void) +{ + T ("%*i", W (schar_t), V (schar_t)); /* { dg-warning "between 1 and 128 " } */ + T ("%*i", W (uchar_t), V (uchar_t)); /* { dg-warning "between 1 and 255 " } */ + + T ("%*i", W (sshort_t), V (sshort_t)); /* { dg-warning "between 1 and 32768 " } */ + T ("%*i", W (ushort_t), V (ushort_t)); /* { dg-warning "between 1 and 65535 " } */ + + T ("%*i", W (sint_t), V (sint_t)); /* { dg-warning "between 1 and 2147483648 " } */ + T ("%*i", W (uint_t), V (uint_t)); /* { dg-warning "between 1 and 2147483648 " } */ + + /* Exercise calls with invalid arguments (to verify there is no ICE). */ + T ("%*li", W (slong_t), V (slong_t)); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*li", W (ulong_t), V (ulong_t)); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%*lli", W (sllong_t), V (sllong_t)); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*lli", W (ullong_t), V (ullong_t)); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%*i", W (float), V (int)); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%*i", W (double), V (int)); /* { dg-warning "between 1 and 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + { + /* Create an unsigned range with a lower bound greater than 1 and + an upper bound in excess of INT_MAX and verify that the lower + bound isn't used as the minimum output (since the excessive + upper bound wraps around zero). It's possible to constrain + the upper bound on the output more, based on the upper bound + of the width here, but not worth the trouble. */ + extern unsigned w; + if (w < 5 || (unsigned)-1 - 7 < w) + w = 5; + + T ("%*u", w, V (int)); /* { dg-warning "between 1 and 2147483648 " } */ + } + + { + /* Verify that enums are correctly handled (i.e., that the warning + doesn't just test for TREE_CODE(type) == INTEGER_TYPE but instead + uses INTEGRAL_TYPE_P() or some equivalent. */ + enum WidthEnum { e7 = 7, e9 = 9 }; + enum WidthEnum w = V (enum WidthEnum); + if (w < e7 || e9 < w) + w = e7; + + T ("%*hu", w, V (int)); /* { dg-warning "between 7 and 9 " } */ + } +} + +void test_precision_cst (void) +{ + T ("%.*i", P (schar_t), 1); /* { dg-warning "between 1 and 127 " } */ + T ("%.*i", P (uchar_t), 12); /* { dg-warning "between 2 and 255 " } */ + + T ("%.*i", P (sshort_t), 123); /* { dg-warning "between 3 and 32767 " } */ + T ("%.*i", P (ushort_t), 1234); /* { dg-warning "between 4 and 65535 " } */ + + T ("%.*i", P (sint_t), 12345); /* { dg-warning "between 5 and 2147483647 " } */ + T ("%.*i", P (uint_t), 123456); /* { dg-warning "between 6 and 2147483647 " } */ + + /* Exercise calls with invalid arguments (to verify there is no ICE). */ + T ("%.*li", P (slong_t), 1234567L); /* { dg-warning "between 7 and 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*li", P (ulong_t), 12345678L); /* { dg-warning "between 8 and 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%.*lli", P (sllong_t), 123456789LL); /* { dg-warning "between 9 and 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*lli", P (ullong_t), 1234567890LL); /* { dg-warning "between 10 and 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%.*i", P (sint128_t), 0); /* { dg-warning "up to 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*i", P (uint128_t), 1); /* { dg-warning "between 1 and 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + { + extern sint128_t si128; + if (si128 < sint128_max / 2 || sint128_max - 8 < si128) + si128 = sint128_max / 2; + + T ("%.*i", si128, 0); /* { dg-warning "up to 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + extern uint128_t ui128; + if (ui128 < uint128_max / 2 || uint128_max - 8 < ui128) + ui128 = uint128_max / 2; + + T ("%.*i", ui128, 0); /* { dg-warning "up to 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + } + + T ("%.*i", P (float), 0); /* { dg-warning "up to 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*i", P (double), 1); /* { dg-warning "between 1 and 2147483647 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ +} + +void test_precision_var (void) +{ + T ("%.*i", P (schar_t), V (schar_t)); /* { dg-warning "up to 128 " } */ + T ("%.*i", P (uchar_t), V (uchar_t)); /* { dg-warning "up to 255 " } */ + + T ("%.*i", P (sshort_t), V (sshort_t)); /* { dg-warning "up to 32768 " } */ + T ("%.*i", P (ushort_t), V (ushort_t)); /* { dg-warning "up to 65535 " } */ + + T ("%.*i", P (sint_t), V (sint_t)); /* { dg-warning "up to 2147483648 " } */ + T ("%.*i", P (uint_t), V (uint_t)); /* { dg-warning "up to 2147483648 " } */ + + /* Exercise calls with invalid arguments (to verify there is no ICE). */ + T ("%.*li", P (slong_t), V (slong_t)); /* { dg-warning "up to 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*li", P (ulong_t), V (ulong_t)); /* { dg-warning "up to 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%.*lli", P (sllong_t), V (sllong_t)); /* { dg-warning "up to 2147483648" } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*lli", P (ullong_t), V (ullong_t)); /* { dg-warning "up to 2147483648" } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + T ("%.*i", P (float), V (int)); /* { dg-warning "up to 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + T ("%.*i", P (double), V (int)); /* { dg-warning "up to 2147483648 " } */ + /* { dg-warning "expects argument of type .int." "" { target *-*-* } .-1 } */ + + { + /* Similar to the corresponding width case, create an unsigned range + with a lower bound greater than 1 and an upper bound in excess of + INT_MAX and verify that the lower bound isn't used as the minimum + output (since the excessive upper bound wraps around zero). */ + extern unsigned p; + if (p < 7 || (unsigned)-1 - 9 < p) + p = 7; + + T ("%.*u", p, V (int)); /* { dg-warning "up to 2147483647 " } */ + } + + { + /* Verify that enums are correctly handled. */ + enum PrecEnum { e9 = 9, e17 = 17 }; + enum PrecEnum p = V (enum PrecEnum); + if (p < e9 || e17 < p) + p = e9; + + T ("%.*u", p, V (int)); /* { dg-warning "between 9 and 17 " } */ + } +}