summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-10-27 22:09:17 +0000
committerMike Stump <mrs@apple.com>2009-10-27 22:09:17 +0000
commit876387ba4ff804995cd3707af70925341c6b58b9 (patch)
tree7c61a34d236f5226857fff03dfefe552d7637606
parenta4374e66f0b92446c4fee3f3f61329a5ff832ba6 (diff)
downloadbcm5719-llvm-876387ba4ff804995cd3707af70925341c6b58b9.tar.gz
bcm5719-llvm-876387ba4ff804995cd3707af70925341c6b58b9.zip
__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. llvm-svn: 85324
-rw-r--r--clang/lib/AST/ExprConstant.cpp64
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp12
2 files changed, 69 insertions, 7 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 8435e034173..dc53289165a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -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);
}
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 29b46611e2e..c26921969a8 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -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.
OpenPOWER on IntegriCloud