diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-10-28 00:22:11 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-10-28 00:22:11 +0000 |
commit | 9d293dfc0ad7c44ae0b5eb9517f1ed8c8d8b7ff7 (patch) | |
tree | a2ce41058d0f9114ddf1d894891afb985b2a0c21 /lib/Analysis/GRExprEngine.cpp | |
parent | 8173dba2229e113052e762b4eda98f8edfdff173 (diff) |
Improve our handling of (C++) references within Clang. Specifically:
- Do not allow expressions to ever have reference type
- Extend Expr::isLvalue to handle more cases where having written a
reference into the source implies that the expression is an lvalue
(e.g., function calls, C++ casts).
- Make GRExprEngine::VisitCall treat the call arguments as lvalues when
they are being bound to a reference parameter.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58306 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index e843f5d9e1..41579ac3a7 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1063,22 +1063,43 @@ const GRState* GRExprEngine::EvalLocation(Expr* Ex, NodeTy* Pred, //===----------------------------------------------------------------------===// // Transfer function: Function calls. //===----------------------------------------------------------------------===// - void GRExprEngine::VisitCall(CallExpr* CE, NodeTy* Pred, CallExpr::arg_iterator AI, CallExpr::arg_iterator AE, - NodeSet& Dst) { + NodeSet& Dst) +{ + // Determine the type of function we're calling (if available). + const FunctionTypeProto *Proto = NULL; + QualType FnType = CE->getCallee()->IgnoreParens()->getType(); + if (const PointerType *FnTypePtr = FnType->getAsPointerType()) + Proto = FnTypePtr->getPointeeType()->getAsFunctionTypeProto(); + + VisitCallRec(CE, Pred, AI, AE, Dst, Proto, /*ParamIdx=*/0); +} + +void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred, + CallExpr::arg_iterator AI, + CallExpr::arg_iterator AE, + NodeSet& Dst, const FunctionTypeProto *Proto, + unsigned ParamIdx) { // Process the arguments. - if (AI != AE) { - - NodeSet DstTmp; - Visit(*AI, Pred, DstTmp); + // If the call argument is being bound to a reference parameter, + // visit it as an lvalue, not an rvalue. + bool VisitAsLvalue = false; + if (Proto && ParamIdx < Proto->getNumArgs()) + VisitAsLvalue = Proto->getArgType(ParamIdx)->isReferenceType(); + + NodeSet DstTmp; + if (VisitAsLvalue) + VisitLValue(*AI, Pred, DstTmp); + else + Visit(*AI, Pred, DstTmp); ++AI; for (NodeSet::iterator DI=DstTmp.begin(), DE=DstTmp.end(); DI != DE; ++DI) - VisitCall(CE, *DI, AI, AE, Dst); + VisitCallRec(CE, *DI, AI, AE, Dst, Proto, ParamIdx + 1); return; } |