зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
a4d55d89c8
Коммит
45b6b9d080
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
Загрузка…
Ссылка в новой задаче