forked from OSchip/llvm-project
[analyzer][UninitializedObjectChecker] Support for nonloc::LocAsInteger
Differential Revision: https://reviews.llvm.org/D49437 llvm-svn: 342221
This commit is contained in:
parent
d6145d9849
commit
f051379fbc
|
@ -274,15 +274,15 @@ bool FindUninitializedFields::isNonUnionUninit(const TypedValueRegion *R,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isDereferencableType(T)) {
|
||||
SVal V = State->getSVal(FieldVal);
|
||||
|
||||
if (isDereferencableType(T) || V.getAs<nonloc::LocAsInteger>()) {
|
||||
if (isDereferencableUninit(FR, LocalChain))
|
||||
ContainsUninitField = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isPrimitiveType(T)) {
|
||||
SVal V = State->getSVal(FieldVal);
|
||||
|
||||
if (isPrimitiveUninit(V)) {
|
||||
if (addFieldToUninits(LocalChain.add(RegularField(FR))))
|
||||
ContainsUninitField = true;
|
||||
|
|
|
@ -57,9 +57,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// 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:
|
||||
|
@ -71,7 +71,13 @@ public:
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -106,11 +112,12 @@ static llvm::Optional<DereferenceInfo> dereference(ProgramStateRef State,
|
|||
bool FindUninitializedFields::isDereferencableUninit(
|
||||
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<nonloc::LocAsInteger>()) &&
|
||||
"This method only checks dereferencable objects!");
|
||||
|
||||
if (V.isUnknown() || V.getAs<loc::ConcreteInt>()) {
|
||||
IsAnyFieldInitialized = true;
|
||||
return false;
|
||||
|
@ -196,13 +203,15 @@ static llvm::Optional<DereferenceInfo> dereference(ProgramStateRef State,
|
|||
|
||||
llvm::SmallSet<const TypedValueRegion *, 5> 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.
|
||||
bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType()) ||
|
||||
V.getAs<nonloc::LocAsInteger>();
|
||||
|
||||
// The region we'd like to acquire.
|
||||
const auto *R = V.getAsRegion()->getAs<TypedValueRegion>();
|
||||
if (!R)
|
||||
|
|
|
@ -21,6 +21,24 @@ void fConcreteIntLocTest() {
|
|||
ConcreteIntLocTest();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// nonloc::LocAsInteger tests.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
using intptr_t = long;
|
||||
|
||||
struct LocAsIntegerTest {
|
||||
intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast<char *>(this->ptr)'}}
|
||||
int dontGetFilteredByNonPedanticMode = 0;
|
||||
|
||||
LocAsIntegerTest(void *ptr) : ptr(reinterpret_cast<intptr_t>(ptr)) {} // expected-warning{{1 uninitialized field}}
|
||||
};
|
||||
|
||||
void fLocAsIntegerTest() {
|
||||
char c;
|
||||
LocAsIntegerTest t(&c);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Null pointer tests.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue