aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp60
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,