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