24 using namespace clang;
32 const bool IsDereferenced;
35 LocField(
const FieldRegion *FR,
const bool IsDereferenced =
true)
36 :
FieldNode(FR), IsDereferenced(IsDereferenced) {}
38 virtual void printNoteMsg(llvm::raw_ostream &Out)
const override {
40 Out <<
"uninitialized pointee ";
42 Out <<
"uninitialized pointer ";
45 virtual void printPrefix(llvm::raw_ostream &Out)
const override {}
47 virtual void printNode(llvm::raw_ostream &Out)
const override {
51 virtual void printSeparator(llvm::raw_ostream &Out)
const override {
52 if (getDecl()->getType()->isPointerType())
61 class NeedsCastLocField final :
public FieldNode {
68 virtual void printNoteMsg(llvm::raw_ostream &Out)
const override {
69 Out <<
"uninitialized pointee ";
72 virtual void printPrefix(llvm::raw_ostream &Out)
const override {
74 if (getDecl()->getType()->isIntegerType())
75 Out <<
"reinterpret_cast";
79 Out <<
'<' << CastBackType.getAsString() <<
">(";
82 virtual void printNode(llvm::raw_ostream &Out)
const override {
86 virtual void printSeparator(llvm::raw_ostream &Out)
const override {
92 class CyclicLocField final :
public FieldNode {
97 virtual void printNoteMsg(llvm::raw_ostream &Out)
const override {
98 Out <<
"object references itself ";
101 virtual void printPrefix(llvm::raw_ostream &Out)
const override {}
103 virtual void printNode(llvm::raw_ostream &Out)
const override {
107 virtual void printSeparator(llvm::raw_ostream &Out)
const override {
108 llvm_unreachable(
"CyclicLocField objects must be the last node of the " 122 : R(R), NeedsCastBack(NCB), IsCyclic(IC) {}
139 bool FindUninitializedFields::isDereferencableUninit(
142 SVal V = State->getSVal(FR);
146 "This method only checks dereferenceable objects!");
149 IsAnyFieldInitialized =
true;
154 return addFieldToUninits(
155 LocalChain.
add(LocField(FR,
false)), FR);
158 if (!Opts.CheckPointeeInitialization) {
159 IsAnyFieldInitialized =
true;
167 IsAnyFieldInitialized =
true;
171 if (DerefInfo->IsCyclic)
172 return addFieldToUninits(LocalChain.
add(CyclicLocField(FR)), FR);
175 const bool NeedsCastBack = DerefInfo->NeedsCastBack;
177 QualType DynT = R->getLocationType();
182 return isNonUnionUninit(R, LocalChain.
add(NeedsCastLocField(FR, DynT)));
183 return isNonUnionUninit(R, LocalChain.
add(LocField(FR)));
187 if (isUnionUninit(R)) {
189 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)),
191 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
193 IsAnyFieldInitialized =
true;
199 IsAnyFieldInitialized =
true;
204 "At this point FR must either have a primitive dynamic type, or it " 205 "must be a null, undefined, unknown or concrete pointer!");
207 SVal PointeeV = State->getSVal(R);
209 if (isPrimitiveUninit(PointeeV)) {
211 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)), R);
212 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
215 IsAnyFieldInitialized =
true;
226 llvm::SmallSet<const TypedValueRegion *, 5> VisitedRegions;
228 SVal V = State->getSVal(FR);
229 assert(V.
getAsRegion() &&
"V must have an underlying region!");
242 VisitedRegions.insert(R);
245 QualType DynT = R->getLocationType();
247 while (
const MemRegion *Tmp = State->getSVal(R, DynT).getAsRegion()) {
254 if (!VisitedRegions.insert(R).second)
257 DynT = R->getLocationType();
265 NeedsCastBack =
true;
267 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 *.