1 // RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
2 // RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
3 
4 #include "Inputs/system-header-simulator-for-valist.h"
5 
f1(int fst,...)6 void f1(int fst, ...) {
7   va_list va;
8   (void)va_arg(va, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
9   // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
10 }
11 
f2(int fst,...)12 int f2(int fst, ...) {
13   va_list va;
14   va_start(va, fst); // expected-note{{Initialized va_list}}
15   va_end(va); // expected-note{{Ended va_list}}
16   return va_arg(va, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
17   // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
18 }
19 
f3(int fst,...)20 void f3(int fst, ...) {
21   va_list va, va2;
22   va_start(va, fst);
23   va_copy(va2, va);
24   va_end(va);
25   (void)va_arg(va2, int);
26   va_end(va2);
27 } //no-warning
28 
f4(int cond,...)29 void f4(int cond, ...) {
30   va_list va;
31   if (cond) { // expected-note{{Assuming 'cond' is 0}}
32     // expected-note@-1{{Taking false branch}}
33     va_start(va, cond);
34     (void)va_arg(va,int);
35   }
36   va_end(va); //expected-warning{{va_end() is called on an uninitialized va_list}}
37   // expected-note@-1{{va_end() is called on an uninitialized va_list}}
38 }
39 
f5(va_list fst,...)40 void f5(va_list fst, ...) {
41   va_start(fst, fst);
42   (void)va_arg(fst, int);
43   va_end(fst);
44 } // no-warning
45 
f7(int * fst,...)46 void f7(int *fst, ...) {
47   va_list x;
48   va_list *y = &x;
49   va_start(*y,fst);
50   (void)va_arg(x, int);
51   va_end(x);
52 } // no-warning
53 
f8(int * fst,...)54 void f8(int *fst, ...) {
55   va_list x;
56   va_list *y = &x;
57   va_start(*y,fst); // expected-note{{Initialized va_list}}
58   va_end(x); // expected-note{{Ended va_list}}
59   (void)va_arg(*y, int); //expected-warning{{va_arg() is called on an uninitialized va_list}}
60   // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
61 }
62 
63 // This only contains problems which are handled by varargs.Unterminated.
reinit(int * fst,...)64 void reinit(int *fst, ...) {
65   va_list va;
66   va_start(va, fst);
67   va_start(va, fst);
68   (void)va_arg(va, int);
69 } // no-warning
70 
reinitOk(int * fst,...)71 void reinitOk(int *fst, ...) {
72   va_list va;
73   va_start(va, fst);
74   (void)va_arg(va, int);
75   va_end(va);
76   va_start(va, fst);
77   (void)va_arg(va, int);
78   va_end(va);
79 } // no-warning
80 
reinit3(int * fst,...)81 void reinit3(int *fst, ...) {
82   va_list va;
83   va_start(va, fst); // expected-note{{Initialized va_list}}
84   (void)va_arg(va, int);
85   va_end(va); // expected-note{{Ended va_list}}
86   va_start(va, fst); // expected-note{{Initialized va_list}}
87   (void)va_arg(va, int);
88   va_end(va); // expected-note{{Ended va_list}}
89   (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}}
90   // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
91 }
92 
copyself(int fst,...)93 void copyself(int fst, ...) {
94   va_list va;
95   va_start(va, fst); // expected-note{{Initialized va_list}}
96   va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
97   // expected-note@-1{{va_list 'va' is copied onto itself}}
98   va_end(va);
99 }
100 
copyselfUninit(int fst,...)101 void copyselfUninit(int fst, ...) {
102   va_list va;
103   va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
104   // expected-note@-1{{va_list 'va' is copied onto itself}}
105 }
106 
copyOverwrite(int fst,...)107 void copyOverwrite(int fst, ...) {
108   va_list va, va2;
109   va_start(va, fst); // expected-note{{Initialized va_list}}
110   va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}}
111   // expected-note@-1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
112 }
113 
copyUnint(int fst,...)114 void copyUnint(int fst, ...) {
115   va_list va, va2;
116   va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}}
117   // expected-note@-1{{Uninitialized va_list is copied}}
118 }
119 
g1(int fst,...)120 void g1(int fst, ...) {
121   va_list va;
122   va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
123   // expected-note@-1{{va_end() is called on an uninitialized va_list}}
124 }
125 
g2(int fst,...)126 void g2(int fst, ...) {
127   va_list va;
128   va_start(va, fst); // expected-note{{Initialized va_list}}
129   va_end(va); // expected-note{{Ended va_list}}
130   va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
131   // expected-note@-1{{va_end() is called on an uninitialized va_list}}
132 }
133 
is_sink(int fst,...)134 void is_sink(int fst, ...) {
135   va_list va;
136   va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
137   // expected-note@-1{{va_end() is called on an uninitialized va_list}}
138   *((volatile int *)0) = 1;
139 }
140 
141 // NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start()
142 // must be matched by a corresponding  invocation of va_end() in the same function."
ends_arg(va_list arg)143 void ends_arg(va_list arg) {
144   va_end(arg);
145 } //no-warning
146 
uses_arg(va_list arg)147 void uses_arg(va_list arg) {
148   (void)va_arg(arg, int);
149 } //no-warning
150 
call_vprintf_ok(int isstring,...)151 void call_vprintf_ok(int isstring, ...) {
152   va_list va;
153   va_start(va, isstring);
154   vprintf(isstring ? "%s" : "%d", va);
155   va_end(va);
156 } //no-warning
157 
call_some_other_func(int n,...)158 void call_some_other_func(int n, ...) {
159   va_list va;
160   some_library_function(n, va);
161 } //no-warning
162 
inlined_uses_arg_good(va_list arg)163 void inlined_uses_arg_good(va_list arg) {
164   (void)va_arg(arg, int);
165 }
166 
call_inlined_uses_arg_good(int fst,...)167 void call_inlined_uses_arg_good(int fst, ...) {
168   va_list va;
169   va_start(va, fst);
170   inlined_uses_arg_good(va);
171   va_end(va);
172 }
173 
va_copy_test(va_list arg)174 void va_copy_test(va_list arg) {
175   va_list dst;
176   va_copy(dst, arg);
177   va_end(dst);
178 }
179