diff options
author | Anna Zaks <ganna@apple.com> | 2012-09-07 19:20:13 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-09-07 19:20:13 +0000 |
commit | 258bd59eee5403fc2a98fb23df71fa0281a3ec29 (patch) | |
tree | 1959e307fb5d5bb1161326d0abaa9fda4a1eb777 /lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp | |
parent | c957319941e93db2bc399efa7a9d1425bc609ba9 (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.cpp | 82 |
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()); } } } |