зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
297d0d701d
Коммит
9ef1ec98a8
|
@ -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.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче