Simplified and generalized transfer function logic for casts, allowing

the transfer function to be invoked without an Expr* for the Cast operation.

Added implicit promotions to the transfer function logic for compound
assignments.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47444 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2008-02-21 18:43:30 +00:00
Родитель 297d0d701d
Коммит 9ef1ec98a8
6 изменённых файлов: 33 добавлений и 63 удалений

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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));
}

Просмотреть файл

@ -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.

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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.