1 // PR c++/83058 - ICE on C++ code with negative array index: in
2 // warn_placement_new_too_small
3 // { dg-do compile }
4 // { dg-additional-options "-Wplacement-new -Wno-pedantic" }
5 // { dg-require-effective-target alloca }
6 
7 #define SIZE_MAX   __SIZE_MAX__
8 #define DIFF_MAX   __PTRDIFF_MAX__
9 #define DIFF_MIN   (-DIFF_MAX - 1)
10 
new(__SIZE_TYPE__ n,void * p)11 void* operator new (__SIZE_TYPE__ n, void *p) { return p; }
12 void* operator new[] (__SIZE_TYPE__ n, void *p) { return p; }
13 
14 struct A { };
15 
16 char carr[2];
17 int iarr[2];
18 
19 struct C0 { char i, carr[0]; };
20 struct I0 { int i, iarr[0]; };
21 struct CX { char i, carr[]; };
22 struct IX { int i, iarr[]; };
23 
test_single(C0 * pc,CX * qc,I0 * pi,IX * qi,int n)24 void test_single (C0 *pc, CX *qc, I0 *pi, IX *qi, int n)
25 {
26   new (&carr[DIFF_MIN]) A ();       // { dg-warning "placement new constructing an object of type .A. and size .1. in a region of type .char \\\[2]. and size .0." }
27   new (&carr[-1]) A;                // { dg-warning "\\\[-Wplacement-new" }
28   new (carr -1 ) A;                 // { dg-warning "\\\[-Wplacement-new" }
29   new (&carr[0]) A;
30   new (carr) A;
31   new (&carr[1]) A;
32   new (carr + 1) A;
33   new (&carr[n]) A;
34   new (carr + n) A;
35   new (&carr[DIFF_MAX]) A;          // { dg-warning "\\\[-Wplacement-new" }
36   new (carr + DIFF_MAX) A;          // { dg-warning "\\\[-Wplacement-new" }
37   new (&carr[SIZE_MAX]) A;          // { dg-warning "\\\[-Wplacement-new" }
38   new (carr + SIZE_MAX) A;          // { dg-warning "\\\[-Wplacement-new" }
39 
40   new (&pc->carr[DIFF_MIN]) A;      // { dg-warning "\\\[-Wplacement-new" }
41   new (&pc->carr[-1]) A;            // { dg-warning "\\\[-Wplacement-new" }
42   new (&pc->carr[0]) A;
43   new (&pc->carr[9]) A;
44   new (&pc->carr[n]) A;
45   new (&pc->carr[DIFF_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
46   new (&pc->carr[SIZE_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
47 
48   {
49     /* The highest index at which a single A can be constructed.  */
50     enum { MAX = DIFF_MAX - sizeof *pc - sizeof (A) };
51     new (&pc->carr[MAX]) A;
52     new (&pc->carr[MAX + 1]) A;     // { dg-warning "\\\[-Wplacement-new" }
53   }
54 
55   new (&qc->carr[DIFF_MIN]) A;      // { dg-warning "\\\[-Wplacement-new" }
56   new (&qc->carr[-1]) A;            // { dg-warning "\\\[-Wplacement-new" }
57   new (&qc->carr[0]) A;
58   new (&qc->carr[9]) A;
59   new (&qc->carr[n]) A;
60   new (&qc->carr[DIFF_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
61   new (&qc->carr[SIZE_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
62 
63   {
64     /* The highest index at which a single A can be constructed.  */
65     enum { MAX = DIFF_MAX - sizeof *qc - sizeof (A) };
66     new (&qc->carr[MAX]) A;
67     new (&qc->carr[MAX + 1]) A;     // { dg-warning "\\\[-Wplacement-new" }
68   }
69 
70   new (&pi->iarr[DIFF_MIN]) A;      // { dg-warning "\\\[-Wplacement-new" }
71   new (&pi->iarr[-1]) A;            // { dg-warning "\\\[-Wplacement-new" }
72   new (&pi->iarr[0]) A;
73   new (&pi->iarr[9]) A;
74   new (&pi->iarr[n]) A;
75   new (&pi->iarr[DIFF_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
76   new (&pi->iarr[SIZE_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
77 
78   {
79     enum { MAX = (DIFF_MAX - sizeof *pi) / sizeof *pi->iarr };
80     new (&pi->iarr[MAX]) A;
81     new (&pi->iarr[MAX + 1]) A;     // { dg-warning "\\\[-Wplacement-new" }
82   }
83 
84   new (&qi->iarr[DIFF_MIN]) A;      // { dg-warning "\\\[-Wplacement-new" }
85   new (&qi->iarr[-1]) A;            // { dg-warning "\\\[-Wplacement-new" }
86   new (&qi->iarr[0]) A;
87   new (&qi->iarr[9]) A;
88   new (&qi->iarr[n]) A;
89   new (&qi->iarr[DIFF_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
90   new (&qi->iarr[SIZE_MAX]) A;      // { dg-warning "\\\[-Wplacement-new" }
91 
92   {
93     enum { MAX = (DIFF_MAX - sizeof *qi) / sizeof *qi->iarr };
94     new (&qi->iarr[MAX]) A;
95     new (&qi->iarr[MAX + 1]) A;     // { dg-warning "\\\[-Wplacement-new" }
96   }
97 
98   new (&iarr[DIFF_MIN]) A;          // { dg-warning "\\\[-Wplacement-new" }
99   new (&iarr[-1]) A;                // { dg-warning "\\\[-Wplacement-new" }
100   new (&iarr[1]) A;
101   new (&iarr[n]) A;
102   new (&iarr[DIFF_MAX]) A;          // { dg-warning "\\\[-Wplacement-new" }
103   new (&iarr[SIZE_MAX]) A;          // { dg-warning "\\\[-Wplacement-new" }
104 }
105 
test_array_1(C0 * pc,CX * qc,I0 * pi,IX * qi)106 void test_array_1 (C0 *pc, CX *qc, I0 *pi, IX *qi)
107 {
108   enum { N = 1 };
109 
110   new (&carr[DIFF_MIN]) A[N];       // { dg-warning "placement new constructing an object of type .A \\\[\[0-9\]+]. and size .\[0-9\]+. in a region of type .char \\\[2]. and size .0." }
111   new (&carr[-1]) A[N];             // { dg-warning "\\\[-Wplacement-new" }
112   new (&carr[DIFF_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
113   new (&carr[SIZE_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
114 
115   new (&pc->carr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
116   new (&pc->carr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
117   new (&pc->carr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
118   new (&pc->carr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
119 
120   {
121     enum { MAX = DIFF_MAX - sizeof *pc - sizeof (A[N]) };
122     new (&pc->carr[MAX]) A[N];
123     new (&pc->carr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
124   }
125 
126   new (&qc->carr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
127   new (&qc->carr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
128   new (&qc->carr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
129   new (&qc->carr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
130 
131   {
132     enum { MAX = DIFF_MAX - sizeof *qc - sizeof (A[N]) };
133     new (&qc->carr[MAX]) A[N];
134     new (&qc->carr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
135   }
136 
137   new (&pi->iarr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
138   new (&pi->iarr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
139   new (&pi->iarr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
140   new (&pi->iarr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
141 
142   {
143     enum { MAX = (DIFF_MAX - sizeof *pi) / sizeof *pi->iarr };
144     new (&pi->iarr[MAX]) A[N];
145     new (&pi->iarr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
146   }
147 
148   new (&qi->iarr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
149   new (&qi->iarr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
150   new (&qi->iarr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
151   new (&qi->iarr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
152 
153   {
154     enum { MAX = (DIFF_MAX - sizeof *qi) / sizeof *qi->iarr };
155     new (&qi->iarr[MAX]) A[N];
156     new (&qi->iarr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
157   }
158 
159   new (&iarr[DIFF_MIN]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
160   new (&iarr[-1]) A[N];             // { dg-warning "\\\[-Wplacement-new" }
161   new (&iarr[DIFF_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
162   new (&iarr[SIZE_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
163 }
164 
165 
test_array_3(C0 * pc,CX * qc,I0 * pi,IX * qi)166 void test_array_3 (C0 *pc, CX *qc, I0 *pi, IX *qi)
167 {
168   enum { N = 3 };
169 
170   new (&carr[DIFF_MIN]) A[N];       // { dg-warning "placement new constructing an object of type .A \\\[\[0-9\]+]. and size .\[0-9\]+. in a region of type .char \\\[2]. and size .0." }
171   new (&carr[-1]) A[N];             // { dg-warning "\\\[-Wplacement-new" }
172   new (&carr[DIFF_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
173   new (&carr[SIZE_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
174 
175   new (&pc->carr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
176   new (&pc->carr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
177   new (&pc->carr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
178   new (&pc->carr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
179 
180   {
181     enum { MAX = DIFF_MAX - sizeof *pc - sizeof (A[N]) };
182     new (&pc->carr[MAX]) A[N];
183     new (&pc->carr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
184   }
185 
186   new (&qc->carr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
187   new (&qc->carr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
188   new (&qc->carr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
189   new (&qc->carr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
190 
191   {
192     enum { MAX = DIFF_MAX - sizeof *qc - sizeof (A[N]) };
193     new (&qc->carr[MAX]) A[N];
194     new (&qc->carr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
195   }
196 
197   new (&pi->iarr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
198   new (&pi->iarr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
199   new (&pi->iarr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
200   new (&pi->iarr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
201 
202   {
203     enum { MAX = (DIFF_MAX - sizeof *pi) / sizeof *pi->iarr };
204     new (&pi->iarr[MAX]) A[N];
205     new (&pi->iarr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
206   }
207 
208   new (&qi->iarr[DIFF_MIN]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
209   new (&qi->iarr[-1]) A[N];         // { dg-warning "\\\[-Wplacement-new" }
210   new (&qi->iarr[DIFF_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
211   new (&qi->iarr[SIZE_MAX]) A[N];   // { dg-warning "\\\[-Wplacement-new" }
212 
213   {
214     enum { MAX = (DIFF_MAX - sizeof *qi) / sizeof *qi->iarr };
215     new (&qi->iarr[MAX]) A[N];
216     new (&qi->iarr[MAX + 1]) A[N];  // { dg-warning "\\\[-Wplacement-new" }
217   }
218 
219   new (&iarr[DIFF_MIN]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
220   new (&iarr[-1]) A[N];             // { dg-warning "\\\[-Wplacement-new" }
221   new (&iarr[DIFF_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
222   new (&iarr[SIZE_MAX]) A[N];       // { dg-warning "\\\[-Wplacement-new" }
223 }
224 
225 
test_vla(unsigned n)226 void test_vla (unsigned n)
227 {
228   char cvla[n];
229 
230   new (&cvla[DIFF_MIN]) A;          // { dg-warning "placement new constructing an object of type .A. and size .1. in a region of type .char \\\[n]. and size .0." }
231   new (&cvla[-1]) A;                // { dg-warning "\\\[-Wplacement-new" }
232   new (cvla -1) A;                  // { dg-warning "\\\[-Wplacement-new" }
233   new (&cvla[0]) A;
234   new (&cvla[9]) A;
235   new (&cvla[n - 1]) A;
236   new (cvla + n - 1) A;
237   new (&cvla[DIFF_MAX - 1]) A;
238   new (&cvla[DIFF_MAX]) A;          // { dg-warning "\\\[-Wplacement-new" }
239   new (cvla + DIFF_MAX) A;          // { dg-warning "\\\[-Wplacement-new" }
240   new (&cvla[SIZE_MAX]) A;          // { dg-warning "\\\[-Wplacement-new" }
241   new (cvla + SIZE_MAX) A;          // { dg-warning "\\\[-Wplacement-new" }
242 }
243