aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-02-26 21:31:18 +0000
committerTed Kremenek <kremenek@apple.com>2008-02-26 21:31:18 +0000
commitd87a321a3c3902f7acfc6539b8946a00da6e45cc (patch)
treed35d451e1427e9b4c082a338d678bbaaaa7daf87
parentebd6610f9b92342b79401cab324bb8c28b0dfa69 (diff)
Removed static analysis-specific diagnostics from DiagnosticKinds.def.
Use custom diagnostics for static analysis checkers. Added warnings for dereferencing uninitialized values and divide-by-zeroes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47626 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Analysis/GRExprEngine.cpp6
-rw-r--r--Analysis/GRSimpleVals.cpp54
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h18
-rw-r--r--include/clang/Basic/DiagnosticKinds.def7
4 files changed, 61 insertions, 24 deletions
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 1dae433e8f..0630fc5fb0 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -1545,7 +1545,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
GraphPrintCheckerState->isExplicitNullDeref(N) ||
GraphPrintCheckerState->isUninitDeref(N) ||
GraphPrintCheckerState->isUninitStore(N) ||
- GraphPrintCheckerState->isUninitControlFlow(N))
+ GraphPrintCheckerState->isUninitControlFlow(N) ||
+ GraphPrintCheckerState->isBadDivide(N))
return "color=\"red\",style=\"filled\"";
return "";
@@ -1586,6 +1587,9 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
else if (GraphPrintCheckerState->isUninitStore(N)) {
Out << "\\|Store to Uninitialized LVal.";
}
+ else if (GraphPrintCheckerState->isBadDivide(N)) {
+ Out << "\\|Divide-by zero or uninitialized value.";
+ }
break;
}
diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp
index 04a13e3703..549aa0bb4f 100644
--- a/Analysis/GRSimpleVals.cpp
+++ b/Analysis/GRSimpleVals.cpp
@@ -19,6 +19,27 @@
using namespace clang;
namespace clang {
+
+template <typename ITERATOR>
+static void EmitWarning(Diagnostic& Diag, SourceManager& SrcMgr,
+ ITERATOR I, ITERATOR E, const char* msg) {
+
+ bool isFirst;
+ unsigned ErrorDiag;
+
+ for (; I != E; ++I) {
+
+ if (isFirst) {
+ isFirst = false;
+ ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg);
+ }
+
+ const PostStmt& L = cast<PostStmt>((*I)->getLocation());
+ Expr* Exp = cast<Expr>(L.getStmt());
+
+ Diag.Report(FullSourceLoc(Exp->getExprLoc(), SrcMgr), ErrorDiag);
+ }
+}
unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
Diagnostic& Diag, bool Visualize) {
@@ -32,18 +53,29 @@ unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
CheckerState->setTransferFunctions(GRSV);
// Execute the worklist algorithm.
- Engine.ExecuteWorkList(10000);
+ Engine.ExecuteWorkList(20000);
- // Look for explicit-Null dereferences and warn about them.
- for (GRExprEngine::null_iterator I=CheckerState->null_begin(),
- E=CheckerState->null_end(); I!=E; ++I) {
-
- const PostStmt& L = cast<PostStmt>((*I)->getLocation());
- Expr* Exp = cast<Expr>(L.getStmt());
-
- Diag.Report(FullSourceLoc(Exp->getExprLoc(), Ctx.getSourceManager()),
- diag::chkr_null_deref_after_check);
- }
+ SourceManager& SrcMgr = Ctx.getSourceManager();
+
+ EmitWarning(Diag, SrcMgr,
+ CheckerState->null_derefs_begin(),
+ CheckerState->null_derefs_end(),
+ "NULL pointer is dereferenced after it is checked for NULL.");
+
+ EmitWarning(Diag, SrcMgr,
+ CheckerState->uninit_derefs_begin(),
+ CheckerState->uninit_derefs_end(),
+ "Dereference of uninitialized value.");
+
+ EmitWarning(Diag, SrcMgr,
+ CheckerState->uninit_derefs_begin(),
+ CheckerState->uninit_derefs_end(),
+ "Dereference of uninitialized value.");
+
+ EmitWarning(Diag, SrcMgr,
+ CheckerState->bad_divides_begin(),
+ CheckerState->bad_divides_end(),
+ "Division by zero/uninitialized value.");
#ifndef NDEBUG
if (Visualize) CheckerState->ViewGraph();
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index 08d2495196..a5f88354b8 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -117,7 +117,7 @@ protected:
typedef llvm::SmallPtrSet<NodeTy*,5> UninitStoresTy;
typedef llvm::SmallPtrSet<NodeTy*,5> BadDerefTy;
- typedef llvm::SmallPtrSet<NodeTy*,5> DivZerosTy;
+ typedef llvm::SmallPtrSet<NodeTy*,5> BadDividesTy;
/// UninitStores - Sinks in the ExplodedGraph that result from
/// making a store to an uninitialized lvalue.
@@ -137,7 +137,7 @@ protected:
/// BadDivides - Nodes in the ExplodedGraph that result from evaluating
/// a divide-by-zero or divide-by-uninitialized.
- DivZerosTy BadDivides;
+ BadDividesTy BadDivides;
bool StateCleaned;
@@ -198,9 +198,17 @@ public:
return N->isSink() && BadDivides.count(const_cast<NodeTy*>(N)) != 0;
}
- typedef BadDerefTy::iterator null_iterator;
- null_iterator null_begin() { return ExplicitNullDeref.begin(); }
- null_iterator null_end() { return ExplicitNullDeref.end(); }
+ typedef BadDerefTy::iterator null_deref_iterator;
+ null_deref_iterator null_derefs_begin() { return ExplicitNullDeref.begin(); }
+ null_deref_iterator null_derefs_end() { return ExplicitNullDeref.end(); }
+
+ typedef BadDerefTy::iterator uninit_deref_iterator;
+ uninit_deref_iterator uninit_derefs_begin() { return UninitDeref.begin(); }
+ uninit_deref_iterator uninit_derefs_end() { return UninitDeref.end(); }
+
+ typedef BadDividesTy::iterator bad_divide_iterator;
+ bad_divide_iterator bad_divides_begin() { return BadDivides.begin(); }
+ bad_divide_iterator bad_divides_end() { return BadDivides.end(); }
/// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement.
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index 902ecc217e..21f348216d 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -966,11 +966,4 @@ DIAG(ext_return_missing_expr, EXTENSION,
DIAG(ext_return_has_expr, EXTENSION,
"void function '%0' should not return a value")
-//===----------------------------------------------------------------------===//
-// Static Analysis Warnings (Bug-Finding)
-//===----------------------------------------------------------------------===//
-
-DIAG(chkr_null_deref_after_check, ERROR,
- "NULL pointer is dereferenced after it is checked for NULL.")
-
#undef DIAG