From e9812bdac5c678e635fde0b056087cea89589e06 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 18 Jul 2009 06:27:51 +0000 Subject: [PATCH] Fix crash in StoreManager::NewCastRegion() when handling casts from 'id' (or whatever) to a BlockPointerType. llvm-svn: 76288 --- clang/lib/Analysis/Store.cpp | 22 ++++++++++++++++++++-- clang/test/Analysis/misc-ps.m | 7 +++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/Store.cpp b/clang/lib/Analysis/Store.cpp index b939a0df9ca7..bd46a68d0135 100644 --- a/clang/lib/Analysis/Store.cpp +++ b/clang/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(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/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index 503352b6f71d..862709cc7d7e 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/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}} +} +