diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-07-18 06:27:51 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-07-18 06:27:51 +0000 |
commit | 63b9cfe8f2aaec53710b59e565bb8d5afb558b40 (patch) | |
tree | 3c7d573cf902a49b55dc4891fb41aaa14df67272 | |
parent | 675bef616e51b502819fd4586ab297b58e04280f (diff) |
Fix crash in StoreManager::NewCastRegion() when handling casts from 'id' (or whatever) to a BlockPointerType.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76288 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/Store.cpp | 22 | ||||
-rw-r--r-- | test/Analysis/misc-ps.m | 7 |
2 files changed, 27 insertions, 2 deletions
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp index b939a0df9c..bd46a68d01 100644 --- a/lib/Analysis/Store.cpp +++ b/lib/Analysis/Store.cpp @@ -59,6 +59,23 @@ StoreManager::NewCastRegion(const GRState *state, const MemRegion* R, state = setCastType(state, R, CastToTy); return CastResult(state, R); } + + if (CastToTy->isBlockPointerType()) { + if (isa<CodeTextRegion>(R)) + return CastResult(state, R); + + // FIXME: This may not be the right approach, depending on the symbol + // involved. Blocks can be casted to/from 'id', as they can be treated + // as Objective-C objects. + if (SymbolRef sym = loc::MemRegionVal(R).getAsSymbol()) { + R = MRMgr.getCodeTextRegion(sym, CastToTy); + return CastResult(state, R); + } + + // We don't know what to make of it. Return a NULL region, which + // will be interpretted as UnknownVal. + return CastResult(state, NULL); + } // Now assume we are casting from pointer to pointer. Other cases should // already be handled. @@ -77,8 +94,9 @@ StoreManager::NewCastRegion(const GRState *state, const MemRegion* R, } case MemRegion::CodeTextRegionKind: { - // CodeTextRegion should be cast to only function pointer type, although - // they can in practice be casted to anything, e.g, void*, char*, etc. + // CodeTextRegion should be cast to only a function or block pointer type, + // although they can in practice be casted to anything, e.g, void*, + // char*, etc. // Just pass the region through. break; } diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m index 503352b6f7..862709cc7d 100644 --- a/test/Analysis/misc-ps.m +++ b/test/Analysis/misc-ps.m @@ -430,3 +430,10 @@ unsigned char test_array_index_bitwidth(const unsigned char *p) { return p[i+1]; } +// This case tests that CastRegion handles casts involving BlockPointerTypes. +// It should not crash. +void test_block_cast() { + id test_block_cast_aux(); + (void (^)(void *))test_block_cast_aux(); // expected-warning{{expression result unused}} +} + |