Always assume block-level expressions in the caller are alive when analyzing

the callee.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100429 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zhongxing Xu 2010-04-05 13:16:29 +00:00
Родитель b3e485c835
Коммит 7b73b92870
2 изменённых файлов: 43 добавлений и 2 удалений

Просмотреть файл

@ -96,6 +96,19 @@ public:
};
} // end anonymous namespace
static bool isBlockExprInCallers(const Stmt *E, const LocationContext *LC) {
const LocationContext *ParentLC = LC->getParent();
while (ParentLC) {
CFG &C = *ParentLC->getCFG();
if (C.isBlkExpr(E))
return true;
ParentLC = ParentLC->getParent();
}
return false;
}
// RemoveDeadBindings:
// - Remove subexpression bindings.
// - Remove dead block expression bindings.
@ -122,13 +135,27 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, const Stmt *S,
I != E; ++I) {
const Stmt *BlkExpr = I.getKey();
const SVal &X = I.getData();
// Block-level expressions in callers are assumed always live.
if (isBlockExprInCallers(BlkExpr, SymReaper.getLocationContext())) {
NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
if (isa<loc::MemRegionVal>(X)) {
const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
DRoots.push_back(R);
}
// Mark all symbols in the block expr's value live.
MarkLiveCallback cb(SymReaper);
ST->scanReachableSymbols(X, cb);
continue;
}
// Not a block-level expression?
if (!C.isBlkExpr(BlkExpr))
continue;
const SVal &X = I.getData();
if (SymReaper.isLive(S, BlkExpr)) {
// Copy the binding to the new map.
NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);

14
test/Analysis/inline4.c Normal file
Просмотреть файл

@ -0,0 +1,14 @@
// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f -verify %s
int g(int a) {
return a;
}
int f(int a) {
// Do not remove block-level expression bindings of caller when analyzing
// in the callee.
if (1 && g(a)) // The binding of '1 && g(a)' which is an UndefinedVal
// carries important information.
return 1;
return 0;
}