]> granicus.if.org Git - clang/blob - test/Analysis/valist-uninitialized.c
Reapply "[analyzer] Added valist related checkers."
[clang] / test / Analysis / valist-uninitialized.c
1 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,alpha.valist.Uninitialized,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
2
3 #include "Inputs/system-header-simulator-for-valist.h"
4
5 void 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
10 int 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
17 void 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
26 void 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
35 void 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
42 void 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
48 void 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
56 void 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.
65 void 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
72 void 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
82 void 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
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}} expected-note{{va_list 'va' is copied onto itself}}
97   va_end(va);
98 } // no-warning
99
100 void 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
105 void 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
111 void 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
116 void 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
121 void 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
128 void 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."
136 void ends_arg(va_list arg) {
137   va_end(arg);
138 } //no-warning
139
140 void 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().
146 void 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
150 void call_inlined_uses_arg(int fst, ...) {
151   va_list va;
152   inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
153 }
154
155 void 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
162 void 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
167 void 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
174 void call_some_other_func(int n, ...) {
175   va_list va;
176   some_library_function(n, va);
177 } //no-warning
178