diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-05-23 04:13:20 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-05-23 04:13:20 +0000 |
| commit | 01ade177e944ba81794fdcaf01c41bd558a31ede (patch) | |
| tree | c0d9a3aab0747cfa754a5aebe216df47950ac8ed /clang/lib | |
| parent | 9fc5c814fa5f3804cb8748f355276ac0b1b4e0a4 (diff) | |
| download | bcm5719-llvm-01ade177e944ba81794fdcaf01c41bd558a31ede.tar.gz bcm5719-llvm-01ade177e944ba81794fdcaf01c41bd558a31ede.zip | |
If the first argument of __builtin_object_size can be folded to a constant
pointer, but such folding encounters side-effects, ignore the side-effects
rather than performing them at runtime: CodeGen generates wrong code for
__builtin_object_size in that case.
llvm-svn: 157310
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 17 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 4 |
2 files changed, 17 insertions, 4 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 5362320f499..d3ab84fc4a8 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4319,10 +4319,16 @@ QualType IntExprEvaluator::GetObjectType(APValue::LValueBase B) { } bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E) { - // TODO: Perhaps we should let LLVM lower this? LValue Base; - if (!EvaluatePointer(E->getArg(0), Base, Info)) - return false; + + { + // The operand of __builtin_object_size is never evaluated for side-effects. + // If there are any, but we can determine the pointed-to object anyway, then + // ignore the side-effects. + SpeculativeEvaluationRAII SpeculativeEval(Info); + if (!EvaluatePointer(E->getArg(0), Base, Info)) + return false; + } // If we can prove the base is null, lower to zero now. if (!Base.getLValueBase()) return Success(0, E); @@ -4355,13 +4361,16 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { return true; // If evaluating the argument has side-effects we can't determine - // the size of the object and lower it to unknown now. + // the size of the object and lower it to unknown now. CodeGen relies on + // us to handle all cases where the expression has side-effects. if (E->getArg(0)->HasSideEffects(Info.Ctx)) { if (E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue() <= 1) return Success(-1ULL, E); return Success(0, E); } + // Expression had no side effects, but we couldn't statically determine the + // size of the referenced object. return Error(E); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 944fbe9f19a..a3d4af72da1 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -335,6 +335,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Builder.CreateCall(F, ArgValue)); } case Builtin::BI__builtin_object_size: { + // We rely on constant folding to deal with expressions with side effects. + assert(!E->getArg(0)->HasSideEffects(getContext()) && + "should have been constant folded"); + // We pass this builtin onto the optimizer so that it can // figure out the object size in more complex cases. llvm::Type *ResType = ConvertType(E->getType()); |

