зеркало из https://github.com/microsoft/clang.git
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:
Родитель
ff871fb8f9
Коммит
28daa53db7
|
@ -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];
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче