From: Ted Kremenek Date: Mon, 4 May 2009 06:35:49 +0000 (+0000) Subject: Handle 'long x = 0; char *y = (char *) x;' by layering an X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fd6b4f3de2ef7bb7b9b33dd252078c53ada43977;p=clang Handle 'long x = 0; char *y = (char *) x;' by layering an 'ElementRegion' on top of the VarRegion for 'x'. This causes the test case xfail_wine_crash.c to now pass for BasicStoreManager. It doesn't crash for RegionStoreManager either, but reports a bogus unintialized value warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70832 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp index 65e90dec33..e9b8f6a27f 100644 --- a/lib/Analysis/Store.cpp +++ b/lib/Analysis/Store.cpp @@ -23,7 +23,7 @@ StoreManager::StoreManager(GRStateManager &stateMgr) StoreManager::CastResult StoreManager::CastRegion(const GRState* state, const MemRegion* R, - QualType CastToTy) { + QualType CastToTy) { ASTContext& Ctx = StateMgr.getContext(); @@ -38,10 +38,11 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R, return CastResult(state, R); } - // Check if we are casting to 'void*'. - // FIXME: Handle arbitrary upcasts. - if (const PointerType* PTy = dyn_cast(ToTy.getTypePtr())) - if (PTy->getPointeeType()->isVoidType()) { + if (const PointerType* PTy = dyn_cast(ToTy.getTypePtr())) { + // Check if we are casting to 'void*'. + // FIXME: Handle arbitrary upcasts. + QualType Pointee = PTy->getPointeeType(); + if (Pointee->isVoidType()) { // Casts to void* only removes TypedViewRegion. If there is no // TypedViewRegion, leave the region untouched. This happens when: @@ -58,6 +59,20 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R, return CastResult(state, R); } + else if (Pointee->isIntegerType()) { + // FIXME: At some point, it stands to reason that this 'dyn_cast' should + // become a 'cast' and that 'R' will always be a TypedRegion. + if (const TypedRegion *TR = dyn_cast(R)) { + // Check if we are casting to a region with an integer type. We now + // the types aren't the same, so we construct an ElementRegion. + // FIXME: We should have a standard query function to get the size + // of the array index. + SVal Idx = ValMgr.makeZeroVal(ValMgr.getContext().VoidPtrTy); + ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, TR); + return CastResult(state, ER); + } + } + } // FIXME: Need to handle arbitrary downcasts. // FIXME: Handle the case where a TypedViewRegion (layering a SymbolicRegion diff --git a/test/Analysis/basicstore_wine_crash.c b/test/Analysis/basicstore_wine_crash.c new file mode 100644 index 0000000000..cb5fac8d29 --- /dev/null +++ b/test/Analysis/basicstore_wine_crash.c @@ -0,0 +1,11 @@ +// RUN: clang-cc -checker-cfref -analyze -analyzer-store=basic %s + +// Once xfail_regionstore_wine_crash.c passes, move this test case +// into misc-ps.m. + +void foo() { + long x = 0; + char *y = (char *) &x; + if (!*y) + return; +} diff --git a/test/Analysis/xfail_wine_crash.c b/test/Analysis/xfail_regionstore_wine_crash.c similarity index 100% rename from test/Analysis/xfail_wine_crash.c rename to test/Analysis/xfail_regionstore_wine_crash.c