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