aboutsummaryrefslogtreecommitdiff
path: root/Analysis/GRConstants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Analysis/GRConstants.cpp')
-rw-r--r--Analysis/GRConstants.cpp124
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: