From 4552ff080062cacc4b57906e6f2f09e9d796b6a4 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 30 Mar 2010 20:31:04 +0000 Subject: [PATCH] RegionStore: specially handle loads from integer global variables declared 'const'. Fixes a false positive reported in PR 6288. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99922 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Checker/RegionStore.cpp | 17 +++++++++++++- test/Analysis/misc-ps-region-store.m | 35 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp index 26d33f6588..d590a86a81 100644 --- a/lib/Checker/RegionStore.cpp +++ b/lib/Checker/RegionStore.cpp @@ -1313,8 +1313,23 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) { return ValMgr.getRegionValueSymbolVal(R); if (isa(MS)) { - if (VD->isFileVarDecl()) + if (VD->isFileVarDecl()) { + // Is 'VD' declared constant? If so, retrieve the constant value. + QualType CT = Ctx.getCanonicalType(T); + if (CT.isConstQualified()) { + const Expr *Init = VD->getInit(); + // Do the null check first, as we want to call 'IgnoreParenCasts'. + if (Init) + if (const IntegerLiteral *IL = + dyn_cast(Init->IgnoreParenCasts())) { + const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL); + return ValMgr.getSValuator().EvalCast(V, Init->getType(), + IL->getType()); + } + } + return ValMgr.getRegionValueSymbolVal(R); + } if (T->isIntegerType()) return ValMgr.makeIntVal(0, T); diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index b95d82f763..d10b9fa5de 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -920,3 +920,38 @@ void pr6302(id x, Class y) { // This previously crashed the analyzer (reported in PR 6302) x->isa = y; } + +//===----------------------------------------------------------------------===// +// Specially handle global variables that are declared constant. In the +// example below, this forces the loop to take exactly 2 iterations. +//===----------------------------------------------------------------------===// + +const int pr6288_L_N = 2; +void pr6288_(void) { + int x[2]; + int *px[2]; + int i; + for (i = 0; i < pr6288_L_N; i++) + px[i] = &x[i]; + *(px[0]) = 0; // no-warning +} + +void pr6288_pos(int z) { + int x[2]; + int *px[2]; + int i; + for (i = 0; i < z; i++) + px[i] = &x[i]; // expected-warning{{Access out-of-bound array element (buffer overflow)}} + *(px[0]) = 0; // expected-warning{{Dereference of undefined pointer value}} +} + +void pr6288_b(void) { + const int L_N = 2; + int x[2]; + int *px[2]; + int i; + for (i = 0; i < L_N; i++) + px[i] = &x[i]; + *(px[0]) = 0; // no-warning +} + -- 2.40.0