Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -292,15 +292,15 @@ continue; } - if (isDereferencableType(T)) { + SVal V = State->getSVal(FieldVal); + + if (isDereferencableType(T) || V.getAs()) { if (isPointerOrReferenceUninit(FR, LocalChain)) ContainsUninitField = true; continue; } if (isPrimitiveType(T)) { - SVal V = State->getSVal(FieldVal); - if (isPrimitiveUninit(V)) { if (addFieldToUninits(LocalChain.add(RegularField(FR)))) ContainsUninitField = true; Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp @@ -60,9 +60,9 @@ } }; -/// Represents a void* field that needs to be casted back to its dynamic type -/// for a correct note message. -class NeedsCastLocField final : public FieldNode { +/// Represents a nonloc::LocAsInteger or void* field, that point to objects, but +/// needs to be casted back to its dynamic type for a correct note message. +class NeedsCastLocField : public FieldNode { QualType CastBackType; public: @@ -74,7 +74,13 @@ } virtual void printPrefix(llvm::raw_ostream &Out) const override { - Out << "static_cast" << '<' << CastBackType.getAsString() << ">("; + // If this object is a nonloc::LocAsInteger. + if (getDecl()->getType()->isIntegerType()) + Out << "reinterpret_cast"; + // If this pointer's dynamic type is different then it's static type. + else + Out << "static_cast"; + Out << '<' << CastBackType.getAsString() << ">("; } virtual void printNode(llvm::raw_ostream &Out) const override { @@ -107,16 +113,15 @@ // Methods for FindUninitializedFields. //===----------------------------------------------------------------------===// -// Note that pointers/references don't contain fields themselves, so in this -// function we won't add anything to LocalChain. bool FindUninitializedFields::isPointerOrReferenceUninit( const FieldRegion *FR, FieldChainInfo LocalChain) { - assert(isDereferencableType(FR->getDecl()->getType()) && - "This method only checks dereferencable objects!"); - SVal V = State->getSVal(FR); + assert((isDereferencableType(FR->getDecl()->getType()) || + V.getAs()) && + "This method only checks dereferencable objects!"); + if (V.isUnknown() || V.getAs()) { IsAnyFieldInitialized = true; return false; @@ -204,13 +209,15 @@ llvm::SmallSet VisitedRegions; - // If the static type of the field is a void pointer, we need to cast it back - // to the dynamic type before dereferencing. - bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType()); - SVal V = State->getSVal(FR); assert(V.getAsRegion() && "V must have an underlying region!"); + // If the static type of the field is a void pointer, or it is a + // nonloc::LocAsInteger, we need to cast it back to the dynamic type before + // dereferencing. + const bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType()) || + V.getAs(); + // The region we'd like to acquire. const auto *R = V.getAsRegion()->getAs(); if (!R) Index: test/Analysis/cxx-uninitialized-object-ptr-ref.cpp =================================================================== --- test/Analysis/cxx-uninitialized-object-ptr-ref.cpp +++ test/Analysis/cxx-uninitialized-object-ptr-ref.cpp @@ -22,6 +22,24 @@ } //===----------------------------------------------------------------------===// +// nonloc::LocAsInteger tests. +//===----------------------------------------------------------------------===// + +using intptr_t = long; + +struct LocAsIntegerTest { + intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast(this->ptr)'}} + int dontGetFilteredByNonPedanticMode = 0; + + LocAsIntegerTest(void *ptr) : ptr(reinterpret_cast(ptr)) {} // expected-warning{{1 uninitialized field}} +}; + +void fLocAsIntegerTest() { + char c; + LocAsIntegerTest t(&c); +} + +//===----------------------------------------------------------------------===// // Null pointer tests. //===----------------------------------------------------------------------===//