Teach analyzer that blocks with no captures are globals. Fixes <rdar://problem/10348049>.

llvm-svn: 150896
This commit is contained in:
Ted Kremenek 2012-02-18 22:41:01 +00:00
parent 66c9699ac3
commit 1c95ef4e94
2 changed files with 33 additions and 11 deletions

View File

@ -690,7 +690,12 @@ const BlockDataRegion *
MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
const LocationContext *LC) {
const MemRegion *sReg = 0;
const BlockDecl *BD = BC->getDecl();
if (!BD->hasCaptures()) {
// This handles 'static' blocks.
sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
}
else {
if (LC) {
// FIXME: Once we implement scope handling, we want the parent region
// to be the scope.
@ -703,6 +708,7 @@ MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
// without context-sensitivity.
sReg = getUnknownRegion();
}
}
return getSubRegion<BlockDataRegion>(BC, LC, sReg);
}

View File

@ -57,8 +57,15 @@ int struct_test(struct baz byVal, int flag) {
typedef int (^ComparatorBlock)(int a, int b);
ComparatorBlock test_return_block(void) {
// This block is a global since it has no captures.
ComparatorBlock b = ^int(int a, int b){ return a > b; };
return b; // expected-warning{{Address of stack-allocated block declared on line 60 returned to caller}}
return b; // no-warning
}
ComparatorBlock test_return_block_with_capture(int x) {
// This block is stack allocated because it has captures.
ComparatorBlock b = ^int(int a, int b){ return a > b + x; };
return b; // expected-warning{{Address of stack-allocated block}}
}
ComparatorBlock test_return_block_neg_aux(void);
@ -73,4 +80,13 @@ int *rdar_7523821_f2() {
return a; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}}
};
// Handle blocks that have no captures or are otherwise declared 'static'.
// <rdar://problem/10348049>
typedef int (^RDar10348049)(int value);
RDar10348049 test_rdar10348049(void) {
static RDar10348049 b = ^int(int x) {
return x + 2;
};
return b; // no-warning
}