зеркало из https://github.com/microsoft/clang-1.git
Refactor GRExprEngine::VisitCall() to use EvalArguments(), just like VisitCXXMemberCallExpr(). Ideally we should unify these code paths as much as possible, since they only differ by a few details.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114628 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
7bb1d23213
Коммит
c69c43845a
|
@ -116,15 +116,6 @@ class GRExprEngine : public GRSubEngine {
|
|||
|
||||
llvm::OwningPtr<GRTransferFuncs> TF;
|
||||
|
||||
class CallExprWLItem {
|
||||
public:
|
||||
CallExpr::const_arg_iterator I;
|
||||
ExplodedNode *N;
|
||||
|
||||
CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
|
||||
: I(i), N(n) {}
|
||||
};
|
||||
|
||||
public:
|
||||
GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf);
|
||||
|
||||
|
|
|
@ -17,9 +17,22 @@
|
|||
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
class CallExprWLItem {
|
||||
public:
|
||||
CallExpr::const_arg_iterator I;
|
||||
ExplodedNode *N;
|
||||
|
||||
CallExprWLItem(const CallExpr::const_arg_iterator &i, ExplodedNode *n)
|
||||
: I(i), N(n) {}
|
||||
};
|
||||
}
|
||||
|
||||
void GRExprEngine::EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
||||
const FunctionProtoType *FnType,
|
||||
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
|
||||
|
||||
|
||||
llvm::SmallVector<CallExprWLItem, 20> WorkList;
|
||||
WorkList.reserve(AE - AI);
|
||||
WorkList.push_back(CallExprWLItem(AI, Pred));
|
||||
|
@ -33,10 +46,13 @@ void GRExprEngine::EvalArguments(ConstExprIterator AI, ConstExprIterator AE,
|
|||
continue;
|
||||
}
|
||||
|
||||
// Evaluate the argument.
|
||||
ExplodedNodeSet Tmp;
|
||||
const unsigned ParamIdx = Item.I - AI;
|
||||
bool VisitAsLvalue = FnType? FnType->getArgType(ParamIdx)->isReferenceType()
|
||||
: false;
|
||||
const bool VisitAsLvalue = FnType && ParamIdx < FnType->getNumArgs()
|
||||
? FnType->getArgType(ParamIdx)->isReferenceType()
|
||||
: false;
|
||||
|
||||
if (VisitAsLvalue)
|
||||
VisitLValue(*Item.I, Item.N, Tmp);
|
||||
else
|
||||
|
|
|
@ -2078,41 +2078,9 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
|||
if (const PointerType *FnTypePtr = FnType->getAs<PointerType>())
|
||||
Proto = FnTypePtr->getPointeeType()->getAs<FunctionProtoType>();
|
||||
|
||||
// Create a worklist to process the arguments.
|
||||
llvm::SmallVector<CallExprWLItem, 20> WorkList;
|
||||
WorkList.reserve(AE - AI);
|
||||
WorkList.push_back(CallExprWLItem(AI, Pred));
|
||||
|
||||
// Evaluate the arguments.
|
||||
ExplodedNodeSet ArgsEvaluated;
|
||||
|
||||
while (!WorkList.empty()) {
|
||||
CallExprWLItem Item = WorkList.back();
|
||||
WorkList.pop_back();
|
||||
|
||||
if (Item.I == AE) {
|
||||
ArgsEvaluated.insert(Item.N);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Evaluate the argument.
|
||||
ExplodedNodeSet Tmp;
|
||||
const unsigned ParamIdx = Item.I - AI;
|
||||
|
||||
bool VisitAsLvalue = false;
|
||||
if (Proto && ParamIdx < Proto->getNumArgs())
|
||||
VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType();
|
||||
|
||||
if (VisitAsLvalue)
|
||||
VisitLValue(*Item.I, Item.N, Tmp);
|
||||
else
|
||||
Visit(*Item.I, Item.N, Tmp);
|
||||
|
||||
// Enqueue evaluating the next argument on the worklist.
|
||||
++(Item.I);
|
||||
|
||||
for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
|
||||
WorkList.push_back(CallExprWLItem(Item.I, *NI));
|
||||
}
|
||||
EvalArguments(CE->arg_begin(), CE->arg_end(), Proto, Pred, ArgsEvaluated);
|
||||
|
||||
// Now process the call itself.
|
||||
ExplodedNodeSet DstTmp;
|
||||
|
@ -2131,7 +2099,6 @@ void GRExprEngine::VisitCall(const CallExpr* CE, ExplodedNode* Pred,
|
|||
// to see if the can evaluate the function call.
|
||||
ExplodedNodeSet DstTmp3;
|
||||
|
||||
|
||||
for (ExplodedNodeSet::iterator DI = DstTmp.begin(), DE = DstTmp.end();
|
||||
DI != DE; ++DI) {
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче