From 0ebdd369b018edb28e9cc79abbf21dbeb9dda8f3 Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Tue, 5 Dec 2017 08:36:39 -0800 Subject: [PATCH] [liveness] don't warn on dead stores of type CKComponentScope Summary: Local `CKComponentScope`'s are often created purely for their side effects, so it's fine for them to be unread. Reviewed By: jeremydubreil Differential Revision: D6475475 fbshipit-source-id: 17e869a --- infer/src/checkers/liveness.ml | 7 ++++-- .../objc/liveness/CoreFoundationExample.m | 25 +++++++++++++++++++ .../codetoanalyze/objc/liveness/Makefile | 2 +- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/infer/src/checkers/liveness.ml b/infer/src/checkers/liveness.ml index 6a1369b6a..83e94bdbc 100644 --- a/infer/src/checkers/liveness.ml +++ b/infer/src/checkers/liveness.ml @@ -103,13 +103,15 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = in let matcher_scope_guard = QualifiedCppName.Match.of_fuzzy_qual_names - [ "folly::RWSpinLock::ReadHolder" + [ (* C++ *) + "folly::RWSpinLock::ReadHolder" ; "folly::RWSpinLock::WriteHolder" ; "folly::SpinLockGuard" ; "folly::ScopeGuard" ; "std::lock_guard" ; "std::scoped_lock" - ; "std::unique_lock" ] + ; "std::unique_lock" (* Obj-C *) + ; "CKComponentScope" ] in (* It's fine to have a dead store on a type that uses the "scope guard" pattern. These types are only read in their destructors, and this is expected/ok. @@ -160,3 +162,4 @@ let checker {Callbacks.tenv; summary; proc_desc} : Specs.summary = in List.iter (CFG.nodes cfg) ~f:report_on_node ; summary + diff --git a/infer/tests/codetoanalyze/objc/liveness/CoreFoundationExample.m b/infer/tests/codetoanalyze/objc/liveness/CoreFoundationExample.m index 32f0a1750..5e3655a62 100644 --- a/infer/tests/codetoanalyze/objc/liveness/CoreFoundationExample.m +++ b/infer/tests/codetoanalyze/objc/liveness/CoreFoundationExample.m @@ -15,3 +15,28 @@ static NSDictionary* dictionaryRepresentationFromCFPreferences( return (__bridge_transfer NSDictionary*)CFPreferencesCopyMultiple( NULL, ID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); } + +// mock for testing +class CKComponentScope { + public: + CKComponentScope(Class __unsafe_unretained componentClass, + id identifier = nil, + id (^initialStateCreator)(void) = nil); + ~CKComponentScope(); + int a; + + private: + CKComponentScope(const CKComponentScope&) = delete; + CKComponentScope& operator=(const CKComponentScope&) = delete; +}; + +@interface ScopeTest : NSObject +@end + +@implementation ScopeTest + ++ (void)dead_ckcomponentscope_ok { + CKComponentScope scope(self); // created for side effects; should not warn +} + +@end diff --git a/infer/tests/codetoanalyze/objc/liveness/Makefile b/infer/tests/codetoanalyze/objc/liveness/Makefile index 9ace83b1f..f16c7bbea 100644 --- a/infer/tests/codetoanalyze/objc/liveness/Makefile +++ b/infer/tests/codetoanalyze/objc/liveness/Makefile @@ -8,7 +8,7 @@ TESTS_DIR = ../../.. ANALYZER = checkers -CLANG_OPTIONS = -x objective-c -c +CLANG_OPTIONS = -x objective-c++ -std=c++11 -fobjc-arc -c INFER_OPTIONS = --liveness-only --debug-exceptions --project-root $(TESTS_DIR) INFERPRINT_OPTIONS = --issues-tests