aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Analysis/GRExprEngine.cpp20
-rw-r--r--Analysis/GRSimpleVals.cpp16
-rw-r--r--Analysis/GRSimpleVals.h4
-rw-r--r--Analysis/GRTransferFuncs.cpp41
-rw-r--r--include/clang/Analysis/PathSensitive/GRExprEngine.h10
-rw-r--r--include/clang/Analysis/PathSensitive/GRTransferFuncs.h5
6 files changed, 33 insertions, 63 deletions
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 1ca37615d8..51b0a597ee 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -477,7 +477,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
NodeTy* N = *I1;
StateTy St = N->getState();
RVal V = GetRVal(St, Ex);
- Nodify(Dst, CastE, N, SetRVal(St, CastE, EvalCast(ValMgr, V, CastE)));
+ Nodify(Dst, CastE, N, SetRVal(St, CastE, EvalCast(V, CastE->getType())));
}
}
@@ -520,14 +520,13 @@ void GRExprEngine::VisitGuardedExpr(Expr* Ex, Expr* L, Expr* R,
void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
NodeTy* Pred,
NodeSet& Dst) {
-
- assert (Ex->isSizeOf() && "AlignOf(Expr) not yet implemented.");
+
+ assert (Ex->isSizeOf() && "FIXME: AlignOf(Expr) not yet implemented.");
// 6.5.3.4 sizeof: "The result type is an integer."
QualType T = Ex->getArgumentType();
-
- // FIXME: Implement alignof
+
// FIXME: Add support for VLAs.
if (!T.getTypePtr()->isConstantSizeType())
@@ -942,7 +941,16 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B,
else
((int&) Op) -= BinaryOperator::MulAssign;
- RVal Result = EvalBinOp(Op, V, RightV);
+ // Get the computation type.
+ QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
+
+ // Perform promotions.
+ V = EvalCast(V, CTy);
+ RightV = EvalCast(V, CTy);
+
+ // Evaluate operands and promote to result type.
+ RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
+
St = SetRVal(SetRVal(St, B, Result), LeftLV, Result);
}
}
diff --git a/Analysis/GRSimpleVals.cpp b/Analysis/GRSimpleVals.cpp
index 675882f42e..ed0706be89 100644
--- a/Analysis/GRSimpleVals.cpp
+++ b/Analysis/GRSimpleVals.cpp
@@ -58,17 +58,16 @@ unsigned RunGRSimpleVals(CFG& cfg, FunctionDecl& FD, ASTContext& Ctx,
// Transfer function for Casts.
//===----------------------------------------------------------------------===//
-RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, Expr* CastExpr) {
+RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, QualType T) {
if (!isa<nonlval::ConcreteInt>(X))
return UnknownVal();
llvm::APSInt V = cast<nonlval::ConcreteInt>(X).getValue();
- QualType T = CastExpr->getType();
V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
- V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+ V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
- if (CastExpr->getType()->isPointerType())
+ if (T->isPointerType())
return lval::ConcreteInt(ValMgr.getValue(V));
else
return nonlval::ConcreteInt(ValMgr.getValue(V));
@@ -76,20 +75,19 @@ RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, NonLVal X, Expr* CastExpr) {
// Casts.
-RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, Expr* CastExpr) {
+RVal GRSimpleVals::EvalCast(ValueManager& ValMgr, LVal X, QualType T) {
- if (CastExpr->getType()->isPointerType())
+ if (T->isPointerType())
return X;
- assert (CastExpr->getType()->isIntegerType());
+ assert (T->isIntegerType());
if (!isa<lval::ConcreteInt>(X))
return UnknownVal();
llvm::APSInt V = cast<lval::ConcreteInt>(X).getValue();
- QualType T = CastExpr->getType();
V.setIsUnsigned(T->isUnsignedIntegerType() || T->isPointerType());
- V.extOrTrunc(ValMgr.getContext().getTypeSize(T, CastExpr->getLocStart()));
+ V.extOrTrunc(ValMgr.getContext().getTypeSize(T, SourceLocation()));
return nonlval::ConcreteInt(ValMgr.getValue(V));
}
diff --git a/Analysis/GRSimpleVals.h b/Analysis/GRSimpleVals.h
index 28286ec11f..870166e8f4 100644
--- a/Analysis/GRSimpleVals.h
+++ b/Analysis/GRSimpleVals.h
@@ -28,8 +28,8 @@ public:
// Casts.
- virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, Expr* CastExpr);
- virtual RVal EvalCast(ValueManager& ValMgr, LVal V, Expr* CastExpr);
+ virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, QualType CastT);
+ virtual RVal EvalCast(ValueManager& ValMgr, LVal V, QualType CastT);
// Unary Operators.
diff --git a/Analysis/GRTransferFuncs.cpp b/Analysis/GRTransferFuncs.cpp
deleted file mode 100644
index 29d6216b71..0000000000
--- a/Analysis/GRTransferFuncs.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-//== GRTransferFuncs.cpp - Path-Sens. Transfer Functions Interface -*- C++ -*--=
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This files defines GRTransferFuncs, which provides a base-class that
-// defines an interface for transfer functions used by GRExprEngine.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Transfer function for Casts.
-//===----------------------------------------------------------------------===//
-
-RVal GRTransferFuncs::EvalCast(ValueManager& ValMgr, RVal X, Expr* CastExpr) {
-
- switch (X.getBaseKind()) {
-
- default:
- assert(false && "Invalid RVal."); break;
-
- case RVal::LValKind:
- return EvalCast(ValMgr, cast<LVal>(X), CastExpr);
-
- case RVal::NonLValKind:
- return EvalCast(ValMgr, cast<NonLVal>(X), CastExpr);
-
- case RVal::UninitializedKind:
- case RVal::UnknownKind: break;
- }
-
- return X;
-}
diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h
index fbb0275dd4..f83f3d3e5c 100644
--- a/include/clang/Analysis/PathSensitive/GRExprEngine.h
+++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h
@@ -341,8 +341,14 @@ public:
void VisitDeref(UnaryOperator* B, NodeTy* Pred, NodeSet& Dst);
- RVal EvalCast(ValueManager& ValMgr, RVal X, Expr* CastExpr) {
- return X.isValid() ? TF->EvalCast(ValMgr, X, CastExpr) : X;
+ RVal EvalCast(RVal X, QualType CastT) {
+ if (X.isUnknownOrUninit())
+ return X;
+
+ if (isa<LVal>(X))
+ return TF->EvalCast(ValMgr, cast<LVal>(X), CastT);
+ else
+ return TF->EvalCast(ValMgr, cast<NonLVal>(X), CastT);
}
RVal EvalMinus(UnaryOperator* U, RVal X) {
diff --git a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
index faa559ee58..2a8ec2b6f7 100644
--- a/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Analysis/PathSensitive/GRTransferFuncs.h
@@ -26,9 +26,8 @@ public:
// Casts.
- RVal EvalCast(ValueManager& ValMgr, RVal V, Expr* CastExpr);
- virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, Expr* CastExpr) =0;
- virtual RVal EvalCast(ValueManager& ValMgr, LVal V, Expr* CastExpr) = 0;
+ virtual RVal EvalCast(ValueManager& ValMgr, NonLVal V, QualType CastT) =0;
+ virtual RVal EvalCast(ValueManager& ValMgr, LVal V, QualType CastT) = 0;
// Unary Operators.