any evaluatable subexpression to be accepted as an integer constant
expression.</li>
<li><b><tt>__builtin_constant_p</tt></b>: This returns true (as a integer
- constant expression) if the operand is any evaluatable constant.</li>
+ constant expression) if the operand is any evaluatable constant. As a
+ special case, if <tt>__builtin_constant_p</tt> is the (potentially
+ parenthesized) condition of a conditional operator expression ("?:"), only
+ the true side of the conditional operator is considered.</li>
<li><b><tt>__builtin_choose_expr</tt></b>: The condition is required to be an
integer constant expression, but we accept any constant as an "extension of
an extension". This only evaluates one operand depending on which way the
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;
-// RUN: clang %s -fsyntax-only -verify
+// RUN: clang %s -fsyntax-only -verify -pedantic
int a() {int p; *(1 ? &p : (void*)(0 && (a(),1))) = 10;}
+
+// rdar://6091492 - ?: with __builtin_constant_p as the operand is an i-c-e.
+int expr;
+char w[__builtin_constant_p(expr) ? expr : 1];
+