summaryrefslogtreecommitdiffstats
path: root/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-09-07 19:20:13 +0000
committerAnna Zaks <ganna@apple.com>2012-09-07 19:20:13 +0000
commit258bd59eee5403fc2a98fb23df71fa0281a3ec29 (patch)
tree1959e307fb5d5bb1161326d0abaa9fda4a1eb777 /lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
parentc957319941e93db2bc399efa7a9d1425bc609ba9 (diff)
[analyzer] Fix a false positive in sizeof malloc checker.
Don't warn when the sizeof argument is an array with the same element type as the pointee of the return type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163407 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp82
1 files changed, 49 insertions, 33 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
index 297e4c09e6..404ea1089f 100644
--- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
@@ -184,42 +184,58 @@ public:
continue;
QualType SizeofType = SFinder.Sizeofs[0]->getTypeOfArgument();
- if (!typesCompatible(BR.getContext(), PointeeType, SizeofType)) {
- const TypeSourceInfo *TSI = 0;
- if (i->CastedExprParent.is<const VarDecl *>()) {
- TSI =
+
+ if (typesCompatible(BR.getContext(), PointeeType, SizeofType))
+ continue;
+
+ // If the argument to sizeof is an array, the result could be a
+ // pointer to the array element.
+ if (const ArrayType *AT = dyn_cast<ArrayType>(SizeofType)) {
+ QualType ElemType = AT->getElementType();
+ if (typesCompatible(BR.getContext(), PointeeType,
+ AT->getElementType()))
+ continue;
+
+ // For now, let's only reason about arrays of built in types.
+ if (!ElemType->isBuiltinType())
+ continue;
+ }
+
+
+ const TypeSourceInfo *TSI = 0;
+ if (i->CastedExprParent.is<const VarDecl *>()) {
+ TSI =
i->CastedExprParent.get<const VarDecl *>()->getTypeSourceInfo();
- } else {
- TSI = i->ExplicitCastType;
- }
-
- SmallString<64> buf;
- llvm::raw_svector_ostream OS(buf);
-
- OS << "Result of ";
- const FunctionDecl *Callee = i->AllocCall->getDirectCallee();
- if (Callee && Callee->getIdentifier())
- OS << '\'' << Callee->getIdentifier()->getName() << '\'';
- else
- OS << "call";
- OS << " is converted to a pointer of type '"
- << PointeeType.getAsString() << "', which is incompatible with "
- << "sizeof operand type '" << SizeofType.getAsString() << "'";
- llvm::SmallVector<SourceRange, 4> Ranges;
- Ranges.push_back(i->AllocCall->getCallee()->getSourceRange());
- Ranges.push_back(SFinder.Sizeofs[0]->getSourceRange());
- if (TSI)
- Ranges.push_back(TSI->getTypeLoc().getSourceRange());
-
- PathDiagnosticLocation L =
+ } else {
+ TSI = i->ExplicitCastType;
+ }
+
+ SmallString<64> buf;
+ llvm::raw_svector_ostream OS(buf);
+
+ OS << "Result of ";
+ const FunctionDecl *Callee = i->AllocCall->getDirectCallee();
+ if (Callee && Callee->getIdentifier())
+ OS << '\'' << Callee->getIdentifier()->getName() << '\'';
+ else
+ OS << "call";
+ OS << " is converted to a pointer of type '"
+ << PointeeType.getAsString() << "', which is incompatible with "
+ << "sizeof operand type '" << SizeofType.getAsString() << "'";
+ llvm::SmallVector<SourceRange, 4> Ranges;
+ Ranges.push_back(i->AllocCall->getCallee()->getSourceRange());
+ Ranges.push_back(SFinder.Sizeofs[0]->getSourceRange());
+ if (TSI)
+ Ranges.push_back(TSI->getTypeLoc().getSourceRange());
+
+ PathDiagnosticLocation L =
PathDiagnosticLocation::createBegin(i->AllocCall->getCallee(),
- BR.getSourceManager(), ADC);
+ BR.getSourceManager(), ADC);
- BR.EmitBasicReport(D, "Allocator sizeof operand mismatch",
- categories::UnixAPI,
- OS.str(),
- L, Ranges.data(), Ranges.size());
- }
+ BR.EmitBasicReport(D, "Allocator sizeof operand mismatch",
+ categories::UnixAPI,
+ OS.str(),
+ L, Ranges.data(), Ranges.size());
}
}
}