summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/UninitializedObject
diff options
context:
space:
mode:
authorKristof Umann <dkszelethus@gmail.com>2018-10-11 11:58:53 +0000
committerKristof Umann <dkszelethus@gmail.com>2018-10-11 11:58:53 +0000
commit8e5328b6f070e3ec2dfadfa99dc34f26f569e528 (patch)
tree534aa5ef7b69e38d24f33b5f158281c6c280435a /clang/lib/StaticAnalyzer/Checkers/UninitializedObject
parentcdd23f221d84123272f380151e09358376541405 (diff)
downloadbcm5719-llvm-8e5328b6f070e3ec2dfadfa99dc34f26f569e528.tar.gz
bcm5719-llvm-8e5328b6f070e3ec2dfadfa99dc34f26f569e528.zip
[analyzer][UninitializedObjectChecker] Reports Loc fields pointing to themselves
I've added a new functionality, the checker is now able to detect and report fields pointing to themselves. I figured this would fit well into the checker as there's no reason for a pointer to point to itself instead of being nullptr. Differential Revision: https://reviews.llvm.org/D51305 llvm-svn: 344242
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/UninitializedObject')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp68
1 files changed, 49 insertions, 19 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
index 623ba6b3ff6..c99dac5adfc 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
@@ -89,15 +89,39 @@ public:
}
};
+/// Represents a Loc field that points to itself.
+class CyclicLocField final : public FieldNode {
+
+public:
+ CyclicLocField(const FieldRegion *FR) : FieldNode(FR) {}
+
+ virtual void printNoteMsg(llvm::raw_ostream &Out) const override {
+ Out << "object references itself ";
+ }
+
+ virtual void printPrefix(llvm::raw_ostream &Out) const override {}
+
+ virtual void printNode(llvm::raw_ostream &Out) const override {
+ Out << getVariableName(getDecl());
+ }
+
+ virtual void printSeparator(llvm::raw_ostream &Out) const override {
+ llvm_unreachable("CyclicLocField objects must be the last node of the "
+ "fieldchain!");
+ }
+};
+
} // end of anonymous namespace
// Utility function declarations.
-/// Returns whether \p T can be (transitively) dereferenced to a void pointer
-/// type (void*, void**, ...).
-static bool isVoidPointer(QualType T);
-
-using DereferenceInfo = std::pair<const TypedValueRegion *, bool>;
+struct DereferenceInfo {
+ const TypedValueRegion *R;
+ const bool NeedsCastBack;
+ const bool IsCyclic;
+ DereferenceInfo(const TypedValueRegion *R, bool NCB, bool IC)
+ : R(R), NeedsCastBack(NCB), IsCyclic(IC) {}
+};
/// Dereferences \p FR and returns with the pointee's region, and whether it
/// needs to be casted back to it's location type. If for whatever reason
@@ -105,6 +129,10 @@ using DereferenceInfo = std::pair<const TypedValueRegion *, bool>;
static llvm::Optional<DereferenceInfo> dereference(ProgramStateRef State,
const FieldRegion *FR);
+/// Returns whether \p T can be (transitively) dereferenced to a void pointer
+/// type (void*, void**, ...).
+static bool isVoidPointer(QualType T);
+
//===----------------------------------------------------------------------===//
// Methods for FindUninitializedFields.
//===----------------------------------------------------------------------===//
@@ -141,8 +169,11 @@ bool FindUninitializedFields::isDereferencableUninit(
return false;
}
- const TypedValueRegion *R = DerefInfo->first;
- const bool NeedsCastBack = DerefInfo->second;
+ if (DerefInfo->IsCyclic)
+ return addFieldToUninits(LocalChain.add(CyclicLocField(FR)));
+
+ const TypedValueRegion *R = DerefInfo->R;
+ const bool NeedsCastBack = DerefInfo->NeedsCastBack;
QualType DynT = R->getLocationType();
QualType PointeeT = DynT->getPointeeType();
@@ -189,15 +220,6 @@ bool FindUninitializedFields::isDereferencableUninit(
// Utility functions.
//===----------------------------------------------------------------------===//
-static bool isVoidPointer(QualType T) {
- while (!T.isNull()) {
- if (T->isVoidPointerType())
- return true;
- T = T->getPointeeType();
- }
- return false;
-}
-
static llvm::Optional<DereferenceInfo> dereference(ProgramStateRef State,
const FieldRegion *FR) {
@@ -229,9 +251,8 @@ static llvm::Optional<DereferenceInfo> dereference(ProgramStateRef State,
return None;
// We found a cyclic pointer, like int *ptr = (int *)&ptr.
- // TODO: Should we report these fields too?
if (!VisitedRegions.insert(R).second)
- return None;
+ return DereferenceInfo{R, NeedsCastBack, /*IsCyclic*/ true};
DynT = R->getLocationType();
// In order to ensure that this loop terminates, we're also checking the
@@ -248,5 +269,14 @@ static llvm::Optional<DereferenceInfo> dereference(ProgramStateRef State,
R = R->getSuperRegion()->getAs<TypedValueRegion>();
}
- return std::make_pair(R, NeedsCastBack);
+ return DereferenceInfo{R, NeedsCastBack, /*IsCyclic*/ false};
+}
+
+static bool isVoidPointer(QualType T) {
+ while (!T.isNull()) {
+ if (T->isVoidPointerType())
+ return true;
+ T = T->getPointeeType();
+ }
+ return false;
}
OpenPOWER on IntegriCloud