зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
b3e485c835
Коммит
7b73b92870
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
Загрузка…
Ссылка в новой задаче