__builtin_object_size refinements. Ensure we handle expressions with

side-effects up front, as when we switch to the llvm intrinsic call
for __builtin_object_size later, it will have two evaluations.

We also finish off the intrinsic version of the code so we can just
turn it on once llvm has the intrinsic.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85324 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Mike Stump 2009-10-27 22:09:17 +00:00
Родитель 25950e8c13
Коммит c4c9045dab
2 изменённых файлов: 69 добавлений и 7 удалений

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

@ -151,6 +151,66 @@ static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType,
return Result;
}
namespace {
class VISIBILITY_HIDDEN HasSideEffect
: public StmtVisitor<HasSideEffect, bool> {
EvalInfo &Info;
public:
HasSideEffect(EvalInfo &info) : Info(info) {}
// Unhandled nodes conservatively default to having side effects.
bool VisitStmt(Stmt *S) {
return true;
}
bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
bool VisitDeclRefExpr(DeclRefExpr *E) {
if (E->getType().isVolatileQualified())
return true;
return false;
}
// We don't want to evaluate BlockExprs multiple times, as they generate
// a ton of code.
bool VisitBlockExpr(BlockExpr *E) { return true; }
bool VisitPredefinedExpr(PredefinedExpr *E) { return false; }
bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E)
{ return Visit(E->getInitializer()); }
bool VisitMemberExpr(MemberExpr *E) { return Visit(E->getBase()); }
bool VisitIntegerLiteral(IntegerLiteral *E) { return false; }
bool VisitFloatingLiteral(FloatingLiteral *E) { return false; }
bool VisitStringLiteral(StringLiteral *E) { return false; }
bool VisitCharacterLiteral(CharacterLiteral *E) { return false; }
bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { return false; }
bool VisitArraySubscriptExpr(ArraySubscriptExpr *E)
{ return Visit(E->getLHS()) && Visit(E->getRHS()); }
bool VisitChooseExpr(ChooseExpr *E)
{ return Visit(E->getChosenSubExpr(Info.Ctx)); }
bool VisitCastExpr(CastExpr *E) { return Visit(E->getSubExpr()); }
bool VisitBinAssign(BinaryOperator *E) { return true; }
bool VisitCompoundAssign(BinaryOperator *E) { return true; }
bool VisitBinaryOperator(BinaryOperator *E) { return false; }
bool VisitUnaryPreInc(UnaryOperator *E) { return true; }
bool VisitUnaryPostInc(UnaryOperator *E) { return true; }
bool VisitUnaryPreDec(UnaryOperator *E) { return true; }
bool VisitUnaryPostDec(UnaryOperator *E) { return true; }
bool VisitUnaryDeref(UnaryOperator *E) {
if (E->getType().isVolatileQualified())
return true;
return false;
}
bool VisitUnaryOperator(UnaryOperator *E) { return Visit(E->getSubExpr()); }
};
bool HasSideEffects(const Expr* E, ASTContext &Ctx) {
Expr::EvalResult Result;
EvalInfo Info(Ctx, Result);
return HasSideEffect(Info).Visit(const_cast<Expr*>(E));
}
} // end anonymous namespace
//===----------------------------------------------------------------------===//
// LValue Evaluation
//===----------------------------------------------------------------------===//
@ -893,12 +953,12 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
}
}
if (Base.HasSideEffects) {
if (HasSideEffects(E->getArg(0), Info.Ctx)) {
if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() < 2)
return Success(-1, E);
return Success(0, E);
}
return Error(E->getLocStart(), diag::note_invalid_subexpr_in_ice, E);
}

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

@ -203,11 +203,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
#if 0
// We pass this builtin onto the optimizer so that it can
// figure out the object size in more complex cases.
Value *F = CGM.getIntrinsic(Intrinsic::objectsize, 0, 0);
Builder.CreateCall2(F,
EmitScalarExpr(E->getArg(0)));
EmitScalarExpr(E->getArg(1)));
return RValue::get(Address);
const llvm::Type *ResType[] = {
ConvertType(E->getType())
};
Value *F = CGM.getIntrinsic(Intrinsic::objectsize, ResType, 1);
return RValue::get(Builder.CreateCall2(F,
EmitScalarExpr(E->getArg(0)),
EmitScalarExpr(E->getArg(1))));
#else
// FIXME: Implement. For now we just always fail and pretend we
// don't know the object size.