[analyzer] Add an option to enable/disable objc inlining.
llvm-svn: 163562
This commit is contained in:
parent
38e05a9eb2
commit
5446f4dfb1
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue