[ELF] Avoid make in elf::writeARMCmseImportLib
[llvm-project.git] / clang / test / Analysis / std-variant-checker.cpp
blob7f136c06b19cc6021fa6c941633456807ba45575
1 // RUN: %clang %s -std=c++17 -Xclang -verify --analyze \
2 // RUN: -Xclang -analyzer-checker=core \
3 // RUN: -Xclang -analyzer-checker=debug.ExprInspection \
4 // RUN: -Xclang -analyzer-checker=core,alpha.core.StdVariant
6 #include "Inputs/system-header-simulator-cxx.h"
8 class Foo{};
10 void clang_analyzer_warnIfReached();
11 void clang_analyzer_eval(int);
13 //helper functions
14 void changeVariantType(std::variant<int, char> &v) {
15 v = 25;
18 void changesToInt(std::variant<int, char> &v);
19 void changesToInt(std::variant<int, char> *v);
21 void cannotChangePtr(const std::variant<int, char> &v);
22 void cannotChangePtr(const std::variant<int, char> *v);
24 char getUnknownChar();
26 void swap(std::variant<int, char> &v1, std::variant<int, char> &v2) {
27 std::variant<int, char> tmp = v1;
28 v1 = v2;
29 v2 = tmp;
32 void cantDo(const std::variant<int, char>& v) {
33 std::variant<int, char> vtmp = v;
34 vtmp = 5;
35 int a = std::get<int> (vtmp);
36 (void) a;
39 void changeVariantPtr(std::variant<int, char> *v) {
40 *v = 'c';
43 using var_t = std::variant<int, char>;
44 using var_tt = var_t;
45 using int_t = int;
46 using char_t = char;
48 // A quick sanity check to see that std::variant's std::get
49 // is not being confused with std::pairs std::get.
50 void wontConfuseStdGets() {
51 std::pair<int, char> p{15, '1'};
52 int a = std::get<int>(p);
53 char c = std::get<char>(p);
54 (void)a;
55 (void)c;
58 //----------------------------------------------------------------------------//
59 // std::get
60 //----------------------------------------------------------------------------//
61 void stdGetType() {
62 std::variant<int, char> v = 25;
63 int a = std::get<int>(v);
64 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
65 (void)a;
66 (void)c;
69 void stdGetPointer() {
70 int *p = new int;
71 std::variant<int*, char> v = p;
72 int *a = std::get<int*>(v);
73 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int *', not a 'char'}}
74 (void)a;
75 (void)c;
76 delete p;
79 void stdGetObject() {
80 std::variant<int, char, Foo> v = Foo{};
81 Foo f = std::get<Foo>(v);
82 int i = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'Foo', not an 'int'}}
83 (void)i;
86 void stdGetPointerAndPointee() {
87 int a = 5;
88 std::variant<int, int*> v = &a;
89 int *b = std::get<int*>(v);
90 int c = std::get<int>(v); // expected-warning {{std::variant 'v' held an 'int *', not an 'int'}}
91 (void)c;
92 (void)b;
95 void variantHoldingVariant() {
96 std::variant<std::variant<int, char>, std::variant<char, int>> v = std::variant<int,char>(25);
97 std::variant<int, char> v1 = std::get<std::variant<int,char>>(v);
98 std::variant<char, int> v2 = std::get<std::variant<char,int>>(v); // expected-warning {{std::variant 'v' held a 'std::variant<int, char>', not a 'class std::variant<char, int>'}}
101 //----------------------------------------------------------------------------//
102 // Constructors and assignments
103 //----------------------------------------------------------------------------//
104 void copyConstructor() {
105 std::variant<int, char> v = 25;
106 std::variant<int, char> t(v);
107 int a = std::get<int> (t);
108 char c = std::get<char> (t); // expected-warning {{std::variant 't' held an 'int', not a 'char'}}
109 (void)a;
110 (void)c;
113 void copyAssignmentOperator() {
114 std::variant<int, char> v = 25;
115 std::variant<int, char> t = 'c';
116 t = v;
117 int a = std::get<int> (t);
118 char c = std::get<char> (t); // expected-warning {{std::variant 't' held an 'int', not a 'char'}}
119 (void)a;
120 (void)c;
123 void assignmentOperator() {
124 std::variant<int, char> v = 25;
125 int a = std::get<int> (v);
126 (void)a;
127 v = 'c';
128 char c = std::get<char>(v);
129 a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
130 (void)a;
131 (void)c;
134 void typeChangeThreeTimes() {
135 std::variant<int, char, float> v = 25;
136 int a = std::get<int> (v);
137 (void)a;
138 v = 'c';
139 char c = std::get<char>(v);
140 v = 25;
141 a = std::get<int>(v);
142 (void)a;
143 v = 1.25f;
144 float f = std::get<float>(v);
145 a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'float', not an 'int'}}
146 (void)a;
147 (void)c;
148 (void)f;
151 void defaultConstructor() {
152 std::variant<int, char> v;
153 int i = std::get<int>(v);
154 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
155 (void)i;
156 (void)c;
159 // Verify that we handle temporary objects correctly
160 void temporaryObjectsConstructor() {
161 std::variant<int, char> v(std::variant<int, char>('c'));
162 char c = std::get<char>(v);
163 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
164 (void)a;
165 (void)c;
168 void temporaryObjectsAssignment() {
169 std::variant<int, char> v = std::variant<int, char>('c');
170 char c = std::get<char>(v);
171 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
172 (void)a;
173 (void)c;
176 // Verify that we handle pointer types correctly
177 void pointerTypeHeld() {
178 int *p = new int;
179 std::variant<int*, char> v = p;
180 int *a = std::get<int*>(v);
181 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int *', not a 'char'}}
182 (void)a;
183 (void)c;
184 delete p;
187 std::variant<int, char> get_unknown_variant();
188 // Verify that the copy constructor is handles properly when the std::variant
189 // has no previously activated type and we copy an object of unknown value in it.
190 void copyFromUnknownVariant() {
191 std::variant<int, char> u = get_unknown_variant();
192 std::variant<int, char> v(u);
193 int a = std::get<int>(v); // no-waring
194 char c = std::get<char>(v); // no-warning
195 (void)a;
196 (void)c;
199 // Verify that the copy constructor is handles properly when the std::variant
200 // has previously activated type and we copy an object of unknown value in it.
201 void copyFromUnknownVariantBef() {
202 std::variant<int, char> v = 25;
203 std::variant<int, char> u = get_unknown_variant();
204 v = u;
205 int a = std::get<int>(v); // no-waring
206 char c = std::get<char>(v); // no-warning
207 (void)a;
208 (void)c;
211 //----------------------------------------------------------------------------//
212 // typedef
213 //----------------------------------------------------------------------------//
215 void typefdefedVariant() {
216 var_t v = 25;
217 int a = std::get<int>(v);
218 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
219 (void)a;
220 (void)c;
223 void typedefedTypedfefedVariant() {
224 var_tt v = 25;
225 int a = std::get<int>(v);
226 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
227 (void)a;
228 (void)c;
231 void typedefedGet() {
232 std::variant<char, int> v = 25;
233 int a = std::get<int_t>(v);
234 char c = std::get<char_t>(v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
235 (void)a;
236 (void)c;
239 void typedefedPack() {
240 std::variant<int_t, char_t> v = 25;
241 int a = std::get<int>(v);
242 char c = std::get<char>(v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
243 (void)a;
244 (void)c;
247 void fromVariable() {
248 char o = 'c';
249 std::variant<int, char> v(o);
250 char c = std::get<char>(v);
251 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
252 (void)a;
253 (void)c;
256 void unknowValueButKnownType() {
257 char o = getUnknownChar();
258 std::variant<int, char> v(o);
259 char c = std::get<char>(v);
260 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
261 (void)a;
262 (void)c;
265 void createPointer() {
266 std::variant<int, char> *v = new std::variant<int, char>(15);
267 int a = std::get<int>(*v);
268 char c = std::get<char>(*v); // expected-warning {{std::variant held an 'int', not a 'char'}}
269 (void)a;
270 (void)c;
271 delete v;
274 //----------------------------------------------------------------------------//
275 // Passing std::variants to functions
276 //----------------------------------------------------------------------------//
278 // Verifying that we are not invalidating the memory region of a variant if
279 // a non inlined or inlined function takes it as a constant reference or pointer
280 void constNonInlineRef() {
281 std::variant<int, char> v = 'c';
282 cannotChangePtr(v);
283 char c = std::get<char>(v);
284 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
285 (void)a;
286 (void)c;
289 void contNonInlinePtr() {
290 std::variant<int, char> v = 'c';
291 cannotChangePtr(&v);
292 char c = std::get<char>(v);
293 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
294 (void)a;
295 (void)c;
298 void copyInAFunction() {
299 std::variant<int, char> v = 'c';
300 cantDo(v);
301 char c = std::get<char>(v);
302 int a = std::get<int>(v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
303 (void)a;
304 (void)c;
308 // Verifying that we can keep track of the type stored in std::variant when
309 // it is passed to an inlined function as a reference or pointer
310 void changeThruPointers() {
311 std::variant<int, char> v = 15;
312 changeVariantPtr(&v);
313 char c = std::get<char> (v);
314 int a = std::get<int> (v); // expected-warning {{std::variant 'v' held a 'char', not an 'int'}}
315 (void)a;
316 (void)c;
319 void functionCallWithCopyAssignment() {
320 var_t v1 = 15;
321 var_t v2 = 'c';
322 swap(v1, v2);
323 int a = std::get<int> (v2);
324 (void)a;
325 char c = std::get<char> (v1);
326 a = std::get<int> (v1); // expected-warning {{std::variant 'v1' held a 'char', not an 'int'}}
327 (void)a;
328 (void)c;
331 void inlineFunctionCall() {
332 std::variant<int, char> v = 'c';
333 changeVariantType(v);
334 int a = std::get<int> (v);
335 char c = std::get<char> (v); // expected-warning {{std::variant 'v' held an 'int', not a 'char'}}
336 (void)a;
337 (void)c;
340 // Verifying that we invalidate the mem region of std::variant when it is
341 // passed as a non const reference or a pointer to a non inlined function.
342 void nonInlineFunctionCall() {
343 std::variant<int, char> v = 'c';
344 changesToInt(v);
345 int a = std::get<int> (v); // no-waring
346 char c = std::get<char> (v); // no-warning
347 (void)a;
348 (void)c;
351 void nonInlineFunctionCallPtr() {
352 std::variant<int, char> v = 'c';
353 changesToInt(&v);
354 int a = std::get<int> (v); // no-warning
355 char c = std::get<char> (v); // no-warning
356 (void)a;
357 (void)c;