diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2016-06-13 03:22:41 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2016-06-13 03:22:41 +0000 |
commit | 160f19cddaebb38a93f6528336c57ef20dd529e6 (patch) | |
tree | ea2e080b5881e6cd00d3c6b3808b563f2a71bf50 /clang/lib/StaticAnalyzer/Core | |
parent | 13cf7cac075970c8b7b5c079ff08eccae0ec3563 (diff) | |
download | bcm5719-llvm-160f19cddaebb38a93f6528336c57ef20dd529e6.tar.gz bcm5719-llvm-160f19cddaebb38a93f6528336c57ef20dd529e6.zip |
[analyzer] Add checker to verify the correct usage of the MPI API
This commit adds a static analysis checker to verify the correct usage of the MPI API in C
and C++. This version updates the reverted r271981 to fix a memory corruption found by the
ASan bots.
Three path-sensitive checks are included:
- Double nonblocking: Double request usage by nonblocking calls without intermediate wait
- Missing wait: Nonblocking call without matching wait.
- Unmatched wait: Waiting for a request that was never used by a nonblocking call
Examples of how to use the checker can be found at https://github.com/0ax1/MPI-Checker
A patch by Alexander Droste!
Reviewers: zaks.anna, dcoughlin
Differential Revision: http://reviews.llvm.org/D21081
llvm-svn: 272529
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 083f6c01bc2..b7b6f42b291 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -632,6 +632,65 @@ void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const { superRegion->printPrettyAsExpr(os); } +std::string MemRegion::getDescriptiveName(bool UseQuotes) const { + std::string VariableName; + std::string ArrayIndices; + const MemRegion *R = this; + SmallString<50> buf; + llvm::raw_svector_ostream os(buf); + + // Obtain array indices to add them to the variable name. + const ElementRegion *ER = nullptr; + while ((ER = R->getAs<ElementRegion>())) { + // Index is a ConcreteInt. + if (auto CI = ER->getIndex().getAs<nonloc::ConcreteInt>()) { + llvm::SmallString<2> Idx; + CI->getValue().toString(Idx); + ArrayIndices = (llvm::Twine("[") + Idx.str() + "]" + ArrayIndices).str(); + } + // If not a ConcreteInt, try to obtain the variable + // name by calling 'getDescriptiveName' recursively. + else { + std::string Idx = ER->getDescriptiveName(false); + if (!Idx.empty()) { + ArrayIndices = (llvm::Twine("[") + Idx + "]" + ArrayIndices).str(); + } + } + R = ER->getSuperRegion(); + } + + // Get variable name. + if (R && R->canPrintPrettyAsExpr()) { + R->printPrettyAsExpr(os); + if (UseQuotes) { + return (llvm::Twine("'") + os.str() + ArrayIndices + "'").str(); + } else { + return (llvm::Twine(os.str()) + ArrayIndices).str(); + } + } + + return VariableName; +} + +SourceRange MemRegion::sourceRange() const { + const VarRegion *const VR = dyn_cast<VarRegion>(this->getBaseRegion()); + const FieldRegion *const FR = dyn_cast<FieldRegion>(this); + + // Check for more specific regions first. + // FieldRegion + if (FR) { + return FR->getDecl()->getSourceRange(); + } + // VarRegion + else if (VR) { + return VR->getDecl()->getSourceRange(); + } + // Return invalid source range (can be checked by client). + else { + return SourceRange{}; + } +} + //===----------------------------------------------------------------------===// // MemRegionManager methods. //===----------------------------------------------------------------------===// |