diff options
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 728b13534a3..8d113569259 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1017,13 +1017,22 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, case ConditionalOperatorClass: { const ConditionalOperator *Exp = cast<ConditionalOperator>(this); - if (!Exp->getCond()->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated)) + const Expr *Cond = Exp->getCond(); + + if (!Cond->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated)) return false; const Expr *TrueExp = Exp->getLHS(); const Expr *FalseExp = Exp->getRHS(); if (Result == 0) std::swap(TrueExp, FalseExp); + // 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. + if (const CallExpr *CallCE = dyn_cast<CallExpr>(Cond->IgnoreParenCasts())) + if (CallCE->isBuiltinCall() == Builtin::BI__builtin_constant_p) + FalseExp = 0; + // Evaluate the false one first, discard the result. if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false)) return false; |

