1 // RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core -analyzer-output=text -verify %s
2 
3 int initializer1(int &p, int x) {
4   if (x) { // expected-note{{Taking false branch}}
5     p = 1;
6     return 0;
7   } else {
8     return 1; // expected-note {{Returning without writing to 'p'}}
9   }
10 }
11 
12 int param_not_initialized_by_func() {
13   int p;                        // expected-note {{'p' declared without an initial value}}
14   int out = initializer1(p, 0); // expected-note{{Calling 'initializer1'}}
15                                 // expected-note@-1{{Returning from 'initializer1'}}
16   return p;                     // expected-note{{Undefined or garbage value returned to caller}}
17                                 // expected-warning@-1{{Undefined or garbage value returned to caller}}
18 }
19 
20 struct S {
21   int initialize(int *p, int param) {
22     if (param) { //expected-note{{Taking false branch}}
23       *p = 1;
24       return 1;
25     }
26     return 0; // expected-note{{Returning without writing to '*p'}}
27   }
28 };
29 
30 int use(S *s) {
31   int p;                //expected-note{{'p' declared without an initial value}}
32   s->initialize(&p, 0); //expected-note{{Calling 'S::initialize'}}
33                         //expected-note@-1{{Returning from 'S::initialize'}}
34   return p;             // expected-warning{{Undefined or garbage value returned to caller}}
35                         // expected-note@-1{{Undefined or garbage value returned to caller}}
36 }
37 
38 int initializer2(const int &p) {
39   return 0;
40 }
41 
42 int no_msg_const_ref() {
43   int p; //expected-note{{'p' declared without an initial value}}
44   initializer2(p);
45   return p; // expected-warning{{Undefined or garbage value returned to caller}}
46             // expected-note@-1{{Undefined or garbage value returned to caller}}
47 }
48 
49 void nested() {}
50 void init_in_nested_func(int **x) {
51   *x = 0; // expected-note{{Null pointer value stored to 'y'}}
52   nested();
53 } // no-note
54 
55 int call_init_nested() {
56   int x = 0;
57   int *y = &x;
58   init_in_nested_func(&y); // expected-note{{Calling 'init_in_nested_func'}}
59                            // expected-note@-1{{Returning from 'init_in_nested_func'}}
60   return *y;               //expected-warning{{Dereference of null pointer (loaded from variable 'y')}}
61                            //expected-note@-1{{Dereference of null pointer (loaded from variable 'y')}}
62 }
63 
64 struct A {
65   int x;
66   int y;
67 };
68 
69 void partial_init_by_reference(A &a) {
70   a.x = 0;
71 } // expected-note {{Returning without writing to 'a.y'}}
72 
73 int use_partial_init_by_reference() {
74   A a;
75   partial_init_by_reference(a); // expected-note{{Calling 'partial_init_by_reference'}}
76                                 // expected-note@-1{{Returning from 'partial_init_by_reference'}}
77   return a.y;                   // expected-warning{{Undefined or garbage value returned to caller}}
78                                 // expected-note@-1{{Undefined or garbage value returned to caller}}
79 }
80 
81 struct B : A {
82 };
83 
84 void partially_init_inherited_struct(B *b) {
85   b->x = 0;
86 } // expected-note{{Returning without writing to 'b->y'}}
87 
88 int use_partially_init_inherited_struct() {
89   B b;
90   partially_init_inherited_struct(&b); // expected-note{{Calling 'partially_init_inherited_struct'}}
91                                        // expected-note@-1{{Returning from 'partially_init_inherited_struct'}}
92   return b.y;                          // expected-warning{{Undefined or garbage value returned to caller}}
93                                        // expected-note@-1{{Undefined or garbage value returned to caller}}
94 }
95 
96 struct C {
97   int x;
98   int y;
99   C(int pX, int pY) : x(pX) {} // expected-note{{Returning without writing to 'this->y'}}
100 
101   C(int pX, int pY, bool Flag) {
102     x = pX;
103     if (Flag) // expected-note{{Assuming 'Flag' is not equal to 0}}
104               // expected-note@-1{{Taking true branch}}
105       return; // expected-note{{Returning without writing to 'this->y'}}
106     y = pY;
107   }
108 };
109 
110 int use_constructor() {
111   C c(0, 0); // expected-note{{Calling constructor for 'C'}}
112              // expected-note@-1{{Returning from constructor for 'C'}}
113   return c.y; // expected-note{{Undefined or garbage value returned to caller}}
114               // expected-warning@-1{{Undefined or garbage value returned to caller}}
115 }
116 
117 int coin();
118 
119 int use_other_constructor() {
120   C c(0, 0, coin()); // expected-note{{Calling constructor for 'C'}}
121                      // expected-note@-1{{Returning from constructor for 'C'}}
122   return c.y; // expected-note{{Undefined or garbage value returned to caller}}
123               // expected-warning@-1{{Undefined or garbage value returned to caller}}
124 }
125 
126 struct D {
127   void initialize(int *);
128 };
129 
130 void D::initialize(int *p) {
131 
132 } // expected-note{{Returning without writing to '*p'}}
133 
134 int use_d_initializer(D* d) {
135   int p; // expected-note {{'p' declared without an initial value}}
136   d->initialize(&p); // expected-note{{Calling 'D::initialize'}}
137                      // expected-note@-1{{Returning from 'D::initialize'}}
138   return p;                     // expected-note{{Undefined or garbage value returned to caller}}
139                                 // expected-warning@-1{{Undefined or garbage value returned to caller}}
140 }
141 
142 struct S2 {
143   int x;
144 };
145 
146 int pointerreference(S2* &s) {
147   if (coin()) // expected-note{{Assuming the condition is true}}
148               // expected-note@-1{{Taking true branch}}
149     return 1; // expected-note{{Returning without writing to 's->x'}}
150 
151   s->x = 0;
152   return 0;
153 }
154 
155 int usepointerreference() {
156   S2 s;
157   S2* p = &s;
158   pointerreference(p); //expected-note{{Calling 'pointerreference'}}
159                          //expected-note@-1{{Returning from 'pointerreference'}}
160   return s.x; // expected-warning{{Undefined or garbage value returned to caller}}
161               // expected-note@-1{{Undefined or garbage value returned to caller}}
162 }
163 
164 void *has_no_argument_and_returns_null(void) {
165   return 0;
166 }
167 
168 void rdar40335545() {
169     int local; // expected-note{{}}
170     void (*takes_int_ptr_argument)(int *) = (void (*)(int*))has_no_argument_and_returns_null;
171 
172     takes_int_ptr_argument(&local); // no-crash
173 
174     int useLocal = local; //expected-warning{{}}
175                           //expected-note@-1{{}}
176     (void)useLocal;
177 }
178