]> granicus.if.org Git - clang/commitdiff
[analyzer] Fix the checker for the performance anti-pattern to accept messages
authorGeorge Karpenkov <ekarpenkov@apple.com>
Wed, 7 Mar 2018 02:54:01 +0000 (02:54 +0000)
committerGeorge Karpenkov <ekarpenkov@apple.com>
Wed, 7 Mar 2018 02:54:01 +0000 (02:54 +0000)
send to ObjC objects.

Differential Revision: https://reviews.llvm.org/D44170

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326868 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/GCDAsyncSemaphoreChecker.cpp
test/Analysis/gcdasyncsemaphorechecker_test.m

index 23ef032bb0549ebdbbb7819fb42931d5e19a1856..eda7a5fcd172c991aa4234628dfb163708fb90c4 100644 (file)
@@ -111,23 +111,26 @@ void GCDAsyncSemaphoreChecker::checkASTCodeBody(const Decl *D,
       )
     ).bind(WarningBinding));
 
-  auto AcceptsBlockM =
-    forEachDescendant(callExpr(hasAnyArgument(hasType(
+  auto HasBlockArgumentM = hasAnyArgument(hasType(
             hasCanonicalType(blockPointerType())
-            ))));
+            ));
 
-  auto BlockSignallingM =
-    forEachDescendant(callExpr(hasAnyArgument(hasDescendant(callExpr(
+  auto ArgCallsSignalM = hasArgument(0, hasDescendant(callExpr(
           allOf(
               callsName("dispatch_semaphore_signal"),
               equalsBoundArgDecl(0, SemaphoreBinding)
-              ))))));
+              ))));
+
+  auto HasBlockAndCallsSignalM = allOf(HasBlockArgumentM, ArgCallsSignalM);
+
+  auto AcceptsBlockM =
+    forEachDescendant(
+      stmt(anyOf(
+        callExpr(HasBlockAndCallsSignalM),
+        objcMessageExpr(HasBlockAndCallsSignalM)
+           )));
 
-  auto FinalM = compoundStmt(
-      SemaphoreBindingM,
-      SemaphoreWaitM,
-      AcceptsBlockM,
-      BlockSignallingM);
+  auto FinalM = compoundStmt(SemaphoreBindingM, SemaphoreWaitM, AcceptsBlockM);
 
   MatchFinder F;
   Callback CB(BR, AM.getAnalysisDeclContext(D), this);
index a82545a3b6a7ff32140bffe00fb5a35a89b7f621..ff434d3652dc96be2e9ef2b56f564ed8e7c6f88a 100644 (file)
@@ -177,7 +177,9 @@ void warn_with_cast() {
 
 @interface Test1 : NSObject
 -(void)use_method_warn;
+-(void)use_objc_callback_warn;
 -(void)testNoWarn;
+-(void)acceptBlock:(block_t)callback;
 @end
 
 @implementation Test1
@@ -200,4 +202,33 @@ void warn_with_cast() {
   dispatch_semaphore_wait(sema, 100);
 }
 
+-(void)acceptBlock:(block_t) callback {
+  callback();
+}
+
+-(void)use_objc_callback_warn {
+  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
+
+  [self acceptBlock:^{
+      dispatch_semaphore_signal(sema);
+  }];
+  dispatch_semaphore_wait(sema, 100); // expected-warning{{Possible semaphore performance anti-pattern}}
+}
+
+void use_objc_and_c_callback(Test1 *t) {
+  dispatch_semaphore_t sema = dispatch_semaphore_create(0);
+
+  func(^{
+      dispatch_semaphore_signal(sema);
+  });
+  dispatch_semaphore_wait(sema, 100); // expected-warning{{Possible semaphore performance anti-pattern}}
+
+  dispatch_semaphore_t sema1 = dispatch_semaphore_create(0);
+
+  [t acceptBlock:^{
+      dispatch_semaphore_signal(sema1);
+  }];
+  dispatch_semaphore_wait(sema1, 100); // expected-warning{{Possible semaphore performance anti-pattern}}
+}
+
 @end