summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
diff options
context:
space:
mode:
authorKristof Umann <dkszelethus@gmail.com>2018-08-14 08:20:51 +0000
committerKristof Umann <dkszelethus@gmail.com>2018-08-14 08:20:51 +0000
commit5a42441d8192827bcf12fea1dd04f7c0f599b114 (patch)
tree190c5cd0fb07d8edc9073e88c699b041f165fa4b /clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
parent5d94b25ffedbdc036ba467ece1695627b1210a8d (diff)
downloadbcm5719-llvm-5a42441d8192827bcf12fea1dd04f7c0f599b114.tar.gz
bcm5719-llvm-5a42441d8192827bcf12fea1dd04f7c0f599b114.zip
[analyzer][UninitializedObjectChecker] Void pointers are casted back to their dynamic type in note message
Differential Revision: https://reviews.llvm.org/D49228 llvm-svn: 339653
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp42
1 files changed, 40 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
index 6c83b2e146d..c855f97de2c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
@@ -60,6 +60,32 @@ public:
}
};
+/// Represents a void* field that needs to be casted back to its dynamic type
+/// for a correct note message.
+class NeedsCastLocField final : public FieldNode {
+ QualType CastBackType;
+
+public:
+ NeedsCastLocField(const FieldRegion *FR, const QualType &T)
+ : FieldNode(FR), CastBackType(T) {}
+
+ virtual void printNoteMsg(llvm::raw_ostream &Out) const override {
+ Out << "uninitialized pointee ";
+ }
+
+ virtual void printPrefix(llvm::raw_ostream &Out) const override {
+ Out << "static_cast" << '<' << CastBackType.getAsString() << ">(";
+ }
+
+ virtual void printNode(llvm::raw_ostream &Out) const override {
+ Out << getVariableName(getDecl()) << ')';
+ }
+
+ virtual void printSeparator(llvm::raw_ostream &Out) const override {
+ Out << "->";
+ }
+};
+
} // end of anonymous namespace
// Utility function declarations.
@@ -122,6 +148,10 @@ bool FindUninitializedFields::isPointerOrReferenceUninit(
QualType DynT = DynTInfo.getType();
+ // If the static type of the field is a void pointer, we need to cast it back
+ // to the dynamic type before dereferencing.
+ bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType());
+
if (isVoidPointer(DynT)) {
IsAnyFieldInitialized = true;
return false;
@@ -160,11 +190,16 @@ bool FindUninitializedFields::isPointerOrReferenceUninit(
const TypedValueRegion *R = RecordV->getRegion();
- if (DynT->getPointeeType()->isStructureOrClassType())
+ if (DynT->getPointeeType()->isStructureOrClassType()) {
+ if (NeedsCastBack)
+ return isNonUnionUninit(R, LocalChain.add(NeedsCastLocField(FR, DynT)));
return isNonUnionUninit(R, LocalChain.add(LocField(FR)));
+ }
if (DynT->getPointeeType()->isUnionType()) {
if (isUnionUninit(R)) {
+ if (NeedsCastBack)
+ return addFieldToUninits(LocalChain.add(NeedsCastLocField(FR, DynT)));
return addFieldToUninits(LocalChain.add(LocField(FR)));
} else {
IsAnyFieldInitialized = true;
@@ -185,8 +220,11 @@ bool FindUninitializedFields::isPointerOrReferenceUninit(
"At this point FR must either have a primitive dynamic type, or it "
"must be a null, undefined, unknown or concrete pointer!");
- if (isPrimitiveUninit(DerefdV))
+ if (isPrimitiveUninit(DerefdV)) {
+ if (NeedsCastBack)
+ return addFieldToUninits(LocalChain.add(NeedsCastLocField(FR, DynT)));
return addFieldToUninits(LocalChain.add(LocField(FR)));
+ }
IsAnyFieldInitialized = true;
return false;
OpenPOWER on IntegriCloud