23 using namespace clang;
31 const bool IsDereferenced;
34 LocField(
const FieldRegion *FR,
const bool IsDereferenced =
true)
35 :
FieldNode(FR), IsDereferenced(IsDereferenced) {}
37 virtual void printNoteMsg(llvm::raw_ostream &Out)
const override {
39 Out <<
"uninitialized pointee ";
41 Out <<
"uninitialized pointer ";
44 virtual void printPrefix(llvm::raw_ostream &Out)
const override {}
46 virtual void printNode(llvm::raw_ostream &Out)
const override {
50 virtual void printSeparator(llvm::raw_ostream &Out)
const override {
51 if (getDecl()->getType()->isPointerType())
60 class NeedsCastLocField final :
public FieldNode {
67 virtual void printNoteMsg(llvm::raw_ostream &Out)
const override {
68 Out <<
"uninitialized pointee ";
71 virtual void printPrefix(llvm::raw_ostream &Out)
const override {
73 if (getDecl()->getType()->isIntegerType())
74 Out <<
"reinterpret_cast";
78 Out <<
'<' << CastBackType.getAsString() <<
">(";
81 virtual void printNode(llvm::raw_ostream &Out)
const override {
85 virtual void printSeparator(llvm::raw_ostream &Out)
const override {
91 class CyclicLocField final :
public FieldNode {
96 virtual void printNoteMsg(llvm::raw_ostream &Out)
const override {
97 Out <<
"object references itself ";
100 virtual void printPrefix(llvm::raw_ostream &Out)
const override {}
102 virtual void printNode(llvm::raw_ostream &Out)
const override {
106 virtual void printSeparator(llvm::raw_ostream &Out)
const override {
107 llvm_unreachable(
"CyclicLocField objects must be the last node of the " 121 : R(R), NeedsCastBack(NCB), IsCyclic(IC) {}
138 bool FindUninitializedFields::isDereferencableUninit(
141 SVal V = State->getSVal(FR);
145 "This method only checks dereferenceable objects!");
148 IsAnyFieldInitialized =
true;
153 return addFieldToUninits(
154 LocalChain.
add(LocField(FR,
false)), FR);
157 if (!Opts.CheckPointeeInitialization) {
158 IsAnyFieldInitialized =
true;
166 IsAnyFieldInitialized =
true;
170 if (DerefInfo->IsCyclic)
171 return addFieldToUninits(LocalChain.
add(CyclicLocField(FR)), FR);
174 const bool NeedsCastBack = DerefInfo->NeedsCastBack;
176 QualType DynT = R->getLocationType();
181 return isNonUnionUninit(R, LocalChain.
add(NeedsCastLocField(FR, DynT)));
182 return isNonUnionUninit(R, LocalChain.
add(LocField(FR)));
186 if (isUnionUninit(R)) {
188 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)),
190 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
192 IsAnyFieldInitialized =
true;
198 IsAnyFieldInitialized =
true;
203 "At this point FR must either have a primitive dynamic type, or it " 204 "must be a null, undefined, unknown or concrete pointer!");
206 SVal PointeeV = State->getSVal(R);
208 if (isPrimitiveUninit(PointeeV)) {
210 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)), R);
211 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
214 IsAnyFieldInitialized =
true;
225 llvm::SmallSet<const TypedValueRegion *, 5> VisitedRegions;
227 SVal V = State->getSVal(FR);
228 assert(V.
getAsRegion() &&
"V must have an underlying region!");
241 VisitedRegions.insert(R);
244 QualType DynT = R->getLocationType();
246 while (
const MemRegion *Tmp = State->getSVal(R, DynT).getAsRegion()) {
253 if (!VisitedRegions.insert(R).second)
256 DynT = R->getLocationType();
264 NeedsCastBack =
true;
266 if (!isa<TypedValueRegion>(R->getSuperRegion()))
TypedValueRegion - An abstract class representing regions having a typed value.
A (possibly-)qualified type.
MemRegion - The root abstract class for all memory regions.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
DereferenceInfo(const TypedValueRegion *R, bool NCB, bool IC)
bool isPrimitiveType(const QualType &T)
Returns true if T is a primitive type.
const T * getAs() const
Member-template getAs<specific type>'.
FieldChainInfo add(const FieldNodeT &FN)
Constructs a new FieldChainInfo object with FN appended.
const FieldDecl * getDecl() const
static llvm::Optional< DereferenceInfo > dereference(ProgramStateRef State, const FieldRegion *FR)
Dereferences FR and returns with the pointee's region, and whether it needs to be casted back to it's...
bool isDereferencableType(const QualType &T)
const RegionTy * getAs() const
std::string getVariableName(const FieldDecl *Field)
Returns with Field's name.
const TypedValueRegion * R
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
bool isVoidPointerType() const
static bool isVoidPointer(QualType T)
Returns whether T can be (transitively) dereferenced to a void pointer type (void*, void**, ...).
bool isStructureOrClassType() const
const MemRegion * getAsRegion() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Represents a field chain.
Dataflow Directional Tag Classes.
A lightweight polymorphic wrapper around FieldRegion *.