1 /* { dg-do compile } */
2 
3 // Test for PR c++/67913 - new expression with negative size not diagnosed.
4 typedef __typeof__ (sizeof 0) size_t;
5 
6 void* operator new (size_t, void*);
7 void* operator new[] (size_t, void*);
8 
9 struct A {
10     int a [4];
11 };
12 
13 struct B {
14     int a [4];
15 
16     void* operator new (size_t, void*);
17     void* operator new[] (size_t, void*);
18 };
19 
20 void* operator new (size_t, B*);
21 void* operator new[] (size_t, B*);
22 
23 void *p;
24 
test_literal()25 void test_literal ()
26 {
27     char c;
28     (void)c;
29 
30     B b;
31 
32     // Verify integer literal.
33     p = new char [-1];           // { dg-error "size .-1. of array is negative" }
34     p = new char [2][-3];        // { dg-error "size .-3. of array|narrowing conversion" }
35     p = new char [-4][5];        // { dg-error "size .-4. of array is negative" }
36     p = new char [-6][-7];       // { dg-error "size .-\[67\]. of array|narrowing conversion" }
37 
38     p = new (p) char [-1];       // { dg-error "size .-1. of array is negative" }
39     p = new (p) char [2][-3];    // { dg-error "size .-3. of array|narrowing conversion" }
40     p = new (p) char [-4][5];    // { dg-error "size .-4. of array is negative" }
41     p = new (p) char [-6][-7];   // { dg-error "size .-\[67\]. of array|narrowing conversion" }
42 
43     p = new (p) A [-1];          // { dg-error "size .-1. of array is negative" }
44     p = new (p) A [2][-3];       // { dg-error "size .-3. of array|narrowing conversion" }
45     p = new (p) A [-4][5];       // { dg-error "size .-4. of array is negative" }
46     p = new (p) A [-6][-7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
47 
48     p = new (p) B [-1];          // { dg-error "size .-1. of array is negative" }
49     p = new (p) B [2][-3];       // { dg-error "size .-3. of array|narrowing conversion" }
50     p = new (p) B [-4][5];       // { dg-error "size .-4. of array is negative" }
51     p = new (p) B [-6][-7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
52 
53     p = new (&b) B [-1];          // { dg-error "size .-1. of array is negative" }
54     p = new (&b) B [2][-3];       // { dg-error "size .-3. of array|narrowing conversion" }
55     p = new (&b) B [-4][5];       // { dg-error "size .-4. of array is negative" }
56     p = new (&b) B [-6][-7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
57 
58     p = new char [1 - 2];         // { dg-error "size .-1. of array is negative" }
59     p = new (p) char [2 - 3];     // { dg-error "size .-1. of array is negative" }
60     p = new A [2 < 1 ? -1 : -2];  // { dg-error "size .-2. of array is negative" }
61     p = new (p) B [2 - 3 * 2];    // { dg-error "size .-4. of array is negative" }
62     p = new (&b) B [1][2 - 3 * 2];// { dg-error "size .-4. of array|narrowing conversion" }
63 }
64 
test_constant_expression()65 void test_constant_expression ()
66 {
67     char c;
68     (void)c;
69 
70     B b;
71 
72     static const signed char i1 = -1;
73     static const signed short i2 = -2;
74     static const signed int i3 = -3;
75     static const signed long i4 = -4;
76     static const signed long long i5 = -5;
77     static const int i6 = -6;
78     static const int i7 = -7;
79 
80     // Verify constant expression.
81     p = new char [i1];           // { dg-error "size .-1. of array is negative" }
82     p = new char [2][i3];        // { dg-error "size .-3. of array|narrowing conversion" }
83     p = new char [i4][5];        // { dg-error "size .-4. of array is negative" }
84     p = new char [i6][i7];       // { dg-error "size .-\[67\]. of array|narrowing conversion" }
85 
86     p = new (p) char [i1];       // { dg-error "size .-1. of array is negative" }
87     p = new (p) char [2][i3];    // { dg-error "size .-3. of array|narrowing conversion" }
88     p = new (p) char [i4][5];    // { dg-error "size .-4. of array is negative" }
89     p = new (p) char [i6][i7];   // { dg-error "size .-\[67\]. of array|narrowing conversion" }
90 
91     p = new (p) A [i1];          // { dg-error "size .-1. of array is negative" }
92     p = new (p) A [2][i3];       // { dg-error "size .-3. of array|narrowing conversion" }
93     p = new (p) A [i4][5];       // { dg-error "size .-4. of array is negative" }
94     p = new (p) A [i6][i7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
95 
96     p = new (p) B [i1];          // { dg-error "size .-1. of array is negative" }
97     p = new (p) B [2][i3];       // { dg-error "size .-3. of array|narrowing conversion" }
98     p = new (p) B [i4][5];       // { dg-error "size .-4. of array is negative" }
99     p = new (p) B [i6][i7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
100 
101     p = new (&b) B [i1];          // { dg-error "size .-1. of array is negative" }
102     p = new (&b) B [2][i3];       // { dg-error "size .-3. of array|narrowing conversion" }
103     p = new (&b) B [i4][5];       // { dg-error "size .-4. of array is negative" }
104     p = new (&b) B [i6][i7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
105 
106     p = new short [i1 - 2];       // { dg-error "size .-3. of array is negative" }
107     p = new (p) bool [i2 - 3];    // { dg-error "size .-5. of array is negative" }
108     p = new A [2 < 1 ? i1 : i2];  // { dg-error "size .-2. of array is negative" }
109     p = new (p) B [2 + i3 * 2];   // { dg-error "size .-4. of array is negative" }
110     p = new (&b) B [1][i1 - 3 * 2];// { dg-error "size .-7. of array|narrowing conversion" }
111 }
112 
test_constexpr()113 void test_constexpr ()
114 {
115     B b;
116 
117 #if __cplusplus >= 201103L
118 
119     // Verify that a constant expression that is "a prvalue core constant
120     // expression whose value is an object where, for that object and its
121     // subobjects each non-static data member of reference type refers to
122     // an object with static storage duration."
123     static constexpr struct S {
124         int i_;
125         constexpr S (int i): i_ (i) { }
126         constexpr operator int () const { return i_; }
127     } s1 (-1), s2 (-2), s3 (-3), s4 (-4), s5 (-5), s6 (-6), s7 (-7);
128 #else
129     // C++ 11 constexpr is not available, fall back on plain ole enum.
130     enum { s1 = -1, s2 = -2, s3 = -3, s4 = -4, s5 = -5, s6 = -6, s7 = -7 };
131 #endif
132 
133     // Verify constant expression.
134     p = new char [s1];           // { dg-error "size .-1. of array is negative" }
135     p = new char [2][s3];        // { dg-error "size .-3. of array|narrowing conversion" }
136     p = new char [s4][5];        // { dg-error "size .-4. of array is negative" }
137     p = new char [s6][s7];       // { dg-error "size .-\[67\]. of array|narrowing conversion" }
138 
139     p = new (p) char [s1];       // { dg-error "size .-1. of array is negative" }
140     p = new (p) char [2][s3];    // { dg-error "size .-3. of array|narrowing conversion" }
141     p = new (p) char [s4][5];    // { dg-error "size .-4. of array is negative" }
142     p = new (p) char [s6][s7];   // { dg-error "size .-\[67\]. of array|narrowing conversion" }
143 
144     p = new (p) A [s1];          // { dg-error "size .-1. of array is negative" }
145     p = new (p) A [2][s3];       // { dg-error "size .-3. of array|narrowing conversion" }
146     p = new (p) A [s4][5];       // { dg-error "size .-4. of array is negative" }
147     p = new (p) A [s6][s7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
148 
149     p = new (p) B [s1];          // { dg-error "size .-1. of array is negative" }
150     p = new (p) B [2][s3];       // { dg-error "size .-3. of array|narrowing conversion" }
151     p = new (p) B [s4][5];       // { dg-error "size .-4. of array is negative" }
152     p = new (p) B [s6][s7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
153 
154     p = new (&b) B [s1];          // { dg-error "size .-1. of array is negative" }
155     p = new (&b) B [2][s3];       // { dg-error "size .-3. of array|narrowing conversion" }
156     p = new (&b) B [s4][5];       // { dg-error "size .-4. of array is negative" }
157     p = new (&b) B [s6][s7];      // { dg-error "size .-\[67\]. of array|narrowing conversion" }
158 
159     p = new int [s1 + s2];           // { dg-error "size .-3. of array is negative" }
160     p = new (p) long [2 * s3];       // { dg-error "size .-6. of array is negative" }
161     p = new A [s2 < s1 ? s1 : s2];   // { dg-error "size .-1. of array is negative" }
162     p = new (p) B [s7 - s2 * 2];     // { dg-error "size .-3. of array is negative" }
163     p = new (&b) B [9][s4 - s1 * 2]; // { dg-error "size .-2. of array|narrowing conversion" }
164 }
165 
166 /* Prune out pedantic warnins (turned into errors via -pedantic-errors).
167   { dg-prune-output "size of array is not an integral constant-expressio" } */
168