Clang Project

clang_source_code/test/CodeGenCXX/new-overflow.cpp
1// RUN: %clang_cc1 -std=c++14 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
2
3// rdar://problem/9246208
4
5// Basic test.
6namespace test0 {
7  struct A {
8    A();
9    int x;
10  };
11
12  typedef A elt;
13
14  // CHECK:    define [[A:%.*]]* @_ZN5test04testEs(i16 signext
15  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
16  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
17  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
18  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
19  // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
20  // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
21  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
22  elt *test(short s) {
23    return new elt[s];
24  }
25}
26
27// test0 with a nested array.
28namespace test1 {
29  struct A {
30    A();
31    int x;
32  };
33
34  typedef A elt[100];
35
36  // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test14testEs(i16 signext
37  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
38  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
39  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
40  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
41  // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
42  // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
43  // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
44  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
45  elt *test(short s) {
46    return new elt[s];
47  }
48}
49
50// test1 with an array cookie.
51namespace test2 {
52  struct A {
53    A();
54    ~A();
55    int x;
56  };
57
58  typedef A elt[100];
59
60  // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test24testEs(i16 signext
61  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
62  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
63  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
64  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
65  // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
66  // CHECK-NEXT: [[T4:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T2]], i32 4)
67  // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T4]], 1
68  // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
69  // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
70  // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
71  // CHECK-NEXT: call i8* @_Znaj(i32 [[T8]])
72  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
73  elt *test(short s) {
74    return new elt[s];
75  }
76}
77
78// test0 with a 1-byte element.
79namespace test4 {
80  struct A {
81    A();
82  };
83
84  typedef A elt;
85
86  // CHECK:    define [[A:%.*]]* @_ZN5test44testEs(i16 signext
87  // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
88  // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
89  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
90  elt *test(short s) {
91    return new elt[s];
92  }
93}
94
95// test4 with no sext required.
96namespace test5 {
97  struct A {
98    A();
99  };
100
101  typedef A elt;
102
103  // CHECK:    define [[A:%.*]]* @_ZN5test54testEi(i32
104  // CHECK:      [[N:%.*]] = load i32, i32*
105  // CHECK-NEXT: call i8* @_Znaj(i32 [[N]])
106  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
107  elt *test(int s) {
108    return new elt[s];
109  }
110}
111
112// test0 with an unsigned size.
113namespace test6 {
114  struct A {
115    A();
116    int x;
117  };
118
119  typedef A elt;
120
121  // CHECK:    define [[A:%.*]]* @_ZN5test64testEt(i16 zeroext
122  // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
123  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
124  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
125  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
126  // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
127  // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
128  // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
129  elt *test(unsigned short s) {
130    return new elt[s];
131  }
132}
133
134// test1 with an unsigned size.
135namespace test7 {
136  struct A {
137    A();
138    int x;
139  };
140
141  typedef A elt[100];
142
143  // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test74testEt(i16 zeroext
144  // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
145  // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
146  // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
147  // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
148  // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
149  // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
150  // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
151  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
152  elt *test(unsigned short s) {
153    return new elt[s];
154  }
155}
156
157// test0 with a signed type larger than size_t.
158namespace test8 {
159  struct A {
160    A();
161    int x;
162  };
163
164  typedef A elt;
165
166  // CHECK:    define [[A:%.*]]* @_ZN5test84testEx(i64
167  // CHECK:      [[N:%.*]] = load i64, i64*
168  // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
169  // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
170  // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
171  // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
172  // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
173  // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
174  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
175  elt *test(long long s) {
176    return new elt[s];
177  }
178}
179
180// test8 with an unsigned type.
181namespace test9 {
182  struct A {
183    A();
184    int x;
185  };
186
187  typedef A elt;
188
189  // CHECK:    define [[A:%.*]]* @_ZN5test94testEy(i64
190  // CHECK:      [[N:%.*]] = load i64, i64*
191  // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
192  // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
193  // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
194  // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
195  // CHECK-NEXT: [[T6:%.*]] = select i1 [[T3]], i32 -1, i32 [[T5]]
196  // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
197  // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
198  elt *test(unsigned long long s) {
199    return new elt[s];
200  }
201}
202