[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