Index: clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -209,6 +209,7 @@ Report->addNote(Pair.second, PathDiagnosticLocation::create(Pair.first->getDecl(), Context.getSourceManager())); + Report->markInteresting(Pair.first); } Context.emitReport(std::move(Report)); } Index: clang/test/Analysis/cxx-uninitialized-object-tracking.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/cxx-uninitialized-object-tracking.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_analyze_cc1 -std=c++11 -verify %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=optin.cplusplus.UninitializedObject \ +// RUN: -analyzer-config \ +// RUN: optin.cplusplus.UninitializedObject:Pedantic=true \ +// RUN: -analyzer-output=text + +namespace must_have_happened { +struct S { + int x; // expected-note{{uninitialized field 'this->x'}} + S(int r) { + if (r) // expected-note{{Assuming 'r' is 0}} + // expected-note@-1{{Taking false branch}} + x = 5; + } // expected-warning{{1 uninitialized field}} + // expected-note@-1{{1 uninitialized field}} +}; + +void f(int r) { + S s(r); // expected-note{{Calling constructor for 'S'}} +} +} // end of namespace must_have_happened + +namespace inlined_category { +void init(int cond, int &val) { + if (cond) + val = 0; +} + +struct S { + int x; // expected-note{{uninitialized field 'this->x'}} + S(int r) { + init(r, x); + } // expected-warning{{1 uninitialized field}} + // expected-note@-1{{1 uninitialized field}} +}; + +void f(int r) { + S s(r); // expected-note{{Calling constructor for 'S'}} +} +} // end of namespace inlined_category + +namespace not_inlined_category { +void init(int cond, int &val) { + if (cond) + val = 0; +} + +struct S { + int x; // expected-note{{uninitialized field 'this->x'}} + S(int r) { + if (r) // expected-note{{Assuming 'r' is 0}} + // expected-note@-1{{Taking false branch}} + init(r, x); + } // expected-warning{{1 uninitialized field}} + // expected-note@-1{{1 uninitialized field}} +}; + +void f(int r) { + S s(r); // expected-note{{Calling constructor for 'S'}} +} +} // end of namespace not_inlined_category Index: clang/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp =================================================================== --- clang/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp +++ clang/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp @@ -1,6 +1,7 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=core,optin.cplusplus.UninitializedObject \ // RUN: -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ // RUN: -analyzer-config optin.cplusplus.UninitializedObject:IgnoreGuardedFields=true \ +// RUN: -analyzer-output=text \ // RUN: -std=c++11 -verify %s //===----------------------------------------------------------------------===// @@ -158,15 +159,16 @@ public: UnguardedFieldThroughMethodTest(Kind K) : K(K) { - switch (K) { + switch (K) { // expected-note{{Control jumps to 'case A:' at line}} case V: Volume = 0; break; case A: - Area = 0; // expected-warning {{1 uninitialized field}} - break; + Area = 0; + break; // expected-note{{Execution jumps to the end of the function}} } - } + } // expected-warning{{1 uninitialized field}} + // expected-note@-1{{1 uninitialized field}} void operator-() { assert(K == Kind::A); @@ -180,6 +182,7 @@ void fUnguardedFieldThroughMethodTest() { UnguardedFieldThroughMethodTest T1(UnguardedFieldThroughMethodTest::Kind::A); + // expected-note@-1{{Calling constructor for 'UnguardedFieldThroughMethodTest'}} } class UnguardedPublicFieldsTest { @@ -196,15 +199,16 @@ public: UnguardedPublicFieldsTest(Kind K) : K(K) { - switch (K) { + switch (K) { // expected-note{{Control jumps to 'case A:' at line}} case V: Volume = 0; break; case A: - Area = 0; // expected-warning {{1 uninitialized field}} - break; + Area = 0; + break; // expected-note{{Execution jumps to the end of the function}} } - } + } // expected-warning {{1 uninitialized field}} + // expected-note@-1{{1 uninitialized field}} void operator-() { assert(K == Kind::A); @@ -219,6 +223,7 @@ void fUnguardedPublicFieldsTest() { UnguardedPublicFieldsTest T1(UnguardedPublicFieldsTest::Kind::A); + // expected-note@-1{{Calling constructor for 'UnguardedPublicFieldsTest'}} } //===----------------------------------------------------------------------===//