summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp37
1 files changed, 12 insertions, 25 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
index 84c18869d74..970f8724e96 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
@@ -94,7 +94,9 @@ public:
};
/// Represents that the FieldNode that comes after this is declared in a base
-/// of the previous FieldNode.
+/// of the previous FieldNode. As such, this descendant doesn't wrap a
+/// FieldRegion, and is purely a tool to describe a relation between two other
+/// FieldRegion wrapping descendants.
class BaseClass final : public FieldNode {
const QualType BaseClassT;
@@ -296,7 +298,7 @@ bool FindUninitializedFields::isNonUnionUninit(const TypedValueRegion *R,
}
if (isDereferencableType(T)) {
- if (isPointerOrReferenceUninit(FR, LocalChain))
+ if (isDereferencableUninit(FR, LocalChain))
ContainsUninitField = true;
continue;
}
@@ -314,7 +316,8 @@ bool FindUninitializedFields::isNonUnionUninit(const TypedValueRegion *R,
llvm_unreachable("All cases are handled!");
}
- // Checking bases.
+ // Checking bases. The checker will regard inherited data members as direct
+ // fields.
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
if (!CXXRD)
return ContainsUninitField;
@@ -361,6 +364,9 @@ bool FindUninitializedFields::isPrimitiveUninit(const SVal &V) {
const FieldRegion *FieldChainInfo::getUninitRegion() const {
assert(!Chain.isEmpty() && "Empty fieldchain!");
+
+ // ImmutableList::getHead() isn't a const method, hence the not too nice
+ // implementation.
return (*Chain.begin()).getRegion();
}
@@ -375,31 +381,11 @@ bool FieldChainInfo::contains(const FieldRegion *FR) const {
/// Prints every element except the last to `Out`. Since ImmutableLists store
/// elements in reverse order, and have no reverse iterators, we use a
/// recursive function to print the fieldchain correctly. The last element in
-/// the chain is to be printed by `print`.
+/// the chain is to be printed by `FieldChainInfo::print`.
static void printTail(llvm::raw_ostream &Out,
const FieldChainInfo::FieldChainImpl *L);
-// TODO: This function constructs an incorrect string if a void pointer is a
-// part of the chain:
-//
-// struct B { int x; }
-//
-// struct A {
-// void *vptr;
-// A(void* vptr) : vptr(vptr) {}
-// };
-//
-// void f() {
-// B b;
-// A a(&b);
-// }
-//
-// The note message will be "uninitialized field 'this->vptr->x'", even though
-// void pointers can't be dereferenced. This should be changed to "uninitialized
-// field 'static_cast<B*>(this->vptr)->x'".
-//
-// TODO: This function constructs an incorrect fieldchain string in the
-// following case:
+// FIXME: This function constructs an incorrect string in the following case:
//
// struct Base { int x; };
// struct D1 : Base {}; struct D2 : Base {};
@@ -515,6 +501,7 @@ std::string clang::ento::getVariableName(const FieldDecl *Field) {
void ento::registerUninitializedObjectChecker(CheckerManager &Mgr) {
auto Chk = Mgr.registerChecker<UninitializedObjectChecker>();
+
Chk->IsPedantic = Mgr.getAnalyzerOptions().getBooleanOption(
"Pedantic", /*DefaultVal*/ false, Chk);
Chk->ShouldConvertNotesToWarnings = Mgr.getAnalyzerOptions().getBooleanOption(
OpenPOWER on IntegriCloud