32 const bool IsDereferenced;
35 LocField(
const FieldRegion *FR,
const bool IsDereferenced =
true)
36 :
FieldNode(FR), IsDereferenced(IsDereferenced) {}
38 void printNoteMsg(llvm::raw_ostream &Out)
const override {
40 Out <<
"uninitialized pointee ";
42 Out <<
"uninitialized pointer ";
45 void printPrefix(llvm::raw_ostream &Out)
const override {}
47 void printNode(llvm::raw_ostream &Out)
const override {
52 if (
getDecl()->getType()->isPointerType())
61class NeedsCastLocField final :
public FieldNode {
68 void printNoteMsg(llvm::raw_ostream &Out)
const override {
69 Out <<
"uninitialized pointee ";
72 void printPrefix(llvm::raw_ostream &Out)
const override {
74 if (
getDecl()->getType()->isIntegerType())
75 Out <<
"reinterpret_cast";
79 Out <<
'<' << CastBackType.getAsString() <<
">(";
82 void printNode(llvm::raw_ostream &Out)
const override {
86 void printSeparator(llvm::raw_ostream &Out)
const override { Out <<
"->"; }
90class CyclicLocField final :
public FieldNode {
95 void printNoteMsg(llvm::raw_ostream &Out)
const override {
96 Out <<
"object references itself ";
99 void printPrefix(llvm::raw_ostream &Out)
const override {}
101 void printNode(llvm::raw_ostream &Out)
const override {
106 llvm_unreachable(
"CyclicLocField objects must be the last node of the "
137bool FindUninitializedFields::isDereferencableUninit(
140 SVal V = State->getSVal(FR);
143 isa<nonloc::LocAsInteger>(
V)) &&
144 "This method only checks dereferenceable objects!");
146 if (
V.isUnknown() || isa<loc::ConcreteInt>(
V)) {
147 IsAnyFieldInitialized =
true;
152 return addFieldToUninits(
153 LocalChain.
add(LocField(FR,
false)), FR);
157 IsAnyFieldInitialized =
true;
163 std::optional<DereferenceInfo> DerefInfo =
dereference(State, FR);
165 IsAnyFieldInitialized =
true;
169 if (DerefInfo->IsCyclic)
170 return addFieldToUninits(LocalChain.
add(CyclicLocField(FR)), FR);
173 const bool NeedsCastBack = DerefInfo->NeedsCastBack;
180 return isNonUnionUninit(R, LocalChain.
add(NeedsCastLocField(FR, DynT)));
181 return isNonUnionUninit(R, LocalChain.
add(LocField(FR)));
185 if (isUnionUninit(R)) {
187 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)),
189 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
191 IsAnyFieldInitialized =
true;
197 IsAnyFieldInitialized =
true;
202 "At this point FR must either have a primitive dynamic type, or it "
203 "must be a null, undefined, unknown or concrete pointer!");
205 SVal PointeeV = State->getSVal(R);
207 if (isPrimitiveUninit(PointeeV)) {
209 return addFieldToUninits(LocalChain.
add(NeedsCastLocField(FR, DynT)), R);
210 return addFieldToUninits(LocalChain.
add(LocField(FR)), R);
213 IsAnyFieldInitialized =
true;
224 llvm::SmallSet<const TypedValueRegion *, 5> VisitedRegions;
226 SVal V = State->getSVal(FR);
227 assert(
V.getAsRegion() &&
"V must have an underlying region!");
240 VisitedRegions.insert(R);
245 while (
const MemRegion *Tmp = State->getSVal(R, DynT).getAsRegion()) {
252 if (!VisitedRegions.insert(R).second)
262 while (isa<CXXBaseObjectRegion>(R)) {
263 NeedsCastBack =
true;
264 const auto *SuperR = dyn_cast<TypedValueRegion>(R->
getSuperRegion());
275 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