aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-09-10 22:56:41 +0000
committerAnna Zaks <ganna@apple.com>2012-09-10 22:56:41 +0000
commit57330eed3fbe530cb05996e4a346cc5fc217c0d9 (patch)
tree2559abcdffadb7bce36fd6470d26df923f145ef7
parent8a198a078e22665deb0a442eb6ba187a230f733a (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.h6
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp13
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp2
-rw-r--r--test/Analysis/inlining/test_objc_inlining_option.m33
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