Index: lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedPointee.cpp @@ -69,6 +69,14 @@ /// known, and thus FD can not be analyzed. static bool isVoidPointer(QualType T); +/// Dereferences V, and stores the dereferences value in it, the dynamic type +/// of V in DynT, and whether it needs to be casted back in NeedsCastBack. +/// +/// V must be loc::MemRegionVal. +/// +/// If for whatever reason dereferencing fails, returns with false. +static bool dereference(ProgramStateRef State, SVal &V, QualType &DynT); + //===----------------------------------------------------------------------===// // Methods for FindUninitializedFields. //===----------------------------------------------------------------------===// @@ -101,61 +109,19 @@ assert(V.getAs() && "At this point V must be loc::MemRegionVal!"); - auto L = V.castAs(); - - // We can't reason about symbolic regions, assume its initialized. - // Note that this also avoids a potential infinite recursion, because - // constructors for list-like classes are checked without being called, and - // the Static Analyzer will construct a symbolic region for Node *next; or - // similar code snippets. - if (L.getRegion()->getSymbolicBase()) { - IsAnyFieldInitialized = true; - return false; - } - - DynamicTypeInfo DynTInfo = getDynamicTypeInfo(State, L.getRegion()); - if (!DynTInfo.isValid()) { - IsAnyFieldInitialized = true; - return false; - } - - QualType DynT = DynTInfo.getType(); - if (isVoidPointer(DynT)) { - IsAnyFieldInitialized = true; - return false; - } + QualType DynT; // At this point the pointer itself is initialized and points to a valid // location, we'll now check the pointee. - SVal DerefdV = State->getSVal(V.castAs(), DynT); - - // If DerefdV is still a pointer value, we'll dereference it again (e.g.: - // int** -> int*). - while (auto Tmp = DerefdV.getAs()) { - if (Tmp->getRegion()->getSymbolicBase()) { - IsAnyFieldInitialized = true; - return false; - } - - DynTInfo = getDynamicTypeInfo(State, Tmp->getRegion()); - if (!DynTInfo.isValid()) { - IsAnyFieldInitialized = true; - return false; - } - - DynT = DynTInfo.getType(); - if (isVoidPointer(DynT)) { - IsAnyFieldInitialized = true; - return false; - } - - DerefdV = State->getSVal(*Tmp, DynT); + if (!dereference(State, V, DynT)) { + IsAnyFieldInitialized = true; + return false; } // If FR is a pointer pointing to a non-primitive type. if (Optional RecordV = - DerefdV.getAs()) { + V.getAs()) { const TypedValueRegion *R = RecordV->getRegion(); @@ -184,7 +150,7 @@ "At this point FR must either have a primitive dynamic type, or it " "must be a null, undefined, unknown or concrete pointer!"); - if (isPrimitiveUninit(DerefdV)) + if (isPrimitiveUninit(V)) return addFieldToUninits(LocalChain.add(LocField(FR))); IsAnyFieldInitialized = true; @@ -203,3 +169,32 @@ } return false; } + +static bool dereference(ProgramStateRef State, SVal &V, QualType &DynT) { + // If V is multiple pointer value, we'll dereference it again (e.g.: int** -> + // int*). + while (auto Tmp = V.getAs()) { + // We can't reason about symbolic regions, assume its initialized. + // Note that this also avoids a potential infinite recursion, because + // constructors for list-like classes are checked without being called, and + // the Static Analyzer will construct a symbolic region for Node *next; or + // similar code snippets. + if (Tmp->getRegion()->getSymbolicBase()) { + return false; + } + + DynamicTypeInfo DynTInfo = getDynamicTypeInfo(State, Tmp->getRegion()); + if (!DynTInfo.isValid()) { + return false; + } + + DynT = DynTInfo.getType(); + + if (isVoidPointer(DynT)) { + return false; + } + + V = State->getSVal(*Tmp, DynT); + } + return true; +}