From 45b6b9d080ac56917337d73d8f1cd6374b27b05d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 6 Oct 2008 06:49:02 +0000 Subject: [PATCH] Add a Expr::isEvaluatable method, eliminate isBuiltinConstantExpr which is checking for something that can be inconsistent with what we can constant fold. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57159 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 8 ++++---- lib/AST/Expr.cpp | 11 ++++------- lib/AST/ExprConstant.cpp | 7 +++++++ lib/Sema/SemaDecl.cpp | 15 +++++---------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index df7a83bcbf..2b42424803 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -124,6 +124,10 @@ public: /// we want to. If this function returns true, it returns the folded constant /// in Result. bool tryEvaluate(APValue& Result, ASTContext &Ctx) const; + + /// isEvaluatable - Call tryEvaluate to see if this expression can be constant + /// folded, but discard the result. + bool isEvaluatable(ASTContext &Ctx) const; /// hasGlobalStorage - Return true if this expression has static storage /// duration. This means that the address of this expression is a link-time @@ -709,10 +713,6 @@ public: /// not, return 0. unsigned isBuiltinCall() const; - - /// isBuiltinConstantExpr - Return true if this built-in call is constant. - bool isBuiltinConstantExpr(ASTContext &Ctx) const; - SourceLocation getRParenLoc() const { return RParenLoc; } virtual SourceRange getSourceRange() const { 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(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(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(Init); @@ -1080,8 +1072,11 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { return false; case Expr::CallExprClass: { const CallExpr *CE = cast(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());