Skip to content
Snippets Groups Projects
Commit 99c06be6 authored by Ted Kremenek's avatar Ted Kremenek
Browse files

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150896 91177308-0d34-0410-b5e6-96231b3b80d8
parent 86024013
No related branches found
No related tags found
No related merge requests found
...@@ -690,18 +690,24 @@ const BlockDataRegion * ...@@ -690,18 +690,24 @@ const BlockDataRegion *
MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
const LocationContext *LC) { const LocationContext *LC) {
const MemRegion *sReg = 0; const MemRegion *sReg = 0;
const BlockDecl *BD = BC->getDecl();
if (LC) { if (!BD->hasCaptures()) {
// FIXME: Once we implement scope handling, we want the parent region // This handles 'static' blocks.
// to be the scope. sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind);
const StackFrameContext *STC = LC->getCurrentStackFrame();
assert(STC);
sReg = getStackLocalsRegion(STC);
} }
else { else {
// We allow 'LC' to be NULL for cases where want BlockDataRegions if (LC) {
// without context-sensitivity. // FIXME: Once we implement scope handling, we want the parent region
sReg = getUnknownRegion(); // 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); return getSubRegion<BlockDataRegion>(BC, LC, sReg);
......
...@@ -57,8 +57,15 @@ int struct_test(struct baz byVal, int flag) { ...@@ -57,8 +57,15 @@ int struct_test(struct baz byVal, int flag) {
typedef int (^ComparatorBlock)(int a, int b); typedef int (^ComparatorBlock)(int a, int b);
ComparatorBlock test_return_block(void) { 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; }; 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); ComparatorBlock test_return_block_neg_aux(void);
...@@ -73,4 +80,13 @@ int *rdar_7523821_f2() { ...@@ -73,4 +80,13 @@ int *rdar_7523821_f2() {
return a; // expected-warning 2 {{ddress of stack memory associated with local variable 'a' returned}} 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
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment