Added boilerplate to execute the CF reference count checker (which isn't yet implemented).
llvm-svn: 47982
This commit is contained in:
parent
dcabdb1b38
commit
ea6507fe04
|
@ -0,0 +1,65 @@
|
|||
// CFRefCount.cpp - Transfer functions for tracking simple values -*- C++ -*--
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This files defines the methods for CFRefCount, which implements
|
||||
// a reference count checker for Core Foundation (Mac OS X).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CFRefCount.h"
|
||||
#include "clang/Analysis/PathSensitive/ValueState.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Analysis/LocalCheckers.h"
|
||||
|
||||
|
||||
using namespace clang;
|
||||
|
||||
|
||||
namespace clang {
|
||||
|
||||
void CheckCFRefCount(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
|
||||
Diagnostic& Diag) {
|
||||
|
||||
if (Diag.hasErrorOccurred())
|
||||
return;
|
||||
|
||||
// FIXME: Refactor some day so this becomes a single function invocation.
|
||||
|
||||
GRCoreEngine<GRExprEngine> Engine(cfg, FD, Ctx);
|
||||
GRExprEngine* CS = &Engine.getCheckerState();
|
||||
CFRefCount TF;
|
||||
CS->setTransferFunctions(TF);
|
||||
Engine.ExecuteWorkList(20000);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CFRefCount::EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
||||
ValueStateManager& StateMgr,
|
||||
GRStmtNodeBuilder<ValueState>& Builder,
|
||||
ValueManager& ValMgr,
|
||||
CallExpr* CE, LVal L,
|
||||
ExplodedNode<ValueState>* Pred) {
|
||||
|
||||
ValueState* St = Pred->getState();
|
||||
|
||||
// Invalidate all arguments passed in by reference (LVals).
|
||||
|
||||
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end();
|
||||
I != E; ++I) {
|
||||
|
||||
RVal V = StateMgr.GetRVal(St, *I);
|
||||
|
||||
if (isa<LVal>(V))
|
||||
St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
|
||||
}
|
||||
|
||||
Builder.Nodify(Dst, CE, Pred, St);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// CFRefCount.h - Transfer functions for the CF Ref. Count checker -*- C++ -*---
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This files defines CFRefCount, which defines the transfer functions
|
||||
// to implement the Core Foundation reference count checker.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ANALYSIS_GRREFCOUNT
|
||||
#define LLVM_CLANG_ANALYSIS_GRREFCOUNT
|
||||
|
||||
#include "GRSimpleVals.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class CFRefCount : public GRSimpleVals {
|
||||
public:
|
||||
CFRefCount() {}
|
||||
virtual ~CFRefCount() {}
|
||||
|
||||
// Calls.
|
||||
|
||||
virtual void EvalCall(ExplodedNodeSet<ValueState>& Dst,
|
||||
ValueStateManager& StateMgr,
|
||||
GRStmtNodeBuilder<ValueState>& Builder,
|
||||
ValueManager& ValMgr,
|
||||
CallExpr* CE, LVal L,
|
||||
ExplodedNode<ValueState>* Pred);
|
||||
};
|
||||
|
||||
} // end clang namespace
|
||||
|
||||
#endif
|
|
@ -636,6 +636,43 @@ void GRSimpleValsVisitor::VisitCFG(CFG& C, FunctionDecl& FD) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Core Foundation Reference Counting Checker
|
||||
|
||||
namespace {
|
||||
class CFRefCountCheckerVisitor : public CFGVisitor {
|
||||
Diagnostic &Diags;
|
||||
ASTContext* Ctx;
|
||||
|
||||
public:
|
||||
CFRefCountCheckerVisitor(Diagnostic &diags, const std::string& fname)
|
||||
: CFGVisitor(fname), Diags(diags) {}
|
||||
|
||||
virtual void Initialize(ASTContext &Context) { Ctx = &Context; }
|
||||
virtual void VisitCFG(CFG& C, FunctionDecl&);
|
||||
virtual bool printFuncDeclStart() { return false; }
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
ASTConsumer* clang::CreateCFRefChecker(Diagnostic &Diags,
|
||||
const std::string& FunctionName) {
|
||||
|
||||
return new CFRefCountCheckerVisitor(Diags, FunctionName);
|
||||
}
|
||||
|
||||
void CFRefCountCheckerVisitor::VisitCFG(CFG& C, FunctionDecl& FD) {
|
||||
|
||||
SourceLocation Loc = FD.getLocation();
|
||||
|
||||
if (!Loc.isFileID() ||
|
||||
Loc.getFileID() != Ctx->getSourceManager().getMainFileID())
|
||||
return;
|
||||
|
||||
CheckCFRefCount(C, FD, *Ctx, Diags);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// AST Serializer
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@ ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
|
|||
ASTConsumer *CreateGRSimpleVals(Diagnostic &Diags,
|
||||
const std::string& Function,
|
||||
bool Visualize = false);
|
||||
|
||||
ASTConsumer* CreateCFRefChecker(Diagnostic &Diags,
|
||||
const std::string& FunctionName);
|
||||
|
||||
ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
|
||||
Diagnostic &Diags);
|
||||
|
|
|
@ -71,6 +71,7 @@ enum ProgActions {
|
|||
AnalysisLiveVariables, // Print results of live-variable analysis.
|
||||
AnalysisGRSimpleVals, // Perform graph-reachability constant prop.
|
||||
AnalysisGRSimpleValsView, // Visualize results of path-sens. analysis.
|
||||
CheckerCFRef, // Run the Core Foundation Ref. Count Checker.
|
||||
WarnDeadStores, // Run DeadStores checker on parsed ASTs.
|
||||
WarnDeadStoresCheck, // Check diagnostics for "DeadStores".
|
||||
WarnUninitVals, // Run UnitializedVariables checker.
|
||||
|
@ -119,6 +120,8 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
|
|||
"Perform path-sensitive constant propagation."),
|
||||
clEnumValN(AnalysisGRSimpleValsView, "grsimple-view",
|
||||
"View results of path-sensitive constant propagation."),
|
||||
clEnumValN(CheckerCFRef, "check-cfref",
|
||||
"Run the Core Foundation reference count checker."),
|
||||
clEnumValN(TestSerialization, "test-pickling",
|
||||
"Run prototype serializtion code."),
|
||||
clEnumValN(EmitLLVM, "emit-llvm",
|
||||
|
@ -1038,6 +1041,9 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
|
|||
case AnalysisGRSimpleValsView:
|
||||
return CreateGRSimpleVals(Diag, AnalyzeSpecificFunction, true);
|
||||
|
||||
case CheckerCFRef:
|
||||
return CreateCFRefChecker(Diag, AnalyzeSpecificFunction);
|
||||
|
||||
case TestSerialization:
|
||||
return CreateSerializationTest(Diag, FileMgr, LangOpts);
|
||||
|
||||
|
|
|
@ -27,7 +27,9 @@ void CheckDeadStores(CFG& cfg, FunctionDecl& FD, ASTContext &Ctx,
|
|||
|
||||
void CheckUninitializedValues(CFG& cfg, ASTContext& Ctx, Diagnostic& Diags,
|
||||
bool FullUninitTaint=false);
|
||||
|
||||
|
||||
void CheckCFRefCount(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
|
||||
Diagnostic& Diag);
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
|
|
Loading…
Reference in New Issue