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