1 // RUN: %clang_analyze_cc1 -w -x c -analyzer-checker=core -analyzer-output=text\
2 // RUN:     -verify %s
3 
4 typedef __typeof(sizeof(int)) size_t;
5 void *memset(void *__s, int __c, size_t __n);
6 
7 int initializer1(int *p, int x) {
8   if (x) { // expected-note{{Taking false branch}}
9     *p = 1;
10     return 0;
11   } else {
12     return 1; // expected-note {{Returning without writing to '*p'}}
13   }
14 }
15 
16 int param_not_initialized_by_func() {
17   int p; // expected-note {{'p' declared without an initial value}}
18   int out = initializer1(&p, 0); // expected-note{{Calling 'initializer1'}}
19                                  // expected-note@-1{{Returning from 'initializer1'}}
20   return p; // expected-note{{Undefined or garbage value returned to caller}}
21             // expected-warning@-1{{Undefined or garbage value returned to caller}}
22 }
23 
24 int param_initialized_properly() {
25   int p;
26   int out = initializer1(&p, 1);
27   return p; //no-warning
28 }
29 
30 static int global;
31 
32 int initializer2(int **p, int x) {
33   if (x) { // expected-note{{Taking false branch}}
34     *p = &global;
35     return 0;
36   } else {
37     return 1; // expected-note {{Returning without writing to '*p'}}
38   }
39 }
40 
41 int param_not_written_into_by_func() {
42   int *p = 0;                    // expected-note{{'p' initialized to a null pointer value}}
43   int out = initializer2(&p, 0); // expected-note{{Calling 'initializer2'}}
44                                  // expected-note@-1{{Returning from 'initializer2'}}
45   return *p;                     // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
46                                  // expected-note@-1{{Dereference of null pointer (loaded from variable 'p')}}
47 }
48 
49 void initializer3(int *p, int param) {
50   if (param) // expected-note{{Taking false branch}}
51     *p = 0;
52 } // expected-note{{Returning without writing to '*p'}}
53 
54 int param_written_into_by_void_func() {
55   int p;               // expected-note{{'p' declared without an initial value}}
56   initializer3(&p, 0); // expected-note{{Calling 'initializer3'}}
57                        // expected-note@-1{{Returning from 'initializer3'}}
58   return p;            // expected-warning{{Undefined or garbage value returned to caller}}
59                        // expected-note@-1{{Undefined or garbage value returned to caller}}
60 }
61 
62 void initializer4(int *p, int param) {
63   if (param) // expected-note{{Taking false branch}}
64     *p = 0;
65 } // expected-note{{Returning without writing to '*p'}}
66 
67 void initializer5(int *p, int param) {
68   if (!param) // expected-note{{Taking false branch}}
69     *p = 0;
70 } // expected-note{{Returning without writing to '*p'}}
71 
72 int multi_init_tries_func() {
73   int p;               // expected-note{{'p' declared without an initial value}}
74   initializer4(&p, 0); // expected-note{{Calling 'initializer4'}}
75                        // expected-note@-1{{Returning from 'initializer4'}}
76   initializer5(&p, 1); // expected-note{{Calling 'initializer5'}}
77                        // expected-note@-1{{Returning from 'initializer5'}}
78   return p;            // expected-warning{{Undefined or garbage value returned to caller}}
79                        // expected-note@-1{{Undefined or garbage value returned to caller}}
80 }
81 
82 int initializer6(const int *p) {
83   return 0;
84 }
85 
86 int no_msg_on_const() {
87   int p; // expected-note{{'p' declared without an initial value}}
88   initializer6(&p);
89   return p; // expected-warning{{Undefined or garbage value returned to caller}}
90             // expected-note@-1{{Undefined or garbage value returned to caller}}
91 }
92 
93 typedef struct {
94   int x;
95 } S;
96 
97 int initializer7(S *s, int param) {
98   if (param) { // expected-note{{Taking false branch}}
99     s->x = 0;
100     return 0;
101   }
102   return 1; // expected-note{{Returning without writing to 's->x'}}
103 }
104 
105 int initialize_struct_field() {
106   S local;
107   initializer7(&local, 0); // expected-note{{Calling 'initializer7'}}
108                            // expected-note@-1{{Returning from 'initializer7'}}
109   return local.x;          // expected-warning{{Undefined or garbage value returned to caller}}
110                            // expected-note@-1{{Undefined or garbage value returned to caller}}
111 }
112 
113 void nullwriter(int **p) {
114   *p = 0; // expected-note{{Null pointer value stored to 'p'}}
115 } // no extra note
116 
117 int usage() {
118   int x = 0;
119   int *p = &x;
120   nullwriter(&p); // expected-note{{Calling 'nullwriter'}}
121                   // expected-note@-1{{Returning from 'nullwriter'}}
122   return *p;      // expected-warning{{Dereference of null pointer (loaded from variable 'p')}}
123                   // expected-note@-1{{Dereference of null pointer (loaded from variable 'p')}}
124 }
125 
126 typedef struct {
127   int x;
128   int y;
129 } A;
130 
131 void partial_initializer(A *a) {
132   a->x = 0;
133 } // expected-note{{Returning without writing to 'a->y'}}
134 
135 int use_partial_initializer() {
136   A a;
137   partial_initializer(&a); // expected-note{{Calling 'partial_initializer'}}
138                            // expected-note@-1{{Returning from 'partial_initializer'}}
139   return a.y;              // expected-warning{{Undefined or garbage value returned to caller}}
140                            // expected-note@-1{{Undefined or garbage value returned to caller}}
141 }
142 
143 typedef struct {
144   int x;
145   int y;
146 } B;
147 
148 typedef struct {
149   B b;
150 } C;
151 
152 void partial_nested_initializer(C *c) {
153   c->b.x = 0;
154 } // expected-note{{Returning without writing to 'c->b.y'}}
155 
156 int use_partial_nested_initializer() {
157   B localB;
158   C localC;
159   localC.b = localB;
160   partial_nested_initializer(&localC); // expected-note{{Calling 'partial_nested_initializer'}}
161                                        // expected-note@-1{{Returning from 'partial_nested_initializer'}}
162   return localC.b.y;                   // expected-warning{{Undefined or garbage value returned to caller}}
163                                        // expected-note@-1{{Undefined or garbage value returned to caller}}
164 }
165 
166 void test_subregion_assignment(C* c) {
167   B b;
168   c->b = b;
169 }
170 
171 int use_subregion_assignment() {
172   C c;
173   test_subregion_assignment(&c); // expected-note{{Calling 'test_subregion_assignment'}}
174                                  // expected-note@-1{{Returning from 'test_subregion_assignment'}}
175   return c.b.x; // expected-warning{{Undefined or garbage value returned to caller}}
176                 // expected-note@-1{{Undefined or garbage value returned to caller}}
177 }
178 
179 int confusing_signature(int *);
180 int confusing_signature(int *p) {
181   return 0; // expected-note{{Returning without writing to '*p'}}
182 }
183 
184 int use_confusing_signature() {
185   int a; // expected-note {{'a' declared without an initial value}}
186   confusing_signature(&a); // expected-note{{Calling 'confusing_signature'}}
187                            // expected-note@-1{{Returning from 'confusing_signature'}}
188   return a; // expected-note{{Undefined or garbage value returned to caller}}
189             // expected-warning@-1{{Undefined or garbage value returned to caller}}
190 }
191 
192 int coin();
193 
194 int multiindirection(int **p) {
195   if (coin()) // expected-note{{Assuming the condition is true}}
196               // expected-note@-1{{Taking true branch}}
197     return 1; // expected-note{{Returning without writing to '**p'}}
198   *(*p) = 0;
199   return 0;
200 }
201 
202 int usemultiindirection() {
203   int a; // expected-note {{'a' declared without an initial value}}
204   int *b = &a;
205   multiindirection(&b); // expected-note{{Calling 'multiindirection'}}
206                         // expected-note@-1{{Returning from 'multiindirection'}}
207   return a; // expected-note{{Undefined or garbage value returned to caller}}
208             // expected-warning@-1{{Undefined or garbage value returned to caller}}
209 }
210 
211 int indirectingstruct(S** s) {
212   if (coin()) // expected-note{{Assuming the condition is true}}
213               // expected-note@-1{{Taking true branch}}
214     return 1; // expected-note{{Returning without writing to '(*s)->x'}}
215 
216   (*s)->x = 0;
217   return 0;
218 }
219 
220 int useindirectingstruct() {
221   S s;
222   S* p = &s;
223   indirectingstruct(&p); //expected-note{{Calling 'indirectingstruct'}}
224                          //expected-note@-1{{Returning from 'indirectingstruct'}}
225   return s.x; // expected-warning{{Undefined or garbage value returned to caller}}
226               // expected-note@-1{{Undefined or garbage value returned to caller}}
227 }
228 
229 typedef struct {
230   int *x;
231 } D;
232 
233 void initializeMaybeInStruct(D* pD) {
234   if (coin()) // expected-note{{Assuming the condition is false}}
235               // expected-note@-1{{Taking false branch}}
236     *pD->x = 120;
237 } // expected-note{{Returning without writing to 'pD->x'}}
238 
239 int useInitializeMaybeInStruct() {
240   int z; // expected-note{{'z' declared without an initial value}}
241   D d;
242   d.x = &z;
243   initializeMaybeInStruct(&d); // expected-note{{Calling 'initializeMaybeInStruct'}}
244                                // expected-note@-1{{Returning from 'initializeMaybeInStruct'}}
245   return z; // expected-warning{{Undefined or garbage value returned to caller}}
246             // expected-note@-1{{Undefined or garbage value returned to caller}}
247 }
248 
249 void test_implicit_function_decl(int *x) {
250   if (x) {} // expected-note{{Assuming 'x' is null}}
251             // expected-note@-1{{Taking false branch}}
252   implicit_function(x);
253   *x = 4; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
254           // expected-note@-1{{Dereference of null pointer (loaded from variable 'x')}}
255 }
256 int implicit_function(int *y) {}
257