Added "Dead Stores", a flow-sensitive checker that checks for stores
to variables that are no longer live. This analysis is built on top
of CFGs and the LiveVariables analysis.
changes to driver:
added driver option "-check-dead-stores" to run the analysis
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41754 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/ASTStreamers.cpp b/Driver/ASTStreamers.cpp
index b5ea293..95d39fa 100644
--- a/Driver/ASTStreamers.cpp
+++ b/Driver/ASTStreamers.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/AST.h"
#include "clang/AST/CFG.h"
#include "clang/Analysis/LiveVariables.h"
+#include "clang/Analysis/LocalCheckers.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/ASTStreamer.h"
using namespace clang;
@@ -209,4 +210,30 @@
ASTStreamer_Terminate(Streamer);
}
+void clang::RunDeadStoresCheck(Preprocessor &PP, unsigned MainFileID,bool Stats)
+{
+ ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
+ ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
+
+ while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->getBody()) {
+ if (CFG* C = CFG::buildCFG(FD->getBody())) {
+ clang::CheckDeadStores(*C,PP);
+ }
+ else
+ fprintf(stderr," Error processing CFG.\n");
+ }
+ }
+ }
+
+ if (Stats) {
+ fprintf(stderr, "\nSTATISTICS:\n");
+ ASTStreamer_PrintStats(Streamer);
+ Context.PrintStats();
+ }
+
+ ASTStreamer_Terminate(Streamer);
+}
+
diff --git a/Driver/ASTStreamers.h b/Driver/ASTStreamers.h
index 34ce864..f568e8e 100644
--- a/Driver/ASTStreamers.h
+++ b/Driver/ASTStreamers.h
@@ -29,6 +29,8 @@
void AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID);
+void RunDeadStoresCheck(Preprocessor &PP, unsigned MainFileID, bool Stats);
+
} // end clang namespace
#endif
diff --git a/Driver/Makefile b/Driver/Makefile
index eca316e..3577a2b 100644
--- a/Driver/Makefile
+++ b/Driver/Makefile
@@ -3,6 +3,6 @@
CXXFLAGS = -fno-rtti
TOOLNAME = clang
-USEDLIBS = clangCodeGen.a clangSEMA.a clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a LLVMCore.a LLVMSupport.a LLVMSystem.a
+USEDLIBS = clangCodeGen.a clangAnalysis.a clangSEMA.a clangAST.a clangParse.a clangLex.a clangBasic.a LLVMCore.a LLVMSupport.a LLVMSystem.a
include $(LEVEL)/Makefile.common
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index ed540ae..79a09f1 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -53,8 +53,9 @@
ParseASTCheck, // Parse ASTs and check diagnostics.
ParseAST, // Parse ASTs.
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
- ParseCFGView, // Parse ASTS. Build CFGs. View CFGs (Graphviz).
+ ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
AnalysisLiveVariables, // Print results of live-variable analysis.
+ WarnDeadStores, // Run DeadStores checker on parsed ASTs.
ParsePrintCallbacks, // Parse and print each callback.
ParseSyntaxOnly, // Parse and perform semantic analysis.
ParseNoop, // Parse with noop callbacks.
@@ -93,6 +94,8 @@
"Run parser, then build and view CFGs with Graphviz."),
clEnumValN(AnalysisLiveVariables, "dump-live-variables",
"Print results of live variable analysis."),
+ clEnumValN(WarnDeadStores, "check-dead-stores",
+ "Flag warnings of stores to dead variables."),
clEnumValN(EmitLLVM, "emit-llvm",
"Build ASTs then convert to LLVM, emit .ll file"),
clEnumValEnd));
@@ -851,7 +854,10 @@
break;
case AnalysisLiveVariables:
AnalyzeLiveVariables(PP, MainFileID);
- break;
+ break;
+ case WarnDeadStores:
+ RunDeadStoresCheck(PP, MainFileID, Stats);
+ break;
case EmitLLVM:
EmitLLVMFromASTs(PP, MainFileID, Stats);
break;