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