diff options
Diffstat (limited to 'test/Analysis/diagnostics/no-store-func-path-notes.cpp')
-rw-r--r-- | test/Analysis/diagnostics/no-store-func-path-notes.cpp | 205 |
1 files changed, 201 insertions, 4 deletions
diff --git a/test/Analysis/diagnostics/no-store-func-path-notes.cpp b/test/Analysis/diagnostics/no-store-func-path-notes.cpp index 17ec96ae5b75d..587c08fae13d5 100644 --- a/test/Analysis/diagnostics/no-store-func-path-notes.cpp +++ b/test/Analysis/diagnostics/no-store-func-path-notes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -x c++ -std=c++14 -analyzer-checker=core -analyzer-output=text -verify %s int initializer1(int &p, int x) { if (x) { // expected-note{{Taking false branch}} @@ -10,10 +10,10 @@ int initializer1(int &p, int x) { } int param_not_initialized_by_func() { - int p; // expected-note {{'p' declared without an initial value}} - int out = initializer1(p, 0); // expected-note{{Calling 'initializer1'}} + int outP; // expected-note {{'outP' declared without an initial value}} + int out = initializer1(outP, 0); // expected-note{{Calling 'initializer1'}} // expected-note@-1{{Returning from 'initializer1'}} - return p; // expected-note{{Undefined or garbage value returned to caller}} + return outP; // expected-note{{Undefined or garbage value returned to caller}} // expected-warning@-1{{Undefined or garbage value returned to caller}} } @@ -175,3 +175,200 @@ void rdar40335545() { //expected-note@-1{{}} (void)useLocal; } + +//////// + +struct HasRef { + int &a; + HasRef(int &a) : a(a) {} +}; + + +void maybeInitialize(const HasRef &&pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA.a = 120; +} // expected-note{{Returning without writing to 'pA.a'}} + +int useMaybeInitializerWritingIntoField() { + int z; // expected-note{{'z' declared without an initial value}} + maybeInitialize(HasRef(z)); // expected-note{{Calling constructor for 'HasRef'}} + // expected-note@-1{{Returning from constructor for 'HasRef'}} + // expected-note@-2{{Calling 'maybeInitialize'}} + // expected-note@-3{{Returning from 'maybeInitialize'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasRefToItself { + HasRefToItself &Ref; // no infinite loop + int &z; + HasRefToItself(int &z) : Ref(*this), z(z) {} +}; + +void maybeInitialize(const HasRefToItself &&pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA.z = 120; +} // expected-note{{Returning without writing to 'pA.Ref.z'}} + +int useMaybeInitializerWritingIntoFieldWithRefToItself() { + int z; // expected-note{{'z' declared without an initial value}} + maybeInitialize(HasRefToItself(z)); // expected-note{{Calling constructor for 'HasRefToItself'}} + // expected-note@-1{{Returning from constructor for 'HasRefToItself'}} + // expected-note@-2{{Calling 'maybeInitialize'}} + // expected-note@-3{{Returning from 'maybeInitialize'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//// + +void maybeInitialize(const HasRef *pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA->a = 120; +} // expected-note{{Returning without writing to 'pA->a'}} + +int useMaybeInitializerStructByPointer() { + int z; // expected-note{{'z' declared without an initial value}} + HasRef wrapper(z); // expected-note{{Calling constructor for 'HasRef'}} + // expected-note@-1{{Returning from constructor for 'HasRef'}} + maybeInitialize(&wrapper); // expected-note{{Calling 'maybeInitialize'}} + // expected-note@-1{{Returning from 'maybeInitialize'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasParentWithRef : public HasRef { + HasParentWithRef(int &a) : HasRef(a) {} // expected-note{{Calling constructor for 'HasRef'}} + // expected-note@-1{{Returning from constructor for 'HasRef'}} +}; + +void maybeInitializeWithParent(const HasParentWithRef &pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA.a = 120; +} // expected-note{{Returning without writing to 'pA.a'}} + +int useMaybeInitializerWritingIntoParentField() { + int z; // expected-note{{'z' declared without an initial value}} + maybeInitializeWithParent(HasParentWithRef(z)); // expected-note{{Calling constructor for 'HasParentWithRef'}} + // expected-note@-1{{Returning from constructor for 'HasParentWithRef'}} + // expected-note@-2{{Calling 'maybeInitializeWithParent'}} + // expected-note@-3{{Returning from 'maybeInitializeWithParent'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasIndirectRef { + HasRef &Ref; + HasIndirectRef(HasRef &Ref) : Ref(Ref) {} +}; + +void maybeInitializeIndirectly(const HasIndirectRef &pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA.Ref.a = 120; +} // expected-note{{Returning without writing to 'pA.Ref.a'}} + +int useMaybeInitializeIndirectly() { + int z; // expected-note{{'z' declared without an initial value}} + HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}} + // expected-note@-1{{Returning from constructor for 'HasRef'}} + maybeInitializeIndirectly(HasIndirectRef(r)); // expected-note{{Calling 'maybeInitializeIndirectly'}} + // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasIndirectRefByValue { + HasRef Ref; + HasIndirectRefByValue(HasRef Ref) : Ref(Ref) {} +}; + +void maybeInitializeIndirectly(const HasIndirectRefByValue &pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA.Ref.a = 120; +} // expected-note{{Returning without writing to 'pA.Ref.a'}} + +int useMaybeInitializeIndirectlyIndirectRefByValue() { + int z; // expected-note{{'z' declared without an initial value}} + HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}} + // expected-note@-1{{Returning from constructor for 'HasRef'}} + maybeInitializeIndirectly(HasIndirectRefByValue(r)); // expected-note{{Calling 'maybeInitializeIndirectly'}} + // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasIndirectPointerRef { + HasRef *Ref; + HasIndirectPointerRef(HasRef *Ref) : Ref(Ref) {} +}; + +void maybeInitializeIndirectly(const HasIndirectPointerRef &pA) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + pA.Ref->a = 120; +} // expected-note{{Returning without writing to 'pA.Ref->a'}} + +int useMaybeInitializeIndirectlyWithPointer() { + int z; // expected-note{{'z' declared without an initial value}} + HasRef r(z); // expected-note{{Calling constructor for 'HasRef'}} + // expected-note@-1{{Returning from constructor for 'HasRef'}} + maybeInitializeIndirectly(HasIndirectPointerRef(&r)); // expected-note{{Calling 'maybeInitializeIndirectly'}} + // expected-note@-1{{Returning from 'maybeInitializeIndirectly'}} + return z; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasFieldA { + int x; +}; + +struct HasFieldB { + int x; +}; + +void maybeInitializeHasField(HasFieldA *b) { + if (coin()) // expected-note{{Assuming the condition is false}} + // expected-note@-1{{Taking false branch}} + ((HasFieldB*)b)->x = 120; +} + +int forceElementRegionApperence() { + HasFieldA a; + maybeInitializeHasField(&a); // expected-note{{Calling 'maybeInitializeHasField'}} + // expected-note@-1{{Returning from 'maybeInitializeHasField'}} + return ((HasFieldB*)&a)->x; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} + +//////// + +struct HasForgottenField { + int x; + HasForgottenField() {} // expected-note{{Returning without writing to 'this->x'}} +}; + +// Test that tracking across exclamation mark works. +bool tracksThroughExclamationMark() { + HasForgottenField a; // expected-note{{Calling default constructor for 'HasForgottenField'}} + // expected-note@-1{{Returning from default constructor for 'HasForgottenField'}} + return !a.x; // expected-warning{{Undefined or garbage value returned to caller}} + // expected-note@-1{{Undefined or garbage value returned to caller}} +} |