Skip to content

Commit

Permalink
[analyzer] MacOSXAPIChecker: Improve warnings for __block vars in dis…
Browse files Browse the repository at this point in the history
…patch_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

llvm-svn: 285637
  • Loading branch information
haoNoQ committed Oct 31, 2016
1 parent 56e6135 commit a21df23
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
12 changes: 10 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
Expand Up @@ -94,10 +94,15 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
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)
Expand All @@ -108,6 +113,9 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
} 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";
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Analysis/dispatch-once.m
Expand Up @@ -90,3 +90,20 @@ void test_ivar_struct_from_external_obj(Object *o) {
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.}}
}

0 comments on commit a21df23

Please sign in to comment.