diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 11 | ||||
-rw-r--r-- | lib/AST/ExprConstant.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 15 |
3 files changed, 16 insertions, 17 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 45363d6992..6cdaacd689 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -162,12 +162,6 @@ unsigned CallExpr::isBuiltinCall() const { } -bool CallExpr::isBuiltinConstantExpr(ASTContext &Ctx) const { - unsigned BID = isBuiltinCall(); - if (!BID) return false; - return Ctx.BuiltinInfo.isConstantExpr(BID); -} - /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "<<=". const char *BinaryOperator::getOpcodeStr(Opcode Op) { @@ -519,8 +513,11 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { return true; case CallExprClass: { const CallExpr *CE = cast<CallExpr>(this); - if (CE->isBuiltinConstantExpr(Ctx)) + + // Allow any constant foldable calls to builtins. + if (CE->isBuiltinCall() && CE->isEvaluatable(Ctx)) return true; + if (Loc) *Loc = getLocStart(); return false; } diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 1506f448aa..af30ceb96c 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -693,3 +693,10 @@ bool Expr::tryEvaluate(APValue &Result, ASTContext &Ctx) const { return false; } + +/// isEvaluatable - Call tryEvaluate to see if this expression can be constant +/// folded, but discard the result. +bool Expr::isEvaluatable(ASTContext &Ctx) const { + APValue V; + return tryEvaluate(V, Ctx); +} diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 74ce855add..125d91cdba 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -879,14 +879,6 @@ bool Sema::CheckAddressConstantExpression(const Expr* Init) { case Expr::StringLiteralClass: case Expr::ObjCStringLiteralClass: return false; - case Expr::CallExprClass: { - const CallExpr *CE = cast<CallExpr>(Init); - if (CE->isBuiltinConstantExpr(Context)) - return false; - Diag(Init->getExprLoc(), - diag::err_init_element_not_constant, Init->getSourceRange()); - return true; - } case Expr::UnaryOperatorClass: { const UnaryOperator *Exp = cast<UnaryOperator>(Init); @@ -1080,8 +1072,11 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { return false; case Expr::CallExprClass: { const CallExpr *CE = cast<CallExpr>(Init); - if (CE->isBuiltinConstantExpr(Context)) + + // Allow any constant foldable calls to builtins. + if (CE->isBuiltinCall() && CE->isEvaluatable(Context)) return false; + Diag(Init->getExprLoc(), diag::err_init_element_not_constant, Init->getSourceRange()); return true; @@ -1226,7 +1221,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { // Okay, the evaluated side evaluates to a constant, so we accept this. // Check to see if the other side is obviously not a constant. If so, // emit a warning that this is a GNU extension. - if (FalseSide && !FalseSide->tryEvaluate(Val, Context)) + if (FalseSide && !FalseSide->isEvaluatable(Context)) Diag(Init->getExprLoc(), diag::ext_typecheck_expression_not_constant_but_accepted, FalseSide->getSourceRange()); |