aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Frontend/Analyses.def25
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp188
-rw-r--r--test/Analysis/inline.c4
-rw-r--r--test/Analysis/inline2.c3
-rw-r--r--test/Analysis/inline3.c4
-rw-r--r--test/Analysis/inline4.c4
-rw-r--r--test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m2
7 files changed, 82 insertions, 148 deletions
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index 287c67ebb7..aaa3920cee 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -15,22 +15,21 @@
#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
#endif
-ANALYSIS(CFGDump, "cfg-dump",
+ANALYSIS(CFGDump, "cfg-dump",
"Display Control-Flow Graphs", Code)
-ANALYSIS(CFGView, "cfg-view",
+ANALYSIS(CFGView, "cfg-view",
"View Control-Flow Graphs using GraphViz", Code)
ANALYSIS(DisplayLiveVariables, "dump-live-variables",
"Print results of live variable analysis", Code)
ANALYSIS(SecuritySyntacticChecks, "analyzer-check-security-syntactic",
- "Perform quick security checks that require no data flow",
- Code)
+ "Perform quick security checks that require no data flow", Code)
ANALYSIS(LLVMConventionChecker, "analyzer-check-llvm-conventions",
- "Check code for LLVM codebase conventions (domain-specific)",
- TranslationUnit)
+ "Check code for LLVM codebase conventions (domain-specific)",
+ TranslationUnit)
ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
"Warn about stores to dead variables", Code)
@@ -39,15 +38,15 @@ ANALYSIS(WarnUninitVals, "warn-uninit-values",
"Warn about uses of uninitialized variables", Code)
ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
- "Warn about Objective-C method signatures with type incompatibilities",
- ObjCImplementation)
+ "Warn about Objective-C method signatures with type incompatibilities",
+ ObjCImplementation)
ANALYSIS(WarnObjCDealloc, "analyzer-check-objc-missing-dealloc",
- "Warn about Objective-C classes that lack a correct implementation of -dealloc",
- ObjCImplementation)
+"Warn about Objective-C classes that lack a correct implementation of -dealloc",
+ ObjCImplementation)
ANALYSIS(WarnObjCUnusedIvars, "analyzer-check-objc-unused-ivars",
- "Warn about private ivars that are never used", ObjCImplementation)
+ "Warn about private ivars that are never used", ObjCImplementation)
ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
"Run the [Core] Foundation reference count checker", Code)
@@ -55,10 +54,6 @@ ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
"Warn about unintended use of sizeof() on pointer expressions", Code)
-ANALYSIS(InlineCall, "inline-call",
- "Experimental transfer function inling callees when its definition"
- " is available.", TranslationUnit)
-
#ifndef ANALYSIS_STORE
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
#endif
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
index d55fbc1a21..6e23e16b51 100644
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -62,20 +62,21 @@ CreatePlistHTMLDiagnosticClient(const std::string& prefix,
namespace {
- class AnalysisConsumer : public ASTConsumer {
- public:
+class AnalysisConsumer : public ASTConsumer {
+public:
typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
TranslationUnitDecl &TU);
- private:
+private:
typedef std::vector<CodeAction> Actions;
typedef std::vector<TUAction> TUActions;
Actions FunctionActions;
Actions ObjCMethodActions;
Actions ObjCImplementationActions;
- TUActions TranslationUnitActions;
+ Actions CXXMethodActions;
+ TUActions TranslationUnitActions; // Remove this.
public:
ASTContext* Ctx;
@@ -161,16 +162,17 @@ public:
void addCodeAction(CodeAction action) {
FunctionActions.push_back(action);
ObjCMethodActions.push_back(action);
- }
-
- void addObjCImplementationAction(CodeAction action) {
- ObjCImplementationActions.push_back(action);
+ CXXMethodActions.push_back(action);
}
void addTranslationUnitAction(TUAction action) {
TranslationUnitActions.push_back(action);
}
+ void addObjCImplementationAction(CodeAction action) {
+ ObjCImplementationActions.push_back(action);
+ }
+
virtual void Initialize(ASTContext &Context) {
Ctx = &Context;
Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
@@ -182,16 +184,8 @@ public:
Opts.TrimGraph));
}
- virtual void HandleTopLevelDecl(DeclGroupRef D) {
- declDisplayed = false;
- for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
- HandleTopLevelSingleDecl(*I);
- }
-
- void HandleTopLevelSingleDecl(Decl *D);
virtual void HandleTranslationUnit(ASTContext &C);
-
- void HandleCode(Decl* D, Stmt* Body, Actions& actions);
+ void HandleCode(Decl *D, Stmt* Body, Actions& actions);
};
} // end anonymous namespace
@@ -208,57 +202,69 @@ namespace llvm {
// AnalysisConsumer implementation.
//===----------------------------------------------------------------------===//
-void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
- switch (D->getKind()) {
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- case Decl::CXXConversion:
- case Decl::CXXMethod:
- case Decl::Function: {
- FunctionDecl* FD = cast<FunctionDecl>(D);
- if (!Opts.AnalyzeSpecificFunction.empty() &&
- FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
- break;
-
- if (Stmt *Body = FD->getBody())
- HandleCode(FD, Body, FunctionActions);
- break;
- }
-
- case Decl::ObjCMethod: {
- ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
- if (!Opts.AnalyzeSpecificFunction.empty() &&
- Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
- return;
+ TranslationUnitDecl *TU = C.getTranslationUnitDecl();
- if (Stmt* Body = MD->getBody())
- HandleCode(MD, Body, ObjCMethodActions);
- break;
- }
+ for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end();
+ I != E; ++I) {
+ Decl *D = *I;
+
+ switch (D->getKind()) {
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
+ case Decl::CXXConversion:
+ case Decl::CXXMethod:
+ case Decl::Function: {
+ FunctionDecl* FD = cast<FunctionDecl>(D);
+
+ if (FD->isThisDeclarationADefinition()) {
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
+ FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
+ break;
+ HandleCode(FD, FD->getBody(), FunctionActions);
+ }
+ break;
+ }
- default:
- break;
- }
-}
+ case Decl::ObjCMethod: {
+ ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+
+ if (MD->isThisDeclarationADefinition()) {
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
+ Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
+ break;
+ HandleCode(MD, MD->getBody(), ObjCMethodActions);
+ }
+ break;
+ }
-void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
+ case Decl::ObjCImplementation: {
+ ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
+ HandleCode(ID, 0, ObjCImplementationActions);
+
+ for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(),
+ ME = ID->meth_end(); MI != ME; ++MI) {
+ if ((*MI)->isThisDeclarationADefinition()) {
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
+ Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
+ break;
+ HandleCode(*MI, (*MI)->getBody(), ObjCMethodActions);
+ }
+ }
+ break;
+ }
- TranslationUnitDecl *TU = C.getTranslationUnitDecl();
+ default:
+ break;
+ }
+ }
for (TUActions::iterator I = TranslationUnitActions.begin(),
E = TranslationUnitActions.end(); I != E; ++I) {
(*I)(*this, *Mgr, *TU);
}
- if (!ObjCImplementationActions.empty()) {
- for (DeclContext::decl_iterator I = TU->decls_begin(),
- E = TU->decls_end();
- I != E; ++I)
- if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
- HandleCode(ID, 0, ObjCImplementationActions);
- }
-
// Explicitly destroy the PathDiagnosticClient. This will flush its output.
// FIXME: This should be replaced with something that doesn't rely on
// side-effects in PathDiagnosticClient's destructor. This is required when
@@ -311,7 +317,6 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
static void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (LiveVariables *L = mgr.getLiveVariables(D)) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR);
}
@@ -320,7 +325,6 @@ static void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
static void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (CFG* c = mgr.getCFG(D)) {
- C.DisplayFunction(D);
CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
}
}
@@ -332,15 +336,11 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
llvm::OwningPtr<GRTransferFuncs> TF(tf);
- // Display progress.
- C.DisplayFunction(D);
-
// Construct the analysis engine. We first query for the LiveVariables
// information to see if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs.
if (!mgr.getLiveVariables(D))
return;
-
GRExprEngine Eng(mgr, TF.take());
if (C.Opts.EnableExperimentalInternalChecks)
@@ -407,28 +407,24 @@ static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
static void ActionDisplayLiveVariables(AnalysisConsumer &C,
AnalysisManager& mgr, Decl *D) {
if (LiveVariables* L = mgr.getLiveVariables(D)) {
- C.DisplayFunction(D);
L->dumpBlockLiveness(mgr.getSourceManager());
}
}
static void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
if (CFG *cfg = mgr.getCFG(D)) {
- C.DisplayFunction(D);
cfg->dump(mgr.getLangOptions());
}
}
static void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
if (CFG *cfg = mgr.getCFG(D)) {
- C.DisplayFunction(D);
cfg->viewCFG(mgr.getLangOptions());
}
}
static void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
AnalysisManager &mgr, Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckSecuritySyntaxOnly(D, BR);
}
@@ -444,86 +440,28 @@ static void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
return;
-
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
}
static void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
}
static void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
}
static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckSizeofPointer(D, BR);
}
-static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
- TranslationUnitDecl &TU) {
-
- // Find the entry function definition (if any).
- FunctionDecl *D = 0;
-
- // Must specify an entry function.
- if (!C.Opts.AnalyzeSpecificFunction.empty()) {
- for (DeclContext::decl_iterator I=TU.decls_begin(), E=TU.decls_end();
- I != E; ++I) {
- if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
- if (fd->isThisDeclarationADefinition() &&
- fd->getNameAsString() == C.Opts.AnalyzeSpecificFunction) {
- D = fd;
- break;
- }
- }
- }
-
- if (!D)
- return;
-
-
- // FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
- // Display progress.
- C.DisplayFunction(D);
-
- // FIXME: Make a fake transfer function. The GRTransferFunc interface
- // eventually will be removed.
- GRExprEngine Eng(mgr, new GRTransferFuncs());
-
- if (C.Opts.EnableExperimentalInternalChecks)
- RegisterExperimentalInternalChecks(Eng);
-
- RegisterAppleChecks(Eng, *D);
-
- if (C.Opts.EnableExperimentalChecks)
- RegisterExperimentalChecks(Eng);
-
- // Register call inliner as the last checker.
- RegisterCallInliner(Eng);
-
- // Execute the worklist algorithm.
- Eng.ExecuteWorkList(mgr.getStackFrame(D));
-
- // Visualize the exploded graph.
- if (mgr.shouldVisualizeGraphviz())
- Eng.ViewGraph(mgr.shouldTrimGraph());
-
- // Display warnings.
- Eng.getBugReporter().FlushReports();
-}
-
//===----------------------------------------------------------------------===//
// AnalysisConsumer creation.
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
index 952de737f7..acaf74ded9 100644
--- a/test/Analysis/inline.c
+++ b/test/Analysis/inline.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
-
+// RUN: false
+// XFAIL: *
int f1() {
int y = 1;
y++;
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
index e2758c160a..ec965a69c6 100644
--- a/test/Analysis/inline2.c
+++ b/test/Analysis/inline2.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+// RUN: false
+// XFAIL: *
// Test parameter 'a' is registered to LiveVariables analysis data although it
// is not referenced in the function body.
diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c
index 3661263b6b..8f45858bb9 100644
--- a/test/Analysis/inline3.c
+++ b/test/Analysis/inline3.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
-
+// RUN: false
+// XFAIL: *
// Test when entering f1(), we set the right AnalysisContext to Environment.
// Otherwise, block-level expr '1 && a' would not be block-level.
diff --git a/test/Analysis/inline4.c b/test/Analysis/inline4.c
index dd2379f043..b2b3c346e3 100644
--- a/test/Analysis/inline4.c
+++ b/test/Analysis/inline4.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f -verify %s
-
+// RUN: false
+// XFAIL: *
int g(int a) {
return a;
}
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
index 2e9c528612..5f5187194d 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -72,11 +72,11 @@ int handleVoidInComma() {
int marker(void) { // control reaches end of non-void function
}
+// CHECK-darwin8: control reaches end of non-void function
// CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
// CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
-// CHECK-darwin8: control reaches end of non-void function
// CHECK-darwin8: 5 warnings generated
// CHECK-darwin9: control reaches end of non-void function
// CHECK-darwin9: 1 warning generated