Teach analyzer that blocks with no captures are globals. Fixes <rdar://problem/10348049>.
llvm-svn: 150896
This commit is contained in:
parent
66c9699ac3
commit
1c95ef4e94
|
@ -690,18 +690,24 @@ const BlockDataRegion *
|
|||
MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
|
||||
const LocationContext *LC) {
|
||||
const MemRegion *sReg = 0;
|
||||
|
||||
if (LC) {
|
||||
// FIXME: Once we implement scope handling, we want the parent region
|
||||
// to be the scope.
|
||||
const StackFrameContext *STC = LC->getCurrentStackFrame();
|
||||
assert(STC);
|
||||
sReg = getStackLocalsRegion(STC);
|
||||
const BlockDecl *BD = BC->getDecl();
|
||||
if (!BD->hasCaptures()) {
|
||||
// This handles 'static' blocks.
|
||||
sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
|
||||
}
|
||||
else {
|
||||
// We allow 'LC' to be NULL for cases where want BlockDataRegions
|
||||
// without context-sensitivity.
|
||||
sReg = getUnknownRegion();
|
||||
if (LC) {
|
||||
// FIXME: Once we implement scope handling, we want the parent region
|
||||
// to be the scope.
|
||||
const StackFrameContext *STC = LC->getCurrentStackFrame();
|
||||
assert(STC);
|
||||
sReg = getStackLocalsRegion(STC);
|
||||
}
|
||||
else {
|
||||
// We allow 'LC' to be NULL for cases where want BlockDataRegions
|
||||
// without context-sensitivity.
|
||||
sReg = getUnknownRegion();
|
||||
}
|
||||
}
|
||||
|
||||
return getSubRegion<BlockDataRegion>(BC, LC, sReg);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue