diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp index 1c33648b2b32..ec1b0a70d7d3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp @@ -40,6 +40,7 @@ class ExprInspectionChecker void analyzerNumTimesReached(const CallExpr *CE, CheckerContext &C) const; void analyzerCrash(const CallExpr *CE, CheckerContext &C) const; void analyzerWarnOnDeadSymbol(const CallExpr *CE, CheckerContext &C) const; + void analyzerValue(const CallExpr *CE, CheckerContext &C) const; void analyzerDumpSValType(const CallExpr *CE, CheckerContext &C) const; void analyzerDump(const CallExpr *CE, CheckerContext &C) const; void analyzerExplain(const CallExpr *CE, CheckerContext &C) const; @@ -60,6 +61,7 @@ class ExprInspectionChecker Optional<SVal> ExprVal = None) const; ExplodedNode *reportBug(llvm::StringRef Msg, BugReporter &BR, ExplodedNode *N, Optional<SVal> ExprVal = None) const; + template <typename T> void printAndReport(CheckerContext &C, T What) const; const Expr *getArgExpr(const CallExpr *CE, CheckerContext &C) const; const MemRegion *getArgRegion(const CallExpr *CE, CheckerContext &C) const; @@ -99,6 +101,7 @@ bool ExprInspectionChecker::evalCall(const CallEvent &Call, &ExprInspectionChecker::analyzerDumpExtent) .Case("clang_analyzer_dumpElementCount", &ExprInspectionChecker::analyzerDumpElementCount) + .Case("clang_analyzer_value", &ExprInspectionChecker::analyzerValue) .StartsWith("clang_analyzer_dumpSvalType", &ExprInspectionChecker::analyzerDumpSValType) .StartsWith("clang_analyzer_dump", @@ -258,6 +261,45 @@ void ExprInspectionChecker::analyzerExplain(const CallExpr *CE, reportBug(Ex.Visit(V), C); } +static void printHelper(llvm::raw_svector_ostream &Out, CheckerContext &C, + const llvm::APSInt &I) { + Out << I.getBitWidth() << (I.isUnsigned() ? "u:" : "s:"); + Out << I; +} + +static void printHelper(llvm::raw_svector_ostream &Out, CheckerContext &C, + SymbolRef Sym) { + C.getConstraintManager().printValue(Out, C.getState(), Sym); +} + +static void printHelper(llvm::raw_svector_ostream &Out, CheckerContext &C, + SVal V) { + Out << V; +} + +template <typename T> +void ExprInspectionChecker::printAndReport(CheckerContext &C, T What) const { + llvm::SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + printHelper(OS, C, What); + reportBug(OS.str(), C); +} + +void ExprInspectionChecker::analyzerValue(const CallExpr *CE, + CheckerContext &C) const { + const Expr *Arg = getArgExpr(CE, C); + if (!Arg) + return; + + SVal V = C.getSVal(Arg); + if (const SymbolRef Sym = V.getAsSymbol()) + printAndReport(C, Sym); + else if (const llvm::APSInt *I = V.getAsInteger()) + printAndReport(C, *I); + else + reportBug("n/a", C); +} + void ExprInspectionChecker::analyzerDumpSValType(const CallExpr *CE, CheckerContext &C) const { const Expr *Arg = getArgExpr(CE, C); @@ -275,11 +317,7 @@ void ExprInspectionChecker::analyzerDump(const CallExpr *CE, return; SVal V = C.getSVal(Arg); - - llvm::SmallString<32> Str; - llvm::raw_svector_ostream OS(Str); - V.dumpToStream(OS); - reportBug(OS.str(), C); + printAndReport(C, V); } void ExprInspectionChecker::analyzerGetExtent(const CallExpr *CE, @@ -303,11 +341,7 @@ void ExprInspectionChecker::analyzerDumpExtent(const CallExpr *CE, DefinedOrUnknownSVal Size = getDynamicExtent(C.getState(), MR, C.getSValBuilder()); - - SmallString<64> Msg; - llvm::raw_svector_ostream Out(Msg); - Out << Size; - reportBug(Out.str(), C); + printAndReport(C, Size); } void ExprInspectionChecker::analyzerDumpElementCount(const CallExpr *CE, @@ -328,11 +362,7 @@ void ExprInspectionChecker::analyzerDumpElementCount(const CallExpr *CE, DefinedOrUnknownSVal ElementCount = getDynamicElementCount(C.getState(), MR, C.getSValBuilder(), ElementTy); - - SmallString<128> Msg; - llvm::raw_svector_ostream Out(Msg); - Out << ElementCount; - reportBug(Out.str(), C); + printAndReport(C, ElementCount); } void ExprInspectionChecker::analyzerPrintState(const CallExpr *CE, |
