Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1527,7 +1527,15 @@ if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) { Optional PS = Succ->getLocationAs(); - if (!PS || PS->getLocationValue() != R) + if (!PS) + return nullptr; + + const auto *LPtr = PS->getLocationValue(); + if (!LPtr) + return nullptr; + const auto *L = reinterpret_cast(LPtr); + + if (PS->getLocationValue() != R && !R->isSubRegionOf(L)) return nullptr; } @@ -1539,7 +1547,12 @@ if (const BinaryOperator *BO = P->getStmtAs()) { if (BO->isAssignmentOp()) InitE = BO->getRHS(); + } else if (const CXXOperatorCallExpr *CE = + P->getStmtAs()) { + if (CE->isAssignmentOp()) + InitE = CE->getArg(1); } + // If we have a declaration like 'S s{1,2}' that needs special // handling, we handle it here. else if (const auto *DS = P->getStmtAs()) { @@ -2157,7 +2170,7 @@ return peelOffOuterExpr(SubEx, N); if (auto *UO = dyn_cast(Ex)) { - if (UO->getOpcode() == UO_LNot) + if (UO->getOpcode() == UO_LNot || UO->getOpcode() == clang::UO_Minus) return peelOffOuterExpr(UO->getSubExpr(), N); // FIXME: There's a hack in our Store implementation that always computes Index: clang/test/Analysis/diagnostics/no-store-func-path-notes.c =================================================================== --- clang/test/Analysis/diagnostics/no-store-func-path-notes.c +++ clang/test/Analysis/diagnostics/no-store-func-path-notes.c @@ -160,9 +160,9 @@ } // expected-note{{Returning without writing to 'c->b.y'}} int use_partial_nested_initializer(void) { - B localB; + B localB; // expected-note{{'localB' initialized here}} C localC; - localC.b = localB; + localC.b = localB; // expected-note{{Uninitialized value stored to 'localC.b.y'}} partial_nested_initializer(&localC); // expected-note{{Calling 'partial_nested_initializer'}} // expected-note@-1{{Returning from 'partial_nested_initializer'}} return localC.b.y; // expected-warning{{Undefined or garbage value returned to caller}} @@ -170,8 +170,8 @@ } void test_subregion_assignment(C* c) { - B b; - c->b = b; + B b; // expected-note{{'b' initialized here}} + c->b = b; // expected-note{{Uninitialized value stored to 'c.b.x'}} } int use_subregion_assignment(void) { Index: clang/test/Analysis/uninit-vals.m =================================================================== --- clang/test/Analysis/uninit-vals.m +++ clang/test/Analysis/uninit-vals.m @@ -293,7 +293,7 @@ IntPoint2D a; a.x = 0; - IntPoint2D b = a; + IntPoint2D b = a; // expected-note{{'b.y'}} extern void useInt(int); useInt(b.x); // no-warning useInt(b.y); // expected-warning{{uninitialized}} @@ -372,11 +372,11 @@ struct { int x : 4; int y : 4; - } a, b; + } a, b; // expected-note{{'a' initialized here}} a.y = 2; - b = a; + b = a; // expected-note{{Uninitialized value stored to 'b.x'}} clang_analyzer_eval(b.y == 2); // expected-warning{{TRUE}} // expected-note@-1{{TRUE}} clang_analyzer_eval(b.x == 1); // expected-warning{{garbage}} @@ -387,11 +387,11 @@ struct { int x : 4; int y : 4; - } a, b; + } a, b; // expected-note{{'a' initialized here}} a.x = 1; - b = a; + b = a; // expected-note{{Uninitialized value stored to 'b.y'}} clang_analyzer_eval(b.x == 1); // expected-warning{{TRUE}} // expected-note@-1{{TRUE}} clang_analyzer_eval(b.y == 2); // expected-warning{{garbage}}