Fortran: Fix PR 47485.
[gcc.git] / gcc / testsuite / g++.dg / warn / Wstringop-overflow-4.C
blob2024f8d93ca3d7a9bdf5ba65d80cd57ca6579fce
1 /* PR middle-end/91582 - missing heap overflow detection for strcpy
2    { dg-do compile }
3    { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
5 #include "../../gcc.dg/range.h"
7 #define INT_MAX     __INT_MAX__
8 #define INT_MIN     (-INT_MAX - 1)
10 extern "C" char* strcpy (char*, const char*);
12 void sink (void*);
14 #define S36 "0123456789abcdefghijklmnopqrstuvwxyz"
15 #define S(N) (S36 + sizeof S36 - N - 1)
17 #define T(src, alloc) do {                      \
18     const char *s = src;                        \
19     char *d = (char*)alloc;                     \
20     strcpy (d, s);                              \
21     sink (d);                                   \
22   } while (0)
25 void test_strcpy_new_char (size_t n)
27   size_t r_0_1 = UR (0, 1);
28   size_t r_1_2 = UR (1, 2);
29   size_t r_2_3 = UR (2, 3);
31   T (S (0), new char[r_0_1]);
32   T (S (1), new char[r_0_1]);       // { dg-warning "\\\[-Wstringop-overflow" }
34   T (S (0), new char[r_1_2]);
35   T (S (1), new char[r_1_2]);
36   T (S (2), new char[r_1_2]);       // { dg-warning "\\\[-Wstringop-overflow" }
38   T (S (0), new char[r_2_3]);
39   T (S (2), new char[r_2_3]);
40   T (S (3), new char[r_2_3]);       // { dg-warning "\\\[-Wstringop-overflow" }
41   T (S (9), new char[r_2_3]);       // { dg-warning "\\\[-Wstringop-overflow" }
43   size_t r_2_smax = UR (2, SIZE_MAX);
44   T (S (0), new char[r_2_smax]);
45   T (S (1), new char[r_2_smax]);
46   T (S (2), new char[r_2_smax]);
47   T (S (3), new char[r_2_smax * 2]);
48   T (S (4), new char[r_2_smax * 2 + 1]);
50   T (S (1), new char[n]);
51   T (S (2), new char[n + 1]);
52   T (S (9), new char[n * 2 + 1]);
54   int r_imin_imax = SR (INT_MIN, INT_MAX);
55   T (S (1), new char[r_imin_imax]);
56   T (S (2), new char[r_imin_imax + 1]);
57   T (S (9), new char[r_imin_imax * 2 + 1]);
59   int r_0_imax = SR (0, INT_MAX);
60   T (S (1), new char[r_0_imax]);
61   T (S (2), new char[r_0_imax + 1]);
62   T (S (9), new char[r_0_imax * 2 + 1]);
64   int r_1_imax = SR (1, INT_MAX);
65   T (S (1), new char[r_1_imax]);
66   T (S (2), new char[r_1_imax + 1]);
67   T (S (9), new char[r_1_imax * 2 + 1]);
69   ptrdiff_t r_dmin_dmax = SR (DIFF_MIN, DIFF_MAX);
70   T (S (1), new char[r_dmin_dmax]);
71   T (S (2), new char[r_dmin_dmax + 1]);
72   T (S (9), new char[r_dmin_dmax * 2 + 1]);
76 void test_strcpy_new_char_array (size_t n)
78   size_t r_0_1 = UR (0, 1);
80   T (S (0), new char[r_0_1][1]);
81   T (S (1), new char[r_0_1][1]);    // { dg-warning "\\\[-Wstringop-overflow" }
82   T (S (1), new char[r_0_1][2]);
83   T (S (2), new char[r_0_1][2]);    // { dg-warning "\\\[-Wstringop-overflow" }
85   size_t r_1_2 = UR (1, 2);
86   T (S (0), new char[r_1_2][0]);    // { dg-warning "\\\[-Wstringop-overflow" }
87   T (S (0), new char[r_1_2][1]);
88   T (S (1), new char[r_1_2][1]);
89   T (S (2), new char[r_1_2][1]);    // { dg-warning "\\\[-Wstringop-overflow" }
91   T (S (0), new char[r_1_2][0]);    // { dg-warning "\\\[-Wstringop-overflow" }
92   T (S (0), new char[r_1_2][1]);
93   T (S (1), new char[r_1_2][2]);
94   T (S (3), new char[r_1_2][2]);
95   T (S (4), new char[r_1_2][2]);    // { dg-warning "\\\[-Wstringop-overflow" }
99 #ifdef __INT16_TYPE__
101 // Hack around PR 92829.
102 #define XUR(min, max) \
103   (++idx, (vals[idx] < min || max < vals[idx] ? min : vals[idx]))
105 typedef __INT16_TYPE__ int16_t;
107 void test_strcpy_new_int16_t (size_t n, const size_t vals[])
109   size_t idx = 0;
111   size_t r_0_1 = XUR (0, 1);
112   size_t r_1_2 = XUR (1, 2);
113   size_t r_2_3 = XUR (2, 3);
115   T (S (0), new int16_t[r_0_1]);
116   T (S (1), new int16_t[r_0_1]);
117   T (S (2), new int16_t[r_0_1]);      // { dg-warning "\\\[-Wstringop-overflow" }
119   T (S (0), new int16_t[r_1_2]);
120   T (S (1), new int16_t[r_1_2]);
121   T (S (2), new int16_t[r_1_2]);
122   T (S (3), new int16_t[r_1_2]);
123   T (S (4), new int16_t[r_1_2]);      // { dg-warning "\\\[-Wstringop-overflow" }
125   T (S (0), new int16_t[r_2_3]);
126   T (S (1), new int16_t[r_2_3]);
127   T (S (5), new int16_t[r_2_3]);
128   T (S (6), new int16_t[r_2_3]);      // { dg-warning "\\\[-Wstringop-overflow" }
129   T (S (9), new int16_t[r_2_3]);      // { dg-warning "\\\[-Wstringop-overflow" }
131   size_t r_2_smax = XUR (2, SIZE_MAX);
132   T (S (0), new int16_t[r_2_smax]);
133   T (S (1), new int16_t[r_2_smax]);
134   T (S (2), new int16_t[r_2_smax]);
135   T (S (3), new int16_t[r_2_smax * 2]);
136   T (S (4), new int16_t[r_2_smax * 2 + 1]);
138   T (S (1), new int16_t[n]);
139   T (S (2), new int16_t[n + 1]);
140   T (S (9), new int16_t[n * 2 + 1]);
142   int r_imin_imax = SR (INT_MIN, INT_MAX);
143   T (S (1), new int16_t[r_imin_imax]);
144   T (S (2), new int16_t[r_imin_imax + 1]); // { dg-bogus "into a region of size" "pr106120" { xfail { lp64 && c++98_only } } }
145   T (S (9), new int16_t[r_imin_imax * 2 + 1]);
147   int r_0_imax = SR (0, INT_MAX);
149   if (sizeof (int) < sizeof (size_t))
150     /* The code below might emit a warning when int is the same size
151        as size_t as a result of threading.  See PR 101688 comment #2.  */
152     T (S (1), new int16_t[r_0_imax]);
154   /* Similar to PR 101688 the following can result in a bougs warning because
155      of threading.  */
156   T (S (2), new int16_t[r_0_imax + 1]); // { dg-bogus "into a region of size" "" { xfail { ilp32 } } }
157   T (S (9), new int16_t[r_0_imax * 2 + 1]);
159   int r_1_imax = SR (1, INT_MAX);
160   T (S (1), new int16_t[r_1_imax]);
161   T (S (2), new int16_t[r_1_imax + 1]);
162   T (S (9), new int16_t[r_1_imax * 2 + 1]);
164   ptrdiff_t r_dmin_dmax = SR (DIFF_MIN, DIFF_MAX);
165   T (S (1), new int16_t[r_dmin_dmax]);
166   /* ?? The above SR(DIFF_MIN, DIFF_MAX) implies r_dmin_dmax can be
167      the entire domain, including negative numbers because ptrdiff_t
168      is a signed entity.
170      This causes a warning in the following line after the
171      DOM/threader changes for C++98.
173       <bb 2> [local count: 1073741824]:
174       _26 ={v} signed_value_source;                      ;; could be -1
175       r_dmin_dmax.1_8 = (sizetype) _26;
176       if (r_dmin_dmax.1_8 <= 4611686018427387900)        ;; placement new rounding
177         goto <bb 3>; [50.00%]
178       else
179         goto <bb 9>; [50.00%]
181       ...
182       ...
184       <bb 9> [local count: 536870912]:
185       # iftmp.0_39 = PHI <18446744073709551615(2)>
186       _41 = operator new [] (iftmp.0_39);
187       __builtin_memcpy (_41, "z", 2);
188       sink (_41);
189       _44 = _26 + 1;                                    ;; _44 = 0
190       _45 = (sizetype) _44;                             ;; _45 = 0
191       if (_45 <= 4611686018427387900)
192         goto <bb 8>; [0.00%]
193       else
194         goto <bb 7>; [100.00%]
196       <bb 8> [local count: 0]:
197       iftmp.2_33 = _45 * 2;                             ;; iftmp.2_33 = 0
198       _34 = operator new [] (iftmp.2_33);               ;; new [] (0)
199   */
200   T (S (2), new int16_t[r_dmin_dmax + 1]); // { dg-bogus "into a region of size" "" { xfail c++98_only } }
201   T (S (9), new int16_t[r_dmin_dmax * 2 + 1]);
204 #endif   // int16_t