diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index bdc5096584a..c01c973cf59 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1028,14 +1028,18 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, // If the condition (ignoring parens) is a __builtin_constant_p call, // then only the true side is actually considered in an integer constant - // expression. This is an important GNU extension. - // - // FIXME: ?: with a conditional expr should arguably be an i-c-e if the true - // side can be folded in any way to a constant. See GCC PR38377 for - // discussion. + // expression, and it is fully evaluated. This is an important GNU + // extension. See GCC PR38377 for discussion. if (const CallExpr *CallCE = dyn_cast<CallExpr>(Cond->IgnoreParenCasts())) - if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p) - FalseExp = 0; + if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p) { + EvalResult EVResult; + if (!Evaluate(EVResult, Ctx) || EVResult.HasSideEffects) + return false; + assert(EVResult.Val.isInt() && "FP conditional expr not expected"); + Result = EVResult.Val.getInt(); + if (Loc) *Loc = EVResult.DiagLoc; + return true; + } // Evaluate the false one first, discard the result. if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false)) |

