diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-07 06:33:19 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-07 06:33:19 +0000 |
commit | 19227e32af1f903541214ef24f693688e67c58d6 (patch) | |
tree | 3e26b0036bfe1cf972ea2c4596a7445fc53ad37e | |
parent | 63a4f697a3c6cf4a8b7911830830d2738da7217a (diff) |
Added proof-of-concept NULL pointer diagnostics to GRConstants.
Modified the driver to pass the Diagnostic object to GRConstants.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46847 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Analysis/GRConstants.cpp | 32 | ||||
-rw-r--r-- | Driver/ASTConsumers.cpp | 8 | ||||
-rw-r--r-- | Driver/ASTConsumers.h | 2 | ||||
-rw-r--r-- | Driver/clang.cpp | 2 | ||||
-rw-r--r-- | include/clang/Analysis/Analyses/GRConstants.h | 4 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 6 |
6 files changed, 43 insertions, 11 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 9fc828616a..84b0debb61 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -22,6 +22,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ASTContext.h" #include "clang/Analysis/Analyses/LiveVariables.h" +#include "clang/Basic/Diagnostic.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" @@ -133,8 +134,6 @@ protected: bool StateCleaned; - ASTContext& getContext() const { return G.getContext(); } - public: GRConstants(GraphTy& g) : G(g), Liveness(G.getCFG(), G.getFunctionDecl()), Builder(NULL), @@ -148,6 +147,9 @@ public: Liveness.runOnAllBlocks(G.getCFG(), NULL, true); } + /// getContext - Return the ASTContext associated with this analysis. + ASTContext& getContext() const { return G.getContext(); } + /// getCFG - Returns the CFG associated with this analysis. CFG& getCFG() { return G.getCFG(); } @@ -178,6 +180,9 @@ public: return N->isSink() && ExplicitNullDeref.count(const_cast<NodeTy*>(N)) != 0; } + typedef NullDerefTy::iterator null_iterator; + null_iterator null_begin() { return ExplicitNullDeref.begin(); } + null_iterator null_end() { return ExplicitNullDeref.end(); } /// ProcessStmt - Called by GREngine. Used to generate new successor /// nodes by processing the 'effects' of a block-level statement. @@ -1321,11 +1326,28 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> : #endif namespace clang { -void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx) { +void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx, + Diagnostic& Diag) { + GREngine<GRConstants> Engine(cfg, FD, Ctx); - Engine.ExecuteWorkList(); + Engine.ExecuteWorkList(); + + // Look for explicit-Null dereferences and warn about them. + GRConstants* CheckerState = &Engine.getCheckerState(); + + for (GRConstants::null_iterator I=CheckerState->null_begin(), + E=CheckerState->null_end(); I!=E; ++I) { + + const PostStmt& L = cast<PostStmt>((*I)->getLocation()); + Expr* E = cast<Expr>(L.getStmt()); + + Diag.Report(FullSourceLoc(E->getExprLoc(), Ctx.getSourceManager()), + diag::chkr_null_deref_after_check); + } + + #ifndef NDEBUG - GraphPrintCheckerState = &Engine.getCheckerState(); + GraphPrintCheckerState = CheckerState; llvm::ViewGraph(*Engine.getGraph().roots_begin(),"GRConstants"); GraphPrintCheckerState = NULL; #endif diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index 7b96a6c138..3868e7d75c 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -572,20 +572,22 @@ ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) { namespace { class GRConstantsVisitor : public CFGVisitor { + Diagnostic &Diags; ASTContext* Ctx; public: + GRConstantsVisitor(Diagnostic &diags) : Diags(diags) {} virtual void Initialize(ASTContext &Context) { Ctx = &Context; } virtual void VisitCFG(CFG& C, FunctionDecl&); }; } // end anonymous namespace -ASTConsumer* clang::CreateGRConstants() { - return new GRConstantsVisitor(); +ASTConsumer* clang::CreateGRConstants(Diagnostic &Diags) { + return new GRConstantsVisitor(Diags); } void GRConstantsVisitor::VisitCFG(CFG& C, FunctionDecl& FD) { - RunGRConstants(C, FD, *Ctx); + RunGRConstants(C, FD, *Ctx, Diags); } //===----------------------------------------------------------------------===// diff --git a/Driver/ASTConsumers.h b/Driver/ASTConsumers.h index 10ab1eb83c..28decda9b3 100644 --- a/Driver/ASTConsumers.h +++ b/Driver/ASTConsumers.h @@ -41,7 +41,7 @@ ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags); ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags); -ASTConsumer *CreateGRConstants(); +ASTConsumer *CreateGRConstants(Diagnostic &Diags); ASTConsumer *CreateCodeRewriterTest(const std::string& InFile, Diagnostic &Diags); diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 998ac1ed86..8b3c2f9cf0 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -969,7 +969,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, return CreateUnitValsChecker(Diag); case AnalysisGRConstants: - return CreateGRConstants(); + return CreateGRConstants(Diag); case TestSerialization: return CreateSerializationTest(Diag, FileMgr, LangOpts); diff --git a/include/clang/Analysis/Analyses/GRConstants.h b/include/clang/Analysis/Analyses/GRConstants.h index 3a0385e5f7..afd0535a9a 100644 --- a/include/clang/Analysis/Analyses/GRConstants.h +++ b/include/clang/Analysis/Analyses/GRConstants.h @@ -18,12 +18,14 @@ #define LLVM_CLANG_GRCONSTANTS namespace clang { + class Diagnostic; /// RunGRConstants - This is a simple driver to run the GRConstants analysis /// on a provided CFG. This interface will eventually be replaced with /// something more elaborate as the requirements on the interface become /// clearer. - void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx); + void RunGRConstants(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx, + Diagnostic& Diag); } // end clang namespace diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index b19c485cf2..7e31847e86 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -954,5 +954,11 @@ 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 |