Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp @@ -190,6 +190,10 @@ const TypedValueRegion *R = RecordV->getRegion(); + while (R->getAs()) { + R = R->getSuperRegion()->getAs(); + } + if (DynT->getPointeeType()->isStructureOrClassType()) { if (NeedsCastBack) return isNonUnionUninit(R, LocalChain.add(NeedsCastLocField(FR, DynT))); Index: test/Analysis/cxx-uninitialized-object-inheritance.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-inheritance.cpp +++ test/Analysis/cxx-uninitialized-object-inheritance.cpp @@ -781,21 +781,40 @@ // Dynamic type test. //===----------------------------------------------------------------------===// -struct DynTBase {}; -struct DynTDerived : DynTBase { +struct DynTBase1 {}; +struct DynTDerived1 : DynTBase1 { // TODO: we'd expect the note: {{uninitialized field 'this->x'}} int x; // no-note }; -struct DynamicTypeTest { - DynTBase *bptr; +struct DynamicTypeTest1 { + DynTBase1 *bptr; int i = 0; // TODO: we'd expect the warning: {{1 uninitialized field}} - DynamicTypeTest(DynTBase *bptr) : bptr(bptr) {} // no-warning + DynamicTypeTest1(DynTBase1 *bptr) : bptr(bptr) {} // no-warning }; -void f() { - DynTDerived d; - DynamicTypeTest t(&d); +void fDynamicTypeTest1() { + DynTDerived1 d; + DynamicTypeTest1 t(&d); }; + +struct DynTBase2 { + int x; // expected-note{{uninitialized field 'this->bptr->x'}} +}; +struct DynTDerived2 : DynTBase2 { + int y; // expected-note{{uninitialized field 'this->bptr->y'}} +}; + +struct DynamicTypeTest2 { + DynTBase2 *bptr; + int i = 0; + + DynamicTypeTest2(DynTBase2 *bptr) : bptr(bptr) {} // expected-warning{{2 uninitialized fields}} +}; + +void fDynamicTypeTest2() { + DynTDerived2 d; + DynamicTypeTest2 t(&d); +}