[analyzer] Add an option to enable/disable objc inlining.

llvm-svn: 163562
This commit is contained in:
Anna Zaks 2012-09-10 22:56:41 +00:00
parent 38e05a9eb2
commit 5446f4dfb1
4 changed files with 51 additions and 3 deletions

View File

@ -178,6 +178,9 @@ private:
/// \sa mayInlineTemplateFunctions
llvm::Optional<bool> InlineTemplateFunctions;
/// \sa mayInlineObjCMethod
llvm::Optional<bool> ObjCInliningMode;
// Cache of the "ipa-always-inline-size" setting.
// \sa getAlwaysInlineSize
llvm::Optional<unsigned> AlwaysInlineSize;
@ -200,6 +203,9 @@ public:
/// \sa CXXMemberInliningMode
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
/// Returns true if ObjectiveC inlining is enabled, false otherwise.
bool mayInlineObjCMethod() const;
/// Returns whether or not the destructors for C++ temporary objects should
/// be included in the CFG.
///

View File

@ -82,6 +82,14 @@ bool AnalyzerOptions::mayInlineTemplateFunctions() const {
return *InlineTemplateFunctions;
}
bool AnalyzerOptions::mayInlineObjCMethod() const {
if (!ObjCInliningMode.hasValue())
const_cast<llvm::Optional<bool> &>(ObjCInliningMode) =
getBooleanOption("objc-inlining", /*Default=*/true);
return *ObjCInliningMode;
}
int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) const {
std::string OptStr = Config.lookup(Name);
if (OptStr.empty())
@ -97,9 +105,8 @@ int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) const {
unsigned AnalyzerOptions::getAlwaysInlineSize() const {
if (!AlwaysInlineSize.hasValue()) {
unsigned DefaultSize = 3;
Optional<unsigned> &MutableOption =
const_cast<Optional<unsigned> &>(AlwaysInlineSize);
MutableOption = getOptionAsInteger("ipa-always-inline-size", DefaultSize);
const_cast<Optional<unsigned> &>(AlwaysInlineSize) =
getOptionAsInteger("ipa-always-inline-size", DefaultSize);
}
return AlwaysInlineSize.getValue();

View File

@ -448,6 +448,8 @@ bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
break;
}
case CE_ObjCMessage:
if (!Opts.mayInlineObjCMethod())
return false;
if (!(getAnalysisManager().options.IPAMode == DynamicDispatch ||
getAnalysisManager().options.IPAMode == DynamicDispatchBifurcate))
return false;

View File

@ -0,0 +1,33 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
typedef signed char BOOL;
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
@protocol NSObject - (BOOL)isEqual:(id)object; @end
@interface NSObject <NSObject> {}
+(id)alloc;
-(id)init;
-(id)autorelease;
-(id)copy;
- (Class)class;
-(id)retain;
@end
// Vanila: ObjC class method is called by name.
@interface MyParent : NSObject
+ (int)getInt;
@end
@interface MyClass : MyParent
+ (int)getInt;
@end
@implementation MyClass
+ (int)testClassMethodByName {
int y = [MyClass getInt];
return 5/y; // no-warning
}
+ (int)getInt {
return 0;
}
@end