summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp17
1 files changed, 13 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);
}
OpenPOWER on IntegriCloud