[cfe-commits] r41754 - in /cfe/trunk: Analysis/LiveVariables.cpp Driver/ASTStreamers.cpp Driver/ASTStreamers.h Driver/Makefile Driver/clang.cpp clang.xcodeproj/project.pbxproj include/clang/Analysis/LiveVariables.h include/clang/Basic/DiagnosticKinds.def
Ted Kremenek
kremenek at apple.com
Thu Sep 6 16:00:42 PDT 2007
Author: kremenek
Date: Thu Sep 6 18:00:42 2007
New Revision: 41754
URL: http://llvm.org/viewvc/llvm-project?rev=41754&view=rev
Log:
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
Modified:
cfe/trunk/Analysis/LiveVariables.cpp
cfe/trunk/Driver/ASTStreamers.cpp
cfe/trunk/Driver/ASTStreamers.h
cfe/trunk/Driver/Makefile
cfe/trunk/Driver/clang.cpp
cfe/trunk/clang.xcodeproj/project.pbxproj
cfe/trunk/include/clang/Analysis/LiveVariables.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/Analysis/LiveVariables.cpp Thu Sep 6 18:00:42 2007
@@ -372,7 +372,7 @@
// liveness queries
//
-bool LiveVariables::IsLive(const CFGBlock* B, const Decl* D) const {
+bool LiveVariables::isLive(const CFGBlock* B, const Decl* D) const {
BlockLivenessMap::const_iterator I = LiveAtBlockEntryMap.find(B);
assert (I != LiveAtBlockEntryMap.end());
@@ -382,6 +382,12 @@
return I->second[VI->second.Idx];
}
+bool LiveVariables::isLive(llvm::BitVector& Live, const Decl* D) const {
+ VarInfoMap::const_iterator VI = VarInfos.find(D);
+ assert (VI != VarInfos.end());
+ return Live[VI->second.Idx];
+}
+
bool LiveVariables::KillsVar(const Stmt* S, const Decl* D) const {
VarInfoMap::const_iterator VI = VarInfos.find(D);
assert (VI != VarInfos.end());
@@ -405,6 +411,15 @@
}
//===----------------------------------------------------------------------===//
+// Defaults for LiveVariablesAuditor
+
+void LiveVariablesAuditor::AuditStmt(Stmt* S, LiveVariables& L,
+ llvm::BitVector& V) {}
+
+void LiveVariablesAuditor::AuditBlockExit(const CFGBlock* B, LiveVariables& L,
+ llvm::BitVector& V) {}
+
+//===----------------------------------------------------------------------===//
// printing liveness state for debugging
//
Modified: cfe/trunk/Driver/ASTStreamers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.cpp?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTStreamers.cpp (original)
+++ cfe/trunk/Driver/ASTStreamers.cpp Thu Sep 6 18:00:42 2007
@@ -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);
+}
+
Modified: cfe/trunk/Driver/ASTStreamers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.h?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTStreamers.h (original)
+++ cfe/trunk/Driver/ASTStreamers.h Thu Sep 6 18:00:42 2007
@@ -29,6 +29,8 @@
void AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID);
+void RunDeadStoresCheck(Preprocessor &PP, unsigned MainFileID, bool Stats);
+
} // end clang namespace
#endif
Modified: cfe/trunk/Driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Makefile?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/Driver/Makefile (original)
+++ cfe/trunk/Driver/Makefile Thu Sep 6 18:00:42 2007
@@ -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
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Thu Sep 6 18:00:42 2007
@@ -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;
Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Thu Sep 6 18:00:42 2007
@@ -13,6 +13,7 @@
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */; };
+ 355CF6840C90A8D400A08AA3 /* DeadStores.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 355CF6830C90A8D400A08AA3 /* DeadStores.cpp */; };
356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */; };
84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; };
84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; };
@@ -210,6 +211,8 @@
1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; };
35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = AST/ExprCXX.cpp; sourceTree = "<group>"; };
3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = "<group>"; };
+ 355CF6820C90A8B600A08AA3 /* LocalCheckers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LocalCheckers.h; path = clang/Analysis/LocalCheckers.h; sourceTree = "<group>"; };
+ 355CF6830C90A8D400A08AA3 /* DeadStores.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DeadStores.cpp; path = Analysis/DeadStores.cpp; sourceTree = "<group>"; };
356EF9B20C8F7DBA006650F5 /* LiveVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LiveVariables.h; path = clang/Analysis/LiveVariables.h; sourceTree = "<group>"; };
356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LiveVariables.cpp; path = Analysis/LiveVariables.cpp; sourceTree = "<group>"; };
84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
@@ -377,9 +380,18 @@
name = Products;
sourceTree = "<group>";
};
+ 355CF6850C90A8D600A08AA3 /* LocalCheckers */ = {
+ isa = PBXGroup;
+ children = (
+ 355CF6830C90A8D400A08AA3 /* DeadStores.cpp */,
+ );
+ name = LocalCheckers;
+ sourceTree = "<group>";
+ };
356EF9AF0C8F7DA4006650F5 /* Analysis */ = {
isa = PBXGroup;
children = (
+ 355CF6820C90A8B600A08AA3 /* LocalCheckers.h */,
356EF9B20C8F7DBA006650F5 /* LiveVariables.h */,
);
name = Analysis;
@@ -389,6 +401,7 @@
isa = PBXGroup;
children = (
356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */,
+ 355CF6850C90A8D600A08AA3 /* LocalCheckers */,
);
name = Analysis;
sourceTree = "<group>";
@@ -741,6 +754,7 @@
35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */,
DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */,
356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */,
+ 355CF6840C90A8D400A08AA3 /* DeadStores.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: cfe/trunk/include/clang/Analysis/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/LiveVariables.h?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/LiveVariables.h (original)
+++ cfe/trunk/include/clang/Analysis/LiveVariables.h Thu Sep 6 18:00:42 2007
@@ -30,14 +30,14 @@
class LiveVariablesAuditor {
public:
- virtual ~LiveVariablesAuditor();
+ virtual ~LiveVariablesAuditor() {}
/// AuditStmt - A callback invoked right before invoking the liveness
/// transfer function on the given statement. If the liveness information
/// has been previously calculated by running LiveVariables::runOnCFG,
/// then V contains the liveness information after the execution of
/// the given statement.
- virtual void AuditStmt(Stmt* S, LiveVariables& L, llvm::BitVector& V) = 0;
+ virtual void AuditStmt(Stmt* S, LiveVariables& L, llvm::BitVector& V);
/// AuditBlockExit - A callback invoked right before invoking the liveness
/// transfer function on the given block. If the liveness information
@@ -45,7 +45,7 @@
/// then V contains the liveness information after the execution of
/// the given block.
virtual void AuditBlockExit(const CFGBlock* B, LiveVariables& L,
- llvm::BitVector& V) = 0;
+ llvm::BitVector& V);
};
class LiveVariables {
@@ -100,7 +100,12 @@
/// IsLive - Return true if a variable is live at beginning of a specified
// block.
- bool IsLive(const CFGBlock* B, const Decl* D) const;
+ bool isLive(const CFGBlock* B, const Decl* D) const;
+
+ /// IsLive - Return true if a variable is live according to the provided
+ /// livness bitvector. This is typically used by classes that subclass
+ /// LiveVariablesAuditor.
+ bool isLive(llvm::BitVector& V, const Decl* D) const;
/// getVarInfo - Return the liveness information associated with a given
/// variable.
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=41754&r1=41753&r2=41754&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Sep 6 18:00:42 2007
@@ -748,6 +748,9 @@
DIAG(warn_floatingpoint_eq, WARNING,
"comparing floating point with == or != is unsafe")
+// CHECK: stores to variables that are no longer live (dead stores)
+DIAG(warn_dead_store, WARNING, "value stored to variable is never used")
+
// CFString checking
DIAG(err_cfstring_literal_not_string_constant, ERROR,
"CFString literal is not a string constant")
More information about the cfe-commits
mailing list