diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-12 19:49:57 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-12 19:49:57 +0000 |
commit | d9435bf47f76644b0bc1d463ccae97a40e2b0116 (patch) | |
tree | 2488908e94de19aac08b34cd47f213f2cf97119f | |
parent | 6083ea3723ec3996ae3bdf8d1b352b0c3b3922c8 (diff) |
Added transfer function logic for sizeof(expr)/sizeof(type). This currently
doesn't support VLAs.
Reordered some cases in the switch statement of GRConstant::Visit() so
that they are ordered alphabetically based on AST node type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47021 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Analysis/GRConstants.cpp | 124 |
1 files changed, 88 insertions, 36 deletions
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp index 8b94aaa70b..90b055c370 100644 --- a/Analysis/GRConstants.cpp +++ b/Analysis/GRConstants.cpp @@ -295,6 +295,10 @@ public: /// VisitLogicalExpr - Transfer function logic for '&&', '||' void VisitLogicalExpr(BinaryOperator* B, NodeTy* Pred, NodeSet& Dst); + + /// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type). + void VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* S, NodeTy* Pred, + NodeSet& Dst); }; } // end anonymous namespace @@ -378,7 +382,8 @@ void GRConstants::ProcessBranch(Expr* Condition, Stmt* Term, // Get the current block counter. GRBlockCounter BC = builder.getBlockCounter(); - unsigned NumVisited = BC.getNumVisited(builder.getTargetBlock(true)->getBlockID()); + unsigned BlockID = builder.getTargetBlock(true)->getBlockID(); + unsigned NumVisited = BC.getNumVisited(BlockID); if (isa<nonlval::ConcreteInt>(V) || BC.getNumVisited(builder.getTargetBlock(true)->getBlockID()) < 1) { @@ -397,8 +402,8 @@ void GRConstants::ProcessBranch(Expr* Condition, Stmt* Term, else builder.markInfeasible(true); - NumVisited = BC.getNumVisited(builder.getTargetBlock(true)->getBlockID()); - + BlockID = builder.getTargetBlock(false)->getBlockID(); + NumVisited = BC.getNumVisited(BlockID); if (isa<nonlval::ConcreteInt>(V) || BC.getNumVisited(builder.getTargetBlock(false)->getBlockID()) < 1) { @@ -583,6 +588,28 @@ void GRConstants::VisitGuardedExpr(Expr* S, Expr* LHS, Expr* RHS, Nodify(Dst, S, Pred, SetValue(St, S, R)); } +/// VisitSizeOfAlignOfTypeExpr - Transfer function for sizeof(type). +void GRConstants::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* S, + NodeTy* Pred, + NodeSet& Dst) { + + // 6.5.3.4 sizeof: "The result type is an integer." + + QualType T = S->getArgumentType(); + + // FIXME: Add support for VLAs. + if (isa<VariableArrayType>(T.getTypePtr())) + return; + + SourceLocation L = S->getExprLoc(); + uint64_t size = getContext().getTypeSize(T, L) / 8; + + Nodify(Dst, S, Pred, + SetValue(Pred->getState(), S, + NonLValue::GetValue(ValMgr, size, getContext().IntTy, L))); + +} + void GRConstants::VisitUnaryOperator(UnaryOperator* U, GRConstants::NodeTy* Pred, GRConstants::NodeSet& Dst) { @@ -686,6 +713,25 @@ void GRConstants::VisitUnaryOperator(UnaryOperator* U, break; } + + case UnaryOperator::SizeOf: { + // 6.5.3.4 sizeof: "The result type is an integer." + + QualType T = U->getSubExpr()->getType(); + + // FIXME: Add support for VLAs. + if (isa<VariableArrayType>(T.getTypePtr())) + return; + + SourceLocation L = U->getExprLoc(); + uint64_t size = getContext().getTypeSize(T, L) / 8; + + Nodify(Dst, U, N1, + SetValue(St, U, NonLValue::GetValue(ValMgr, size, + getContext().IntTy, L))); + + break; + } case UnaryOperator::AddrOf: { const LValue& L1 = GetLValue(St, U->getSubExpr()); @@ -885,69 +931,75 @@ void GRConstants::Visit(Stmt* S, GRConstants::NodeTy* Pred, Nodify(Dst, B, Pred, SetValue(St, B, GetValue(St, B->getRHS()))); break; } - } - // Fall-through. - - case Stmt::CompoundAssignOperatorClass: VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); break; + } + + case Stmt::CastExprClass: { + CastExpr* C = cast<CastExpr>(S); + VisitCast(C, C->getSubExpr(), Pred, Dst); + break; + } - case Stmt::StmtExprClass: { - StmtExpr* SE = cast<StmtExpr>(S); - - StateTy St = Pred->getState(); - Expr* LastExpr = cast<Expr>(*SE->getSubStmt()->body_rbegin()); - Nodify(Dst, SE, Pred, SetValue(St, SE, GetValue(St, LastExpr))); - break; + case Stmt::ChooseExprClass: { // __builtin_choose_expr + ChooseExpr* C = cast<ChooseExpr>(S); + VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); + break; } - case Stmt::UnaryOperatorClass: - VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst); + case Stmt::CompoundAssignOperatorClass: + VisitBinaryOperator(cast<BinaryOperator>(S), Pred, Dst); break; - case Stmt::ParenExprClass: - Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst); + case Stmt::ConditionalOperatorClass: { // '?' operator + ConditionalOperator* C = cast<ConditionalOperator>(S); + VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); break; - + } + case Stmt::DeclRefExprClass: VisitDeclRefExpr(cast<DeclRefExpr>(S), Pred, Dst); break; + case Stmt::DeclStmtClass: + VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst); + break; + case Stmt::ImplicitCastExprClass: { ImplicitCastExpr* C = cast<ImplicitCastExpr>(S); VisitCast(C, C->getSubExpr(), Pred, Dst); break; } - - case Stmt::CastExprClass: { - CastExpr* C = cast<CastExpr>(S); - VisitCast(C, C->getSubExpr(), Pred, Dst); + + case Stmt::ParenExprClass: + Visit(cast<ParenExpr>(S)->getSubExpr(), Pred, Dst); break; - } - case Stmt::ConditionalOperatorClass: { // '?' operator - ConditionalOperator* C = cast<ConditionalOperator>(S); - VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); - break; - } - - case Stmt::ChooseExprClass: { // __builtin_choose_expr - ChooseExpr* C = cast<ChooseExpr>(S); - VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); + case Stmt::SizeOfAlignOfTypeExprClass: + VisitSizeOfAlignOfTypeExpr(cast<SizeOfAlignOfTypeExpr>(S), Pred, Dst); break; + + case Stmt::StmtExprClass: { + StmtExpr* SE = cast<StmtExpr>(S); + + StateTy St = Pred->getState(); + Expr* LastExpr = cast<Expr>(*SE->getSubStmt()->body_rbegin()); + Nodify(Dst, SE, Pred, SetValue(St, SE, GetValue(St, LastExpr))); + break; } - case Stmt::ReturnStmtClass: + case Stmt::ReturnStmtClass: { if (Expr* R = cast<ReturnStmt>(S)->getRetValue()) Visit(R, Pred, Dst); else Dst.Add(Pred); break; + } - case Stmt::DeclStmtClass: - VisitDeclStmt(cast<DeclStmt>(S), Pred, Dst); + case Stmt::UnaryOperatorClass: + VisitUnaryOperator(cast<UnaryOperator>(S), Pred, Dst); break; default: |