[cfe-commits] r163816 - in /cfe/trunk: lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp test/Analysis/unix-fns.c

Ted Kremenek kremenek at apple.com
Thu Sep 13 11:18:37 PDT 2012


Author: kremenek
Date: Thu Sep 13 13:18:37 2012
New Revision: 163816

URL: http://llvm.org/viewvc/llvm-project?rev=163816&view=rev
Log:
When warning about unsafe uses of dispatch_once, specially handle the
crazy case where dispatch_once gets redefined as a macro that calls
_dispatch_once (which calls the real dispatch_once).  Users want to
see the warning in their own code.

Fixes <rdar://problem/11617767>

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
    cfe/trunk/test/Analysis/unix-fns.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp?rev=163816&r1=163815&r2=163816&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp Thu Sep 13 13:18:37 2012
@@ -70,6 +70,16 @@
     BT_dispatchOnce.reset(new BugType("Improper use of 'dispatch_once'",
                                       "Mac OS X API"));
 
+  // Handle _dispatch_once, which in some versions of the OS X SDK that
+  // dispatch_once is a macro that wraps a call to _dispatch_once, which
+  // then calls the real dispatch_once.  Users do not care; they just
+  // want the warning at the top-level call.
+  if (CE->getLocStart().isMacroID()) {
+    StringRef TrimmedFName = FName.ltrim("_");
+    if (TrimmedFName != FName)
+      FName = TrimmedFName;
+  }
+  
   SmallString<256> S;
   llvm::raw_svector_ostream os(S);
   os << "Call to '" << FName << "' uses";
@@ -99,7 +109,9 @@
 
   SubChecker SC =
     llvm::StringSwitch<SubChecker>(Name)
-      .Cases("dispatch_once", "dispatch_once_f",
+      .Cases("dispatch_once",
+             "_dispatch_once",
+             "dispatch_once_f",
              &MacOSXAPIChecker::CheckDispatchOnce)
       .Default(NULL);
 

Modified: cfe/trunk/test/Analysis/unix-fns.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unix-fns.c?rev=163816&r1=163815&r2=163816&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/unix-fns.c (original)
+++ cfe/trunk/test/Analysis/unix-fns.c Thu Sep 13 13:18:37 2012
@@ -136,3 +136,18 @@
     foo[i] = 0;
   }
 }
+
+// Test dispatch_once being a macro that wraps a call to _dispatch_once, which in turn
+// calls the real dispatch_once.
+
+static inline void _dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)
+{
+  dispatch_once(predicate, block);
+}
+
+#define dispatch_once _dispatch_once
+
+void test_dispatch_once_in_macro() {
+  dispatch_once_t pred = 0;
+  dispatch_once(&pred, ^(){});  // expected-warning {{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
+}





More information about the cfe-commits mailing list