28 const bool IsDereferenced;
31 LocField(
const FieldRegion *FR,
const bool IsDereferenced =
true)
32 :
FieldNode(FR), IsDereferenced(IsDereferenced) {}
34 void printNoteMsg(llvm::raw_ostream &Out)
const override {
36 Out <<
"uninitialized pointee ";
38 Out <<
"uninitialized pointer ";
41 void printPrefix(llvm::raw_ostream &Out)
const override {}
43 void printNode(llvm::raw_ostream &Out)
const override {
48 if (
getDecl()->getType()->isPointerType())
57class NeedsCastLocField final :
public FieldNode {
64 void printNoteMsg(llvm::raw_ostream &Out)
const override {
65 Out <<
"uninitialized pointee ";
68 void printPrefix(llvm::raw_ostream &Out)
const override {
70 if (
getDecl()->getType()->isIntegerType())
71 Out <<
"reinterpret_cast";
75 Out <<
'<' << CastBackType.getAsString() <<
">(";
78 void printNode(llvm::raw_ostream &Out)
const override {
82 void printSeparator(llvm::raw_ostream &Out)
const override { Out <<
"->"; }
86class CyclicLocField final :
public FieldNode {
91 void printNoteMsg(llvm::raw_ostream &Out)
const override {
92 Out <<
"object references itself ";
95 void printPrefix(llvm::raw_ostream &Out)
const override {}
97 void printNode(llvm::raw_ostream &Out)
const override {
102 llvm_unreachable(
"CyclicLocField objects must be the last node of the "
133bool FindUninitializedFields::isDereferencableUninit(
136 SVal V = State->getSVal(FR);
139 isa<nonloc::LocAsInteger>(
V)) &&
140 "This method only checks dereferenceable objects!");
142 if (
V.isUnknown() || isa<loc::ConcreteInt>(
V)) {
143 IsAnyFieldInitialized =
true;
148 return addFieldToUninits(
149 LocalChain.
add(LocField(FR,
false)), FR);
153 IsAnyFieldInitialized =
true;
159 std::optional<DereferenceInfo> DerefInfo =
dereference(State, FR);
161 IsAnyFieldInitialized =
true;
165 if (DerefInfo->IsCyclic)
166 return addFieldToUninits(LocalChain.
add(CyclicLocField(FR)), FR);
169 const bool NeedsCastBack = DerefInfo->NeedsCastBack;
176 return isNonUnionUninit(R, LocalChain.
add(NeedsCastLocField(FR, DynT)));
177 return isNonUnionUninit(R, LocalChain.
add(LocField(FR)));
181 if (isUnionUninit(R)) {
183 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)),
185 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
187 IsAnyFieldInitialized =
true;
193 IsAnyFieldInitialized =
true;
198 "At this point FR must either have a primitive dynamic type, or it "
199 "must be a null, undefined, unknown or concrete pointer!");
201 SVal PointeeV = State->getSVal(R);
203 if (isPrimitiveUninit(PointeeV)) {
205 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)), R);
206 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
209 IsAnyFieldInitialized =
true;
222 SVal V = State->getSVal(FR);
223 assert(
V.getAsRegion() &&
"V must have an underlying region!");
236 VisitedRegions.insert(R);
241 while (
const MemRegion *Tmp = State->getSVal(R, DynT).getAsRegion()) {
248 if (!VisitedRegions.insert(R).second)
258 while (isa<CXXBaseObjectRegion>(R)) {
259 NeedsCastBack =
true;
260 const auto *SuperR = dyn_cast<TypedValueRegion>(R->
getSuperRegion());
271 while (!
T.isNull()) {
static std::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...
static bool isVoidPointer(QualType T)
Returns whether T can be (transitively) dereferenced to a void pointer type (void*,...
A (possibly-)qualified type.
bool isVoidPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isStructureOrClassType() const
Represents a field chain.
FieldChainInfo add(const FieldNodeT &FN)
Constructs a new FieldChainInfo object with FN appended.
A lightweight polymorphic wrapper around FieldRegion *.
virtual void printSeparator(llvm::raw_ostream &Out) const =0
Print the separator.
virtual void printPrefix(llvm::raw_ostream &Out) const =0
Print any prefixes before the fieldchain. Could contain casts, etc.
virtual void printNoteMsg(llvm::raw_ostream &Out) const =0
If this is the last element of the fieldchain, this method will print the note message associated wit...
const FieldDecl * getDecl() const
virtual void printNode(llvm::raw_ostream &Out) const =0
Print the node. Should contain the name of the field stored in FR.
LLVM_ATTRIBUTE_RETURNS_NONNULL const FieldDecl * getDecl() const override
MemRegion - The root abstract class for all memory regions.
const RegionTy * getAs() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
TypedValueRegion - An abstract class representing regions having a typed value.
QualType getLocationType() const override
std::string getVariableName(const FieldDecl *Field)
Returns with Field's name.
bool isPrimitiveType(const QualType &T)
Returns true if T is a primitive type.
bool isDereferencableType(const QualType &T)
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
DereferenceInfo(const TypedValueRegion *R, bool NCB, bool IC)
const TypedValueRegion * R
bool CheckPointeeInitialization