From d9435bf47f76644b0bc1d463ccae97a40e2b0116 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 12 Feb 2008 19:49:57 +0000 Subject: [PATCH] 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 --- Analysis/GRConstants.cpp | 124 +++++++++++++++++++++++++++------------ 1 file 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(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(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(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(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(S), Pred, Dst); break; + } + + case Stmt::CastExprClass: { + CastExpr* C = cast(S); + VisitCast(C, C->getSubExpr(), Pred, Dst); + break; + } - case Stmt::StmtExprClass: { - StmtExpr* SE = cast(S); - - StateTy St = Pred->getState(); - Expr* LastExpr = cast(*SE->getSubStmt()->body_rbegin()); - Nodify(Dst, SE, Pred, SetValue(St, SE, GetValue(St, LastExpr))); - break; + case Stmt::ChooseExprClass: { // __builtin_choose_expr + ChooseExpr* C = cast(S); + VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); + break; } - case Stmt::UnaryOperatorClass: - VisitUnaryOperator(cast(S), Pred, Dst); + case Stmt::CompoundAssignOperatorClass: + VisitBinaryOperator(cast(S), Pred, Dst); break; - case Stmt::ParenExprClass: - Visit(cast(S)->getSubExpr(), Pred, Dst); + case Stmt::ConditionalOperatorClass: { // '?' operator + ConditionalOperator* C = cast(S); + VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); break; - + } + case Stmt::DeclRefExprClass: VisitDeclRefExpr(cast(S), Pred, Dst); break; + case Stmt::DeclStmtClass: + VisitDeclStmt(cast(S), Pred, Dst); + break; + case Stmt::ImplicitCastExprClass: { ImplicitCastExpr* C = cast(S); VisitCast(C, C->getSubExpr(), Pred, Dst); break; } - - case Stmt::CastExprClass: { - CastExpr* C = cast(S); - VisitCast(C, C->getSubExpr(), Pred, Dst); + + case Stmt::ParenExprClass: + Visit(cast(S)->getSubExpr(), Pred, Dst); break; - } - case Stmt::ConditionalOperatorClass: { // '?' operator - ConditionalOperator* C = cast(S); - VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); - break; - } - - case Stmt::ChooseExprClass: { // __builtin_choose_expr - ChooseExpr* C = cast(S); - VisitGuardedExpr(C, C->getLHS(), C->getRHS(), Pred, Dst); + case Stmt::SizeOfAlignOfTypeExprClass: + VisitSizeOfAlignOfTypeExpr(cast(S), Pred, Dst); break; + + case Stmt::StmtExprClass: { + StmtExpr* SE = cast(S); + + StateTy St = Pred->getState(); + Expr* LastExpr = cast(*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(S)->getRetValue()) Visit(R, Pred, Dst); else Dst.Add(Pred); break; + } - case Stmt::DeclStmtClass: - VisitDeclStmt(cast(S), Pred, Dst); + case Stmt::UnaryOperatorClass: + VisitUnaryOperator(cast(S), Pred, Dst); break; default: -- 2.50.1