1 /* PR tree-optimization/97027 - missing warning on buffer overflow storing
2    a larger scalar into a smaller array
3    Verify warnings for overflow by stores of results of built-in functions.
4    { dg-do compile }
5    { dg-options "-O2" } */
6 
7 typedef __INT16_TYPE__ int16_t;
8 typedef __SIZE_TYPE__  size_t;
9 
10 extern int abs (int);
11 
12 extern void* alloca (size_t);
13 
14 extern double nan (const char *);
15 
16 #ifdef __DEC32_MAX__
17   _Decimal32 nand32 (const char *);
18 #else
19 /* _Decimal32 is supported only conditionally and not available on all
20    targets.  */
21 #  define _Decimal32  double
22 #  define nand32(s)   nan (s)
23 #endif
24 
25 extern size_t strlen (const char *);
26 extern char* strcpy (char *, const char *);
27 
28 
29 extern unsigned char ax[], a1[1], a2[2], a8[8];
30 
31 
nowarn_abs(int i)32 void nowarn_abs (int i)
33 {
34   *(int *)ax = abs (i);
35   *(char *)a1 = abs (i);
36 }
37 
warn_abs(int i)38 void warn_abs (int i)
39 {
40   *(int *)a1 = abs (i);         // { dg-warning "\\\[-Wstringop-overflow" }
41 }
42 
43 
nowarn_alloca(size_t n)44 void nowarn_alloca (size_t n)
45 {
46   *(void **)ax = alloca (n);
47 }
48 
warn_alloca(size_t n)49 void warn_alloca (size_t n)
50 {
51   *(void **)a1 = alloca (n);    // { dg-warning "\\\[-Wstringop-overflow" }
52 }
53 
54 
nowarn_complex(double x,double i)55 void nowarn_complex (double x, double i)
56 {
57   *(_Complex double *)ax = __builtin_complex (x, i);
58 }
59 
warn_complex(double x,double i)60 void warn_complex (double x, double i)
61 {
62   _Complex double *p = (_Complex double *)a1;
63   *p = __builtin_complex (x, i);  // { dg-warning "\\\[-Wstringop-overflow" "pr101455" { xfail *-*-* } }
64 }
65 
66 
nowarn_nan(const char * s)67 __attribute__ ((noipa)) void nowarn_nan (const char *s)
68 {
69   *(double *)ax = nan (s);
70 }
71 
warn_nan(const char * s)72 __attribute__ ((noipa)) void warn_nan (const char *s)
73 {
74   *(double *)a1 = nan (s);      // { dg-warning "\\\[-Wstringop-overflow" }
75 }
76 
77 
nowarn_nand32(const char * s)78 __attribute__ ((noipa)) void nowarn_nand32 (const char *s)
79 {
80   *(_Decimal32 *)ax = nand32 (s);
81 }
82 
warn_nand32(const char * s)83 __attribute__ ((noipa)) void warn_nand32 (const char *s)
84 {
85   *(_Decimal32 *)a1 = nand32 (s); // { dg-warning "\\\[-Wstringop-overflow" }
86 }
87 
88 
nowarn_strlen(const char * s1,const char * s2,const char * s3)89 void nowarn_strlen (const char *s1, const char *s2, const char *s3)
90 {
91   *(char *)ax = strlen (s1);
92   *(char *)a1 = strlen (s2);
93   *(size_t *)a8 = strlen (s3);
94 }
95 
warn_strlen(const char * s1,const char * s2)96 void warn_strlen (const char *s1, const char *s2)
97 {
98   *(int16_t *)a1 = strlen (s1); // { dg-warning "\\\[-Wstringop-overflow" }
99   *(size_t *)a2 = strlen (s2);  // { dg-warning "\\\[-Wstringop-overflow" "!ptr_eq_short" { target { ! ptr_eq_short } } }
100 }
101 
102 
nowarn_strcpy(char * s1,char * s2,const char * s3)103 void nowarn_strcpy (char *s1, char *s2, const char *s3)
104 {
105   *(char **)ax = strcpy (s1, s2);
106   *(char **)a8 = strcpy (s2, s3);
107 }
108 
warn_strcpy(char * s1,char * s2,const char * s3)109 void warn_strcpy (char *s1, char *s2, const char *s3)
110 {
111   *(char **)a1 = strcpy (s1, s2);   // { dg-warning "\\\[-Wstringop-overflow" }
112   *(char **)a2 = strcpy (s2, s3);   // { dg-warning "\\\[-Wstringop-overflow" "!ptr_eq_short" { target { ! ptr_eq_short } } }
113 }
114