implement rdar://6091492 - ?: with __builtin_constant_p as the operand is an i-c-e.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60934 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 728b135..8d11356 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1017,13 +1017,22 @@
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;