diff options
author | Anna Zaks <ganna@apple.com> | 2012-09-10 22:56:41 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-09-10 22:56:41 +0000 |
commit | 57330eed3fbe530cb05996e4a346cc5fc217c0d9 (patch) | |
tree | 2559abcdffadb7bce36fd6470d26df923f145ef7 | |
parent | 8a198a078e22665deb0a442eb6ba187a230f733a (diff) |
[analyzer] Add an option to enable/disable objc inlining.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163562 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/StaticAnalyzer/Core/AnalyzerOptions.h | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 13 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 2 | ||||
-rw-r--r-- | test/Analysis/inlining/test_objc_inlining_option.m | 33 |
4 files changed, 51 insertions, 3 deletions
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 72e614d3e7..718f54c75a 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -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. /// diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 5cbbb8d462..9e029c7e29 100644 --- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -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(); diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index a4e1eb2f4c..54c66d37ba 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -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; diff --git a/test/Analysis/inlining/test_objc_inlining_option.m b/test/Analysis/inlining/test_objc_inlining_option.m new file mode 100644 index 0000000000..963b572b1e --- /dev/null +++ b/test/Analysis/inlining/test_objc_inlining_option.m @@ -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
\ No newline at end of file |