Author: dergachev Date: Mon Oct 31 16:04:54 2016 New Revision: 285637 URL: http://llvm.org/viewvc/llvm-project?rev=285637&view=rev Log: [analyzer] MacOSXAPIChecker: Improve warnings for __block vars in dispatch_once.
The checker already warns for __block-storage variables being used as a dispatch_once() predicate, however it refers to them as local which is not quite accurate, so we fix that. Differential Revision: https://reviews.llvm.org/D26159 Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp cfe/trunk/test/Analysis/dispatch-once.m Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp?rev=285637&r1=285636&r2=285637&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp Mon Oct 31 16:04:54 2016 @@ -94,10 +94,15 @@ void MacOSXAPIChecker::CheckDispatchOnce bool SuggestStatic = false; os << "Call to '" << FName << "' uses"; if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) { - // We filtered out globals earlier, so it must be a local variable. + // We filtered out globals earlier, so it must be a local variable + // or a block variable which is under UnknownSpaceRegion. if (VR != R) os << " memory within"; - os << " the local variable '" << VR->getDecl()->getName() << '\''; + if (VR->getDecl()->hasAttr<BlocksAttr>()) + os << " the block variable '"; + else + os << " the local variable '"; + os << VR->getDecl()->getName() << '\''; SuggestStatic = true; } else if (const ObjCIvarRegion *IVR = getParentIvarRegion(R)) { if (IVR != R) @@ -108,6 +113,9 @@ void MacOSXAPIChecker::CheckDispatchOnce } else if (isa<UnknownSpaceRegion>(RS)) { // Presence of an IVar superregion has priority over this branch, because // ObjC objects are on the heap even if the core doesn't realize this. + // Presence of a block variable base region has priority over this branch, + // because block variables are known to be either on stack or on heap + // (might actually move between the two, hence UnknownSpace). return; } else { os << " stack allocated memory"; Modified: cfe/trunk/test/Analysis/dispatch-once.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dispatch-once.m?rev=285637&r1=285636&r2=285637&view=diff ============================================================================== --- cfe/trunk/test/Analysis/dispatch-once.m (original) +++ cfe/trunk/test/Analysis/dispatch-once.m Mon Oct 31 16:04:54 2016 @@ -90,3 +90,20 @@ void test_ivar_struct_from_external_obj( void test_ivar_array_from_external_obj(Object *o) { dispatch_once(&o->once_array[1], ^{}); // expected-warning{{Call to 'dispatch_once' uses memory within the instance variable 'once_array' for the predicate value.}} } + +void test_block_var_from_block() { + __block dispatch_once_t once; + ^{ + dispatch_once(&once, ^{}); // expected-warning{{Call to 'dispatch_once' uses the block variable 'once' for the predicate value.}} + }; +} + +void use_block_var(dispatch_once_t *once); + +void test_block_var_from_outside_block() { + __block dispatch_once_t once; + ^{ + use_block_var(&once); + }; + dispatch_once(&once, ^{}); // expected-warning{{Call to 'dispatch_once' uses the block variable 'once' for the predicate value.}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits