From b2d0409d5054e7e21173935d13eaf16a7655bb82 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 22 Jul 2009 04:23:20 +0000 Subject: [PATCH] Fix a crasher in StoreManager::InvalidateRegion() caused by using the 'cast type' of a region to invalidate its binding. This only occurs when using RegionStoreManager, as it records the cast type. I'm currently considering removing the notion of a cast type (see comments in code). llvm-svn: 76719 --- clang/lib/Analysis/Store.cpp | 8 ++++++++ clang/test/Analysis/misc-ps.m | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/clang/lib/Analysis/Store.cpp b/clang/lib/Analysis/Store.cpp index bd46a68..bddf054 100644 --- a/clang/lib/Analysis/Store.cpp +++ b/clang/lib/Analysis/Store.cpp @@ -258,6 +258,13 @@ const GRState *StoreManager::InvalidateRegion(const GRState *state, const TypedRegion *TR = cast(R); QualType T = TR->getValueType(Ctx); + // FIXME: The code causes a crash when using RegionStore on the test case + // 'test_invalidate_cast_int' (misc-ps.m). Consider removing it + // permanently. Region casts are probably not too strict to handle + // the transient interpretation of memory. Instead we can use the QualType + // passed to 'Retrieve' and friends to determine the most current + // interpretation of memory when it is actually used. +#if 0 // If the region is cast to another type, use that type. if (const QualType *CastTy = getCastType(state, R)) { assert(!(*CastTy)->isObjCObjectPointerType()); @@ -270,6 +277,7 @@ const GRState *StoreManager::InvalidateRegion(const GRState *state, if (!(Loc::IsLocType(T) && !Loc::IsLocType(NewT))) T = NewT; } +#endif if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { SVal V = ValMgr.getConjuredSymbolVal(E, T, Count); diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index de39a00..e2c0e05 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/test/Analysis/misc-ps.m @@ -459,3 +459,14 @@ void PR4594() { char **foo = buf; *foo = "test"; } + +// Test invalidation logic where an integer is casted to an array with a +// different sign and then invalidated. +void test_invalidate_cast_int() { + void test_invalidate_cast_int_aux(unsigned *i); + signed i; + test_invalidate_cast_int_aux((unsigned*) &i); + if (i < 0) + return; +} + -- 2.7.4