From e95db4f2cd3ed4825a179bd7f151a5fc86b38e6f Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 24 Nov 2008 19:35:33 +0000 Subject: [PATCH] Fix crash of array bounds checking under 64-bit. There might be other, similar bugs lurking there. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59974 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/BasicConstraintManager.cpp | 10 ++++++++-- lib/Analysis/RegionStore.cpp | 9 ++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/Analysis/BasicConstraintManager.cpp b/lib/Analysis/BasicConstraintManager.cpp index a359b23c54..6f62c4ba77 100644 --- a/lib/Analysis/BasicConstraintManager.cpp +++ b/lib/Analysis/BasicConstraintManager.cpp @@ -369,8 +369,14 @@ BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx, } const llvm::APSInt& Zero = getBasicVals().getZeroWithPtrWidth(false); - const llvm::APSInt& IdxV = cast(Idx).getValue(); - const llvm::APSInt& UBV = cast(UpperBound).getValue(); + llvm::APSInt IdxV = cast(Idx).getValue(); + // IdxV might be too narrow. + if (IdxV.getBitWidth() < Zero.getBitWidth()) + IdxV.extend(Zero.getBitWidth()); + // UBV might be too narrow, too. + llvm::APSInt UBV = cast(UpperBound).getValue(); + if (UBV.getBitWidth() < Zero.getBitWidth()) + UBV.extend(Zero.getBitWidth()); bool InBound = (Zero <= IdxV) && (IdxV < UBV); diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 9a1f3eca34..747b16d7b6 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -254,12 +254,15 @@ SVal RegionStoreManager::getLValueElement(const GRState* St, if ((CI1 = dyn_cast(&Idx)) && (CI2 = dyn_cast(&Offset))) { - // Temporary SVal to hold a potential signed APSInt. + // Temporary SVal to hold a potential signed and extended APSInt. SVal SignedInt; - // Index might be unsigned. We have to convert it to signed. - if (CI2->getValue().isUnsigned()) { + // Index might be unsigned. We have to convert it to signed. It might also + // be less wide than the size. We have to extend it. + if (CI2->getValue().isUnsigned() || + CI2->getValue().getBitWidth() < CI1->getValue().getBitWidth()) { llvm::APSInt SI = CI2->getValue(); + SI.extend(CI1->getValue().getBitWidth()); SI.setIsSigned(true); SignedInt = nonloc::ConcreteInt(getBasicVals().getValue(SI)); CI2 = cast(&SignedInt); -- 2.40.0