diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-30 22:17:15 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-30 22:17:15 +0000 |
commit | ee90dba3529dba5086918d6419fb7ce0d687bc05 (patch) | |
tree | 30955e30e406bc0388533944988ef582b3131e4f /lib/Analysis/GRExprEngine.cpp | |
parent | a084bb667db31158278248f249cd302281c7da59 (diff) |
Add placeholder code in the static analyzer for MemberExprs involving struct temporaries.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50502 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 55 |
1 files changed, 45 insertions, 10 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 7bfcaab112..e10e9ae8f3 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -831,22 +831,57 @@ void GRExprEngine::VisitMemberExpr(MemberExpr* M, NodeTy* Pred, // abstract address of the base object. NodeSet Tmp; - if (IsPointerType(Base->getType())) // Base always is an LVal. - Visit(Base, Pred, Tmp); - else - VisitLVal(Base, Pred, Tmp); + if (asLVal) { + + if (IsPointerType(Base->getType())) // Base always is an LVal. + Visit(Base, Pred, Tmp); + else + VisitLVal(Base, Pred, Tmp); + + for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { + ValueState* St = GetState(*I); + RVal BaseV = GetRVal(St, Base); + + RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base), + M->getMemberDecl()); + + MakeNode(Dst, M, *I, SetRVal(St, M, V)); + } + + return; + } + + // Evaluate the base. Can be an LVal or NonLVal (depends on whether + // or not isArrow() is true). + Visit(Base, Pred, Tmp); for (NodeSet::iterator I=Tmp.begin(), E=Tmp.end(); I!=E; ++I) { + ValueState* St = GetState(*I); - RVal BaseV = GetRVal(St, Base); + RVal BaseV = GetRVal(St, Base); - RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base), - M->getMemberDecl()); + if (IsPointerType(Base->getType())) { + + assert (M->isArrow()); + + RVal V = lval::FieldOffset::Make(BasicVals, GetRVal(St, Base), + M->getMemberDecl()); - if (asLVal) - MakeNode(Dst, M, *I, SetRVal(St, M, V)); - else EvalLoad(Dst, M, *I, St, V); + } + else { + + assert (!M->isArrow()); + + if (BaseV.isUnknownOrUndef()) { + MakeNode(Dst, M, *I, SetRVal(St, M, BaseV)); + continue; + } + + // FIXME: Implement nonlval objects representing struct temporaries. + assert (isa<NonLVal>(BaseV)); + MakeNode(Dst, M, *I, SetRVal(St, M, UnknownVal())); + } } } |