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
This commit is contained in:
Chris Lattner 2008-12-12 06:55:44 +00:00
Родитель ff871fb8f9
Коммит 28daa53db7
3 изменённых файлов: 20 добавлений и 3 удалений

Просмотреть файл

@ -1152,7 +1152,10 @@ interacts with constant evaluation:</p>
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

Просмотреть файл

@ -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;

Просмотреть файл

@ -1,3 +1,8 @@
// 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];