[analyzer] Replace "-analyzer-ipa" with "-analyzer-config ipa".

The idea is to eventually place all analyzer options under
"analyzer-config". In addition, this lays the ground for introduction of
a high-level analyzer mode option, which will influence the
default setting for IPAMode.

llvm-svn: 173385
This commit is contained in:
Anna Zaks 2013-01-24 23:15:30 +00:00
parent c7f5e69e50
commit 6bab4ef4e8
36 changed files with 111 additions and 100 deletions

View File

@ -41,16 +41,6 @@ ANALYSIS_PURGE(PurgeStmt, "statement", "Purge symbols, bindings, and constraint
ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block")
ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constraints")
#ifndef ANALYSIS_IPA
#define ANALYSIS_IPA(NAME, CMDFLAG, DESC)
#endif
ANALYSIS_IPA(None, "none", "Perform only intra-procedural analysis")
ANALYSIS_IPA(BasicInlining, "basic-inlining", "Inline C functions and blocks when their definitions are available")
ANALYSIS_IPA(Inlining, "inlining", "Inline callees when their definitions are available")
ANALYSIS_IPA(DynamicDispatch, "dynamic", "Experimental: Enable inlining of dynamically dispatched methods")
ANALYSIS_IPA(DynamicDispatchBifurcate, "dynamic-bifurcate", "Experimental: Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailable")
#ifndef ANALYSIS_INLINING_MODE
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
#endif

View File

@ -64,13 +64,6 @@ enum AnalysisPurgeMode {
NumPurgeModes
};
/// AnalysisIPAMode - Set of inter-procedural modes.
enum AnalysisIPAMode {
#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) NAME,
#include "clang/StaticAnalyzer/Core/Analyses.def"
NumIPAModes
};
/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
enum AnalysisInliningMode {
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
@ -102,6 +95,27 @@ enum CXXInlineableMemberKind {
CIMK_Destructors
};
/// \brief Describes the different modes of inter-procedural analysis.
enum IPAKind {
IPAK_NotSet = 0,
/// Perform only intra-procedural analysis.
IPAK_None = 1,
/// Inline C functions and blocks when their definitions are available.
IPAK_BasicInlining = 2,
/// Inline callees when their definitions are available.
// TODO: How is this different from BasicInlining?
IPAK_Inlining = 3,
/// Enable inlining of dynamically dispatched methods.
IPAK_DynamicDispatch = 4,
/// Enable inlining of dynamically dispatched methods, bifurcate paths when
/// exact type info is unavailable.
IPAK_DynamicDispatchBifurcate = 5
};
class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
public:
@ -117,9 +131,6 @@ public:
AnalysisDiagClients AnalysisDiagOpt;
AnalysisPurgeMode AnalysisPurgeOpt;
// \brief The interprocedural analysis mode.
AnalysisIPAMode IPAMode;
std::string AnalyzeSpecificFunction;
/// \brief The maximum number of exploded nodes the analyzer will generate.
@ -165,6 +176,9 @@ public:
AnalysisInliningMode InliningMode;
private:
/// Controls the mode of inter-procedural analysis.
IPAKind IPAMode;
/// Controls which C++ member functions will be considered for inlining.
CXXInlineableMemberKind CXXMemberInliningMode;
@ -210,9 +224,8 @@ private:
int getOptionAsInteger(StringRef Name, int DefaultVal);
public:
AnalysisIPAMode getIPAMode() const {
return IPAMode;
}
/// \brief Returns the inter-procedural analysis mode.
IPAKind getIPAMode();
/// Returns the option controlling which C++ member functions will be
/// considered for inlining.
@ -289,28 +302,28 @@ public:
unsigned getMaxTimesInlineLarge();
public:
AnalyzerOptions() : CXXMemberInliningMode() {
AnalysisStoreOpt = RegionStoreModel;
AnalysisConstraintsOpt = RangeConstraintsModel;
AnalysisDiagOpt = PD_HTML;
AnalysisPurgeOpt = PurgeStmt;
IPAMode = DynamicDispatchBifurcate;
ShowCheckerHelp = 0;
AnalyzeAll = 0;
AnalyzerDisplayProgress = 0;
AnalyzeNestedBlocks = 0;
eagerlyAssumeBinOpBifurcation = 0;
TrimGraph = 0;
visualizeExplodedGraphWithGraphViz = 0;
visualizeExplodedGraphWithUbiGraph = 0;
UnoptimizedCFG = 0;
PrintStats = 0;
NoRetryExhausted = 0;
AnalyzerOptions() :
AnalysisStoreOpt(RegionStoreModel),
AnalysisConstraintsOpt(RangeConstraintsModel),
AnalysisDiagOpt(PD_HTML),
AnalysisPurgeOpt(PurgeStmt),
ShowCheckerHelp(0),
AnalyzeAll(0),
AnalyzerDisplayProgress(0),
AnalyzeNestedBlocks(0),
eagerlyAssumeBinOpBifurcation(0),
TrimGraph(0),
visualizeExplodedGraphWithGraphViz(0),
visualizeExplodedGraphWithUbiGraph(0),
UnoptimizedCFG(0),
PrintStats(0),
NoRetryExhausted(0),
// Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
InlineMaxStackDepth = 5;
InlineMaxFunctionSize = 50;
InliningMode = NoRedundancy;
}
InlineMaxStackDepth(5),
InlineMaxFunctionSize(50),
InliningMode(NoRedundancy),
CXXMemberInliningMode() {}
};
typedef IntrusiveRefCntPtr<AnalyzerOptions> AnalyzerOptionsRef;

View File

@ -100,7 +100,7 @@ public:
}
bool shouldInlineCall() const {
return options.IPAMode != None;
return options.getIPAMode() != IPAK_None;
}
CFG *getCFG(Decl const *D) {

View File

@ -188,22 +188,6 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
}
}
if (Arg *A = Args.getLastArg(OPT_analyzer_ipa)) {
StringRef Name = A->getValue();
AnalysisIPAMode Value = llvm::StringSwitch<AnalysisIPAMode>(Name)
#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) \
.Case(CMDFLAG, NAME)
#include "clang/StaticAnalyzer/Core/Analyses.def"
.Default(NumIPAModes);
if (Value == NumIPAModes) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << Name;
Success = false;
} else {
Opts.IPAMode = Value;
}
}
if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
StringRef Name = A->getValue();
AnalysisInliningMode Value = llvm::StringSwitch<AnalysisInliningMode>(Name)

View File

@ -20,9 +20,31 @@
using namespace clang;
using namespace llvm;
IPAKind AnalyzerOptions::getIPAMode() {
if (IPAMode == IPAK_NotSet) {
// Lookup the ipa configuration option, use the default from User Mode.
StringRef ModeStr(Config.GetOrCreateValue("ipa",
"dynamic-bifurcate").getValue());
IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
.Case("none", IPAK_None)
.Case("basic-inlining", IPAK_BasicInlining)
.Case("inlining", IPAK_Inlining)
.Case("dynamic", IPAK_DynamicDispatch)
.Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
.Default(IPAK_NotSet);
assert(IPAConfig != IPAK_NotSet && "IPA Mode is not set or invalid.");
// Set the member variable.
IPAMode = IPAConfig;
}
return IPAMode;
}
bool
AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind K) {
if (getIPAMode() < Inlining)
if (getIPAMode() < IPAK_Inlining)
return false;
if (!CXXMemberInliningMode) {

View File

@ -559,8 +559,8 @@ bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
if (!Opts.mayInlineObjCMethod())
return false;
AnalyzerOptions &Options = getAnalysisManager().options;
if (!(Options.getIPAMode() == DynamicDispatch ||
Options.getIPAMode() == DynamicDispatchBifurcate))
if (!(Options.getIPAMode() == IPAK_DynamicDispatch ||
Options.getIPAMode() == IPAK_DynamicDispatchBifurcate))
return false;
break;
}
@ -741,13 +741,13 @@ void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
AnalyzerOptions &Options = getAnalysisManager().options;
// Explore with and without inlining the call.
if (Options.getIPAMode() == DynamicDispatchBifurcate) {
if (Options.getIPAMode() == IPAK_DynamicDispatchBifurcate) {
BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
return;
}
// Don't inline if we're not in any dynamic dispatch mode.
if (Options.getIPAMode() != DynamicDispatch) {
if (Options.getIPAMode() != IPAK_DynamicDispatch) {
conservativeEvalCall(*Call, Bldr, Pred, State);
return;
}

View File

@ -8,7 +8,8 @@ void foo() { bar(); }
// CHECK-NEXT: cfg-temporary-dtors = false
// CHECK-NEXT: faux-bodies = true
// CHECK-NEXT: graph-trim-interval = 1000
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: [stats]
// CHECK-NEXT: num-entries = 5
// CHECK-NEXT: num-entries = 6

View File

@ -17,7 +17,8 @@ public:
// CHECK-NEXT: cfg-temporary-dtors = false
// CHECK-NEXT: faux-bodies = true
// CHECK-NEXT: graph-trim-interval = 1000
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: [stats]
// CHECK-NEXT: num-entries = 8
// CHECK-NEXT: num-entries = 9

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=none -fblocks -verify %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify %s
void clang_analyzer_eval(int);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=none -verify %s
// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=inlining -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -verify %s
void clang_analyzer_eval(bool);
void clang_analyzer_checkInlined(bool);
@ -192,7 +192,7 @@ namespace Invalidation {
virtual void touchV2(int &x) const;
int test() const {
// We were accidentally not invalidating under -analyzer-ipa=inlining
// We were accidentally not invalidating under inlining
// at one point for virtual methods with visible definitions.
int a, b, c, d;
touch(a);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
#include "InlineObjCInstanceMethod.h"

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -verify %s
// Test inlining of ObjC class methods.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
#include "InlineObjCInstanceMethod.h"

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
typedef signed char BOOL;
@protocol NSObject - (BOOL)isEqual:(id)object; @end

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
typedef signed char BOOL;
typedef struct objc_class *Class;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-ipa=dynamic-bifurcate -analyzer-checker=core,osx -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -verify %s
typedef signed char BOOL;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-ipa=dynamic-bifurcate -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-config ipa=dynamic-bifurcate -verify %s
typedef signed char BOOL;
typedef struct objc_class *Class;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=dynamic -analyzer-config c++-stdlib-inlining=false -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-ipa=dynamic -analyzer-config c++-stdlib-inlining=true -DINLINE=1 -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-stdlib-inlining=false -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-stdlib-inlining=true -DINLINE=1 -verify %s
#include "../Inputs/system-header-simulator-cxx.h"

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
// expected-no-diagnostics
typedef signed char BOOL;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=text -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=plist-multi-file %s -o %t.plist
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file %s -o %t.plist
// RUN: FileCheck --input-file=%t.plist %s
// Test warning about null or uninitialized pointer values used as instance member

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-config c++-inlining=constructors -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-ipa=inlining -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-ipa=inlining -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
// Test basic handling of references.
char &test1_aux();

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
void clang_analyzer_eval(bool);
struct X0 { };

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-ipa=none -analyzer-store=region -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-config ipa=none -analyzer-store=region -verify %s
typedef const struct __CFString * CFStringRef;
typedef const struct __CFAllocator * CFAllocatorRef;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
void clang_analyzer_eval(bool);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -analyzer-ipa=dynamic -fno-builtin %s -verify
// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -analyzer-config ipa=dynamic -fno-builtin %s -verify
// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -fno-builtin %s -verify
@class NSZone, NSCoder;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify -w %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s
struct Trivial {
Trivial(int x) : value(x) {}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-ipa=inlining -analyzer-eagerly-assume -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -fblocks -verify -o %t.plist
// RUN: FileCheck --input-file=%t.plist %s
struct _opaque_pthread_once_t {