377 lines · cpp
1// RUN: %clang_analyze_cc1 -x c++ -std=c++14 -analyzer-checker=core -analyzer-output=text -verify %s2 3int initializer1(int &p, int x) {4 if (x) { // expected-note{{'x' is 0}}5 // expected-note@-1{{Taking false branch}}6 p = 1;7 return 0;8 } else {9 return 1; // expected-note {{Returning without writing to 'p'}}10 }11}12 13int param_not_initialized_by_func() {14 int outP; // expected-note {{'outP' declared without an initial value}}15 int out = initializer1(outP, 0); // expected-note{{Calling 'initializer1'}}16 // expected-note@-1{{Returning from 'initializer1'}}17 return outP; // expected-note{{Undefined or garbage value returned to caller}}18 // expected-warning@-1{{Undefined or garbage value returned to caller}}19}20 21struct S {22 int initialize(int *p, int param) {23 if (param) { // expected-note{{'param' is 0}}24 // expected-note@-1{{Taking false branch}}25 *p = 1;26 return 1;27 }28 return 0; // expected-note{{Returning without writing to '*p'}}29 }30};31 32int use(S *s) {33 int p; //expected-note{{'p' declared without an initial value}}34 s->initialize(&p, 0); //expected-note{{Calling 'S::initialize'}}35 //expected-note@-1{{Returning from 'S::initialize'}}36 return p; // expected-warning{{Undefined or garbage value returned to caller}}37 // expected-note@-1{{Undefined or garbage value returned to caller}}38}39 40int initializer2(const int &p) {41 return 0;42}43 44int no_msg_const_ref() {45 int p; //expected-note{{'p' declared without an initial value}}46 initializer2(p);47 return p; // expected-warning{{Undefined or garbage value returned to caller}}48 // expected-note@-1{{Undefined or garbage value returned to caller}}49}50 51void nested() {}52void init_in_nested_func(int **x) {53 *x = 0; // expected-note{{Null pointer value stored to 'y'}}54 nested();55} // no-note56 57int call_init_nested() {58 int x = 0;59 int *y = &x;60 init_in_nested_func(&y); // expected-note{{Calling 'init_in_nested_func'}}61 // expected-note@-1{{Returning from 'init_in_nested_func'}}62 return *y; //expected-warning{{Dereference of null pointer (loaded from variable 'y')}}63 //expected-note@-1{{Dereference of null pointer (loaded from variable 'y')}}64}65 66struct A {67 int x;68 int y;69};70 71void partial_init_by_reference(A &a) {72 a.x = 0;73} // expected-note {{Returning without writing to 'a.y'}}74 75int use_partial_init_by_reference() {76 A a;77 partial_init_by_reference(a); // expected-note{{Calling 'partial_init_by_reference'}}78 // expected-note@-1{{Returning from 'partial_init_by_reference'}}79 return a.y; // expected-warning{{Undefined or garbage value returned to caller}}80 // expected-note@-1{{Undefined or garbage value returned to caller}}81}82 83struct B : A {84};85 86void partially_init_inherited_struct(B *b) {87 b->x = 0;88} // expected-note{{Returning without writing to 'b->y'}}89 90int use_partially_init_inherited_struct() {91 B b;92 partially_init_inherited_struct(&b); // expected-note{{Calling 'partially_init_inherited_struct'}}93 // expected-note@-1{{Returning from 'partially_init_inherited_struct'}}94 return b.y; // expected-warning{{Undefined or garbage value returned to caller}}95 // expected-note@-1{{Undefined or garbage value returned to caller}}96}97 98struct C {99 int x;100 int y;101 C(int pX, int pY) : x(pX) {} // expected-note{{Returning without writing to 'this->y'}}102 103 C(int pX, int pY, bool Flag) {104 x = pX;105 if (Flag) // expected-note{{Assuming 'Flag' is true}}106 // expected-note@-1{{Taking true branch}}107 return; // expected-note{{Returning without writing to 'this->y'}}108 y = pY;109 }110};111 112int use_constructor() {113 C c(0, 0); // expected-note{{Calling constructor for 'C'}}114 // expected-note@-1{{Returning from constructor for 'C'}}115 return c.y; // expected-note{{Undefined or garbage value returned to caller}}116 // expected-warning@-1{{Undefined or garbage value returned to caller}}117}118 119int coin();120 121int use_other_constructor() {122 C c(0, 0, coin()); // expected-note{{Calling constructor for 'C'}}123 // expected-note@-1{{Returning from constructor for 'C'}}124 return c.y; // expected-note{{Undefined or garbage value returned to caller}}125 // expected-warning@-1{{Undefined or garbage value returned to caller}}126}127 128struct D {129 void initialize(int *);130};131 132void D::initialize(int *p) {133 134} // expected-note{{Returning without writing to '*p'}}135 136int use_d_initializer(D* d) {137 int p; // expected-note {{'p' declared without an initial value}}138 d->initialize(&p); // expected-note{{Calling 'D::initialize'}}139 // expected-note@-1{{Returning from 'D::initialize'}}140 return p; // expected-note{{Undefined or garbage value returned to caller}}141 // expected-warning@-1{{Undefined or garbage value returned to caller}}142}143 144struct S2 {145 int x;146};147 148int pointerreference(S2* &s) {149 if (coin()) // expected-note{{Assuming the condition is true}}150 // expected-note@-1{{Taking true branch}}151 return 1; // expected-note{{Returning without writing to 's->x'}}152 153 s->x = 0;154 return 0;155}156 157int usepointerreference() {158 S2 s;159 S2* p = &s;160 pointerreference(p); //expected-note{{Calling 'pointerreference'}}161 //expected-note@-1{{Returning from 'pointerreference'}}162 return s.x; // expected-warning{{Undefined or garbage value returned to caller}}163 // expected-note@-1{{Undefined or garbage value returned to caller}}164}165 166void *has_no_argument_and_returns_null(void) {167 return 0;168}169 170void rdar40335545() {171 int local; // expected-note{{}}172 void (*takes_int_ptr_argument)(int *) = (void (*)(int*))has_no_argument_and_returns_null;173 174 takes_int_ptr_argument(&local); // no-crash175 176 int useLocal = local; //expected-warning{{}}177 //expected-note@-1{{}}178 (void)useLocal;179}180 181////////182 183struct HasRef {184 int &a;185 HasRef(int &a) : a(a) {}186};187 188 189void maybeInitialize(const HasRef &&pA) {190 if (coin()) // expected-note{{Assuming the condition is false}}191 // expected-note@-1{{Taking false branch}}192 pA.a = 120;193} // expected-note{{Returning without writing to 'pA.a'}}194 195int useMaybeInitializerWritingIntoField() {196 int z; // expected-note{{'z' declared without an initial value}}197 maybeInitialize(HasRef(z)); // expected-note{{Calling constructor for 'HasRef'}}198 // expected-note@-1{{Returning from constructor for 'HasRef'}}199 // expected-note@-2{{Calling 'maybeInitialize'}}200 // expected-note@-3{{Returning from 'maybeInitialize'}}201 return z; // expected-warning{{Undefined or garbage value returned to caller}}202 // expected-note@-1{{Undefined or garbage value returned to caller}}203}204 205////////206 207struct HasRefToItself {208 HasRefToItself &Ref; // no infinite loop209 int &z;210 HasRefToItself(int &z) : Ref(*this), z(z) {}211};212 213void maybeInitialize(const HasRefToItself &&pA) {214 if (coin()) // expected-note{{Assuming the condition is false}}215 // expected-note@-1{{Taking false branch}}216 pA.z = 120;217} // expected-note{{Returning without writing to 'pA.Ref.z'}}218 219int useMaybeInitializerWritingIntoFieldWithRefToItself() {220 int z; // expected-note{{'z' declared without an initial value}}221 maybeInitialize(HasRefToItself(z)); // expected-note{{Calling constructor for 'HasRefToItself'}}222 // expected-note@-1{{Returning from constructor for 'HasRefToItself'}}223 // expected-note@-2{{Calling 'maybeInitialize'}}224 // expected-note@-3{{Returning from 'maybeInitialize'}}225 return z; // expected-warning{{Undefined or garbage value returned to caller}}226 // expected-note@-1{{Undefined or garbage value returned to caller}}227}228 229////230 231void maybeInitialize(const HasRef *pA) {232 if (coin()) // expected-note{{Assuming the condition is false}}233 // expected-note@-1{{Taking false branch}}234 pA->a = 120;235} // expected-note{{Returning without writing to 'pA->a'}}236 237int useMaybeInitializerStructByPointer() {238 int z; // expected-note{{'z' declared without an initial value}}239 HasRef wrapper(z); // expected-note{{Calling constructor for 'HasRef'}}240 // expected-note@-1{{Returning from constructor for 'HasRef'}}241 maybeInitialize(&wrapper); // expected-note{{Calling 'maybeInitialize'}}242 // expected-note@-1{{Returning from 'maybeInitialize'}}243 return z; // expected-warning{{Undefined or garbage value returned to caller}}244 // expected-note@-1{{Undefined or garbage value returned to caller}}245}246 247////////248 249struct HasParentWithRef : public HasRef {250 HasParentWithRef(int &a) : HasRef(a) {} // expected-note{{Calling constructor for 'HasRef'}}251 // expected-note@-1{{Returning from constructor for 'HasRef'}}252};253 254void maybeInitializeWithParent(const HasParentWithRef &pA) {255 if (coin()) // expected-note{{Assuming the condition is false}}256 // expected-note@-1{{Taking false branch}}257 pA.a = 120;258} // expected-note{{Returning without writing to 'pA.a'}}259 260int useMaybeInitializerWritingIntoParentField() {261 int z; // expected-note{{'z' declared without an initial value}}262 maybeInitializeWithParent(HasParentWithRef(z)); // expected-note{{Calling constructor for 'HasParentWithRef'}}263 // expected-note@-1{{Returning from constructor for 'HasParentWithRef'}}264 // expected-note@-2{{Calling 'maybeInitializeWithParent'}}265 // expected-note@-3{{Returning from 'maybeInitializeWithParent'}}266 return z; // expected-warning{{Undefined or garbage value returned to caller}}267 // expected-note@-1{{Undefined or garbage value returned to caller}}268}269 270////////271 272struct HasIndirectRef {273 HasRef &Ref;274 HasIndirectRef(HasRef &Ref) : Ref(Ref) {}275};276 277void maybeInitializeIndirectly(const HasIndirectRef &pA) {278 if (coin()) // expected-note{{Assuming the condition is false}}279 // expected-note@-1{{Taking false branch}}280 pA.Ref.a = 120;281} // expected-note{{Returning without writing to 'pA.Ref.a'}}282 283int useMaybeInitializeIndirectly() {284 int z; // expected-note{{'z' declared without an initial value}}285 HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}}286 // expected-note@-1{{Returning from constructor for 'HasRef'}}287 maybeInitializeIndirectly(HasIndirectRef(r)); // expected-note{{Calling 'maybeInitializeIndirectly'}}288 // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}}289 return z; // expected-warning{{Undefined or garbage value returned to caller}}290 // expected-note@-1{{Undefined or garbage value returned to caller}}291}292 293////////294 295struct HasIndirectRefByValue {296 HasRef Ref;297 HasIndirectRefByValue(HasRef Ref) : Ref(Ref) {}298};299 300void maybeInitializeIndirectly(const HasIndirectRefByValue &pA) {301 if (coin()) // expected-note{{Assuming the condition is false}}302 // expected-note@-1{{Taking false branch}}303 pA.Ref.a = 120;304} // expected-note{{Returning without writing to 'pA.Ref.a'}}305 306int useMaybeInitializeIndirectlyIndirectRefByValue() {307 int z; // expected-note{{'z' declared without an initial value}}308 HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}}309 // expected-note@-1{{Returning from constructor for 'HasRef'}}310 maybeInitializeIndirectly(HasIndirectRefByValue(r)); // expected-note{{Calling 'maybeInitializeIndirectly'}}311 // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}}312 return z; // expected-warning{{Undefined or garbage value returned to caller}}313 // expected-note@-1{{Undefined or garbage value returned to caller}}314}315 316////////317 318struct HasIndirectPointerRef {319 HasRef *Ref;320 HasIndirectPointerRef(HasRef *Ref) : Ref(Ref) {}321};322 323void maybeInitializeIndirectly(const HasIndirectPointerRef &pA) {324 if (coin()) // expected-note{{Assuming the condition is false}}325 // expected-note@-1{{Taking false branch}}326 pA.Ref->a = 120;327} // expected-note{{Returning without writing to 'pA.Ref->a'}}328 329int useMaybeInitializeIndirectlyWithPointer() {330 int z; // expected-note{{'z' declared without an initial value}}331 HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}}332 // expected-note@-1{{Returning from constructor for 'HasRef'}}333 maybeInitializeIndirectly(HasIndirectPointerRef(&r)); // expected-note{{Calling 'maybeInitializeIndirectly'}}334 // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}}335 return z; // expected-warning{{Undefined or garbage value returned to caller}}336 // expected-note@-1{{Undefined or garbage value returned to caller}}337}338 339////////340 341struct HasFieldA {342 int x;343};344 345struct HasFieldB {346 int x;347};348 349void maybeInitializeHasField(HasFieldA *b) {350 if (coin()) // expected-note{{Assuming the condition is false}}351 // expected-note@-1{{Taking false branch}}352 ((HasFieldB*)b)->x = 120;353}354 355int forceElementRegionApperence() {356 HasFieldA a;357 maybeInitializeHasField(&a); // expected-note{{Calling 'maybeInitializeHasField'}}358 // expected-note@-1{{Returning from 'maybeInitializeHasField'}}359 return ((HasFieldB*)&a)->x; // expected-warning{{Undefined or garbage value returned to caller}}360 // expected-note@-1{{Undefined or garbage value returned to caller}}361}362 363////////364 365struct HasForgottenField {366 int x;367 HasForgottenField() {} // expected-note{{Returning without writing to 'this->x'}}368};369 370// Test that tracking across exclamation mark works.371bool tracksThroughExclamationMark() {372 HasForgottenField a; // expected-note{{Calling default constructor for 'HasForgottenField'}}373 // expected-note@-1{{Returning from default constructor for 'HasForgottenField'}}374 return !a.x; // expected-warning{{Undefined or garbage value returned to caller}}375 // expected-note@-1{{Undefined or garbage value returned to caller}}376}377