<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.im
        {mso-style-name:im;}
span.EmailStyle18
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">|
</span>I've amended this change to permit constant-foldable UB in C variable initializers again in r254992.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Works for us, thanks!<o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">| |
</span>(2) Shouldn't it diagnose each bad expression in an initializer?<o:p></o:p></p>
<p class="MsoNormal">| That change would be unrelated to the one at hand -- this is the way we've always behaved.<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">If it's consistent with past practice, that's fine.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">--paulr<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> metafoo@gmail.com [mailto:metafoo@gmail.com]
<b>On Behalf Of </b>Richard Smith<br>
<b>Sent:</b> Monday, December 07, 2015 7:25 PM<br>
<b>To:</b> Robinson, Paul<br>
<b>Cc:</b> cfe-commits (cfe-commits@lists.llvm.org)<br>
<b>Subject:</b> Re: r254574 - PR17381: Treat undefined behavior during expression evaluation as an unmodeled<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<p class="MsoNormal">I've amended this change to permit constant-foldable UB in C variable initializers again in r254992.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">On Mon, Dec 7, 2015 at 6:45 PM, Robinson, Paul via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<o:p></o:p></p>
<p class="MsoNormal">Two more questions:<br>
<br>
(1) Commit message implied this is only for C, but I see it with C++11<br>
(but not C++03). <o:p></o:p></p>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">$ cat t.cpp<br>
enum { foo = 123456 * 234567 };<br>
$ clang -c t.cpp -std=c++03<br>
$ clang -c t.cpp -std=c++11<br>
t.cpp:1:14: error: expression is not an integral constant expression<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">That is the behavior required by the C++11 standard, but we used to accept GNU constant folding here as an extension.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">....<br>
<br>
(2) Shouldn't it diagnose each bad expression in an initializer?<br>
I see the error only for the first such expression.<br>
<br>
$ cat t.c<br>
int foo[2] = { 123456 * 234567, 654321 * 765432 };<br>
$ clang -c t.c<br>
t.c:1:23: error: initializer element is not a compile-time constant<br>
int foo[2] = { 123456 * 234567, 654321 * 765432 };<br>
               ~~~~~~~^~~~~~~~<o:p></o:p></p>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">That change would be unrelated to the one at hand -- this is the way we've always behaved. Consider for instance:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">  int n;<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">  int foo[2] = { n, n };<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If you wanted to make us report the other ones, the relevant code is in Expr::isConstantInitializer and Sema::CheckForConstantInitializer.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal">1 error generated.<br>
<br>
Thanks,<br>
--paulr<br>
<br>
<span class="im">> -----Original Message-----</span><br>
<span class="im">> From: cfe-commits [mailto:<a href="mailto:cfe-commits-bounces@lists.llvm.org">cfe-commits-bounces@lists.llvm.org</a>] On Behalf Of</span><br>
<span class="im">> Richard Smith via cfe-commits</span><o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">> Sent: Wednesday, December 02, 2015 5:36 PM<br>
> To: <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> Subject: r254574 - PR17381: Treat undefined behavior during expression<br>
> evaluation as an unmodeled<br>
><br>
> Author: rsmith<br>
> Date: Wed Dec  2 19:36:22 2015<br>
> New Revision: 254574<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=254574&view=rev" target="_blank">
http://llvm.org/viewvc/llvm-project?rev=254574&view=rev</a><br>
> Log:<br>
> PR17381: Treat undefined behavior during expression evaluation as an<br>
> unmodeled<br>
> side-effect, so that we don't allow speculative evaluation of such<br>
> expressions<br>
> during code generation.<br>
><br>
> This caused a diagnostic quality regression, so fix constant expression<br>
> diagnostics to prefer either the first "can't be constant folded"<br>
> diagnostic or<br>
> the first "not a constant expression" diagnostic depending on the kind of<br>
> evaluation we're doing. This was always the intent, but didn't quite work<br>
> correctly before.<br>
><br>
> This results in certain initializers that used to be constant initializers<br>
> to<br>
> no longer be; in particular, things like:<br>
><br>
>   float f = 1e100;<br>
><br>
> are no longer accepted in C. This seems appropriate, as such constructs<br>
> would<br>
> lead to code being executed if sanitizers are enabled.<br>
><br>
> Added:<br>
>     cfe/trunk/test/CodeGen/ubsan-conditional.c<br>
> Modified:<br>
>     cfe/trunk/lib/AST/ExprConstant.cpp<br>
>     cfe/trunk/lib/Sema/SemaChecking.cpp<br>
>     cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp<br>
>     cfe/trunk/test/CodeGen/complex-init-list.c<br>
>     cfe/trunk/test/PCH/floating-literal.c<br>
>     cfe/trunk/test/Sema/const-eval.c<br>
>     cfe/trunk/test/Sema/integer-overflow.c<br>
>     cfe/trunk/test/Sema/switch-1.c<br>
>     cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
>     cfe/trunk/test/SemaCXX/constexpr-printing.cpp<br>
><br>
> Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=254574&r1=254573&r2=254574&<br>
> view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
> +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Dec  2 19:36:22 2015<br>
> @@ -473,6 +473,10 @@ namespace {<br>
>      /// notes attached to it will also be stored, otherwise they will not<br>
> be.<br>
>      bool HasActiveDiagnostic;<br>
><br>
> +    /// \brief Have we emitted a diagnostic explaining why we couldn't<br>
> constant<br>
> +    /// fold (not just why it's not strictly a constant expression)?<br>
> +    bool HasFoldFailureDiagnostic;<br>
> +<br>
>      enum EvaluationMode {<br>
>        /// Evaluate as a constant expression. Stop if we find that the<br>
> expression<br>
>        /// is not a constant expression.<br>
> @@ -537,7 +541,7 @@ namespace {<br>
>          BottomFrame(*this, SourceLocation(), nullptr, nullptr, nullptr),<br>
>          EvaluatingDecl((const ValueDecl *)nullptr),<br>
>          EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false),<br>
> -        EvalMode(Mode) {}<br>
> +        HasFoldFailureDiagnostic(false), EvalMode(Mode) {}<br>
><br>
>      void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {<br>
>        EvaluatingDecl = Base;<br>
> @@ -597,7 +601,7 @@ namespace {<br>
>      /// Diagnose that the evaluation cannot be folded.<br>
>      OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId<br>
>                                = diag::note_invalid_subexpr_in_const_expr,<br>
> -                            unsigned ExtraNotes = 0) {<br>
> +                            unsigned ExtraNotes = 0, bool IsCCEDiag =<br>
> false) {<br>
>        if (EvalStatus.Diag) {<br>
>          // If we have a prior diagnostic, it will be noting that the<br>
> expression<br>
>          // isn't a constant expression. This diagnostic is more<br>
> important,<br>
> @@ -610,10 +614,9 @@ namespace {<br>
>            case EM_ConstantFold:<br>
>            case EM_IgnoreSideEffects:<br>
>            case EM_EvaluateForOverflow:<br>
> -            if (!EvalStatus.HasSideEffects)<br>
> +            if (!HasFoldFailureDiagnostic)<br>
>                break;<br>
> -            // We've had side-effects; we want the diagnostic from them,<br>
> not<br>
> -            // some later problem.<br>
> +            // We've already failed to fold something. Keep that<br>
> diagnostic.<br>
>            case EM_ConstantExpression:<br>
>            case EM_PotentialConstantExpression:<br>
>            case EM_ConstantExpressionUnevaluated:<br>
> @@ -632,6 +635,7 @@ namespace {<br>
>            CallStackNotes = 0;<br>
><br>
>          HasActiveDiagnostic = true;<br>
> +        HasFoldFailureDiagnostic = !IsCCEDiag;<br>
>          EvalStatus.Diag->clear();<br>
>          EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);<br>
>          addDiag(Loc, DiagId);<br>
> @@ -645,9 +649,9 @@ namespace {<br>
><br>
>      OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId<br>
>                                = diag::note_invalid_subexpr_in_const_expr,<br>
> -                            unsigned ExtraNotes = 0) {<br>
> +                            unsigned ExtraNotes = 0, bool IsCCEDiag =<br>
> false) {<br>
>        if (EvalStatus.Diag)<br>
> -        return Diag(E->getExprLoc(), DiagId, ExtraNotes);<br>
> +        return Diag(E->getExprLoc(), DiagId, ExtraNotes, IsCCEDiag);<br>
>        HasActiveDiagnostic = false;<br>
>        return OptionalDiagnostic();<br>
>      }<br>
> @@ -667,7 +671,7 @@ namespace {<br>
>          HasActiveDiagnostic = false;<br>
>          return OptionalDiagnostic();<br>
>        }<br>
> -      return Diag(Loc, DiagId, ExtraNotes);<br>
> +      return Diag(Loc, DiagId, ExtraNotes, true);<br>
>      }<br>
><br>
>      /// Add a note to a prior diagnostic.<br>
> @@ -1541,10 +1545,11 @@ static bool EvaluateAsBooleanCondition(c<br>
>  }<br>
><br>
>  template<typename T><br>
> -static void HandleOverflow(EvalInfo &Info, const Expr *E,<br>
> +static bool HandleOverflow(EvalInfo &Info, const Expr *E,<br>
>                             const T &SrcValue, QualType DestType) {<br>
>    Info.CCEDiag(E, diag::note_constexpr_overflow)<br>
>      << SrcValue << DestType;<br>
> +  return Info.noteSideEffect();<br>
>  }<br>
><br>
>  static bool HandleFloatToIntCast(EvalInfo &Info, const Expr *E,<br>
> @@ -1558,7 +1563,7 @@ static bool HandleFloatToIntCast(EvalInf<br>
>    bool ignored;<br>
>    if (Value.convertToInteger(Result, llvm::APFloat::rmTowardZero,<br>
> &ignored)<br>
>        & APFloat::opInvalidOp)<br>
> -    HandleOverflow(Info, E, Value, DestType);<br>
> +    return HandleOverflow(Info, E, Value, DestType);<br>
>    return true;<br>
>  }<br>
><br>
> @@ -1570,7 +1575,7 @@ static bool HandleFloatToFloatCast(EvalI<br>
>    if (Result.convert(Info.Ctx.getFloatTypeSemantics(DestType),<br>
>                       APFloat::rmNearestTiesToEven, &ignored)<br>
>        & APFloat::opOverflow)<br>
> -    HandleOverflow(Info, E, Value, DestType);<br>
> +    return HandleOverflow(Info, E, Value, DestType);<br>
>    return true;<br>
>  }<br>
><br>
> @@ -1593,7 +1598,7 @@ static bool HandleIntToFloatCast(EvalInf<br>
>    if (Result.convertFromAPInt(Value, Value.isSigned(),<br>
>                                APFloat::rmNearestTiesToEven)<br>
>        & APFloat::opOverflow)<br>
> -    HandleOverflow(Info, E, Value, DestType);<br>
> +    return HandleOverflow(Info, E, Value, DestType);<br>
>    return true;<br>
>  }<br>
><br>
> @@ -1669,23 +1674,26 @@ static bool EvalAndBitcastToAPInt(EvalIn<br>
>  /// bits, and check for overflow in the original type (if that type was<br>
> not an<br>
>  /// unsigned type).<br>
>  template<typename Operation><br>
> -static APSInt CheckedIntArithmetic(EvalInfo &Info, const Expr *E,<br>
> -                                   const APSInt &LHS, const APSInt &RHS,<br>
> -                                   unsigned BitWidth, Operation Op) {<br>
> -  if (LHS.isUnsigned())<br>
> -    return Op(LHS, RHS);<br>
> +static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E,<br>
> +                                 const APSInt &LHS, const APSInt &RHS,<br>
> +                                 unsigned BitWidth, Operation Op,<br>
> +                                 APSInt &Result) {<br>
> +  if (LHS.isUnsigned()) {<br>
> +    Result = Op(LHS, RHS);<br>
> +    return true;<br>
> +  }<br>
><br>
>    APSInt Value(Op(LHS.extend(BitWidth), RHS.extend(BitWidth)), false);<br>
> -  APSInt Result = Value.trunc(LHS.getBitWidth());<br>
> +  Result = Value.trunc(LHS.getBitWidth());<br>
>    if (Result.extend(BitWidth) != Value) {<br>
>      if (Info.checkingForOverflow())<br>
>        Info.Ctx.getDiagnostics().Report(E->getExprLoc(),<br>
> -        diag::warn_integer_constant_overflow)<br>
> +<br>
> diag::warn_integer_constant_overflow)<br>
>            << Result.toString(10) << E->getType();<br>
>      else<br>
> -      HandleOverflow(Info, E, Value, E->getType());<br>
> +      return HandleOverflow(Info, E, Value, E->getType());<br>
>    }<br>
> -  return Result;<br>
> +  return true;<br>
>  }<br>
><br>
>  /// Perform the given binary integer operation.<br>
> @@ -1697,17 +1705,14 @@ static bool handleIntIntBinOp(EvalInfo &<br>
>      Info.Diag(E);<br>
>      return false;<br>
>    case BO_Mul:<br>
> -    Result = CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() *<br>
> 2,<br>
> -                                  std::multiplies<APSInt>());<br>
> -    return true;<br>
> +    return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() * 2,<br>
> +                                std::multiplies<APSInt>(), Result);<br>
>    case BO_Add:<br>
> -    Result = CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() +<br>
> 1,<br>
> -                                  std::plus<APSInt>());<br>
> -    return true;<br>
> +    return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() + 1,<br>
> +                                std::plus<APSInt>(), Result);<br>
>    case BO_Sub:<br>
> -    Result = CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() +<br>
> 1,<br>
> -                                  std::minus<APSInt>());<br>
> -    return true;<br>
> +    return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() + 1,<br>
> +                                std::minus<APSInt>(), Result);<br>
>    case BO_And: Result = LHS & RHS; return true;<br>
>    case BO_Xor: Result = LHS ^ RHS; return true;<br>
>    case BO_Or:  Result = LHS | RHS; return true;<br>
> @@ -1717,11 +1722,13 @@ static bool handleIntIntBinOp(EvalInfo &<br>
>        Info.Diag(E, diag::note_expr_divide_by_zero);<br>
>        return false;<br>
>      }<br>
> -    // Check for overflow case: INT_MIN / -1 or INT_MIN % -1.<br>
> +    Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);<br>
> +    // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. APSInt<br>
> supports<br>
> +    // this operation and gives the two's complement result.<br>
>      if (RHS.isNegative() && RHS.isAllOnesValue() &&<br>
>          LHS.isSigned() && LHS.isMinSignedValue())<br>
> -      HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1), E-<br>
> >getType());<br>
> -    Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS);<br>
> +      return HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1),<br>
> +                            E->getType());<br>
>      return true;<br>
>    case BO_Shl: {<br>
>      if (Info.getLangOpts().OpenCL)<br>
> @@ -1809,8 +1816,11 @@ static bool handleFloatFloatBinOp(EvalIn<br>
>      break;<br>
>    }<br>
><br>
> -  if (LHS.isInfinity() || LHS.isNaN())<br>
> +  if (LHS.isInfinity() || LHS.isNaN()) {<br>
>      Info.CCEDiag(E, diag::note_constexpr_float_arithmetic) <<<br>
> LHS.isNaN();<br>
> +    // Undefined behavior is a side-effect.<br>
> +    return Info.noteSideEffect();<br>
> +  }<br>
>    return true;<br>
>  }<br>
><br>
> @@ -3009,7 +3019,7 @@ struct IncDecSubobjectHandler {<br>
>        if (!WasNegative && Value.isNegative() &&<br>
>            isOverflowingIntegerType(Info.Ctx, SubobjType)) {<br>
>          APSInt ActualValue(Value, /*IsUnsigned*/true);<br>
> -        HandleOverflow(Info, E, ActualValue, SubobjType);<br>
> +        return HandleOverflow(Info, E, ActualValue, SubobjType);<br>
>        }<br>
>      } else {<br>
>        --Value;<br>
> @@ -3019,7 +3029,7 @@ struct IncDecSubobjectHandler {<br>
>          unsigned BitWidth = Value.getBitWidth();<br>
>          APSInt ActualValue(Value.sext(BitWidth + 1),<br>
> /*IsUnsigned*/false);<br>
>          ActualValue.setBit(BitWidth);<br>
> -        HandleOverflow(Info, E, ActualValue, SubobjType);<br>
> +        return HandleOverflow(Info, E, ActualValue, SubobjType);<br>
>        }<br>
>      }<br>
>      return true;<br>
> @@ -6240,8 +6250,8 @@ static bool EvaluateBuiltinConstantP(AST<br>
>      APValue &V = Result.Val;<br>
>      if (V.getKind() == APValue::Int)<br>
>        return true;<br>
> -<br>
> -    return EvaluateBuiltinConstantPForLValue(V);<br>
> +    if (V.getKind() == APValue::LValue)<br>
> +      return EvaluateBuiltinConstantPForLValue(V);<br>
>    } else if (ArgType->isFloatingType() || ArgType->isAnyComplexType()) {<br>
>      return Arg->isEvaluatable(Ctx);<br>
>    } else if (ArgType->isPointerType() || Arg->isGLValue()) {<br>
> @@ -7258,7 +7268,7 @@ bool IntExprEvaluator::VisitBinaryOperat<br>
>        LValue LHSValue, RHSValue;<br>
><br>
>        bool LHSOK = EvaluatePointer(E->getLHS(), LHSValue, Info);<br>
> -      if (!LHSOK && Info.keepEvaluatingAfterFailure())<br>
> +      if (!LHSOK && !Info.keepEvaluatingAfterFailure())<br>
>          return false;<br>
><br>
>        if (!EvaluatePointer(E->getRHS(), RHSValue, Info) || !LHSOK)<br>
> @@ -7270,21 +7280,20 @@ bool IntExprEvaluator::VisitBinaryOperat<br>
>          if (E->getOpcode() == BO_Sub) {<br>
>            // Handle &&A - &&B.<br>
>            if (!LHSValue.Offset.isZero() || !RHSValue.Offset.isZero())<br>
> -            return false;<br>
> +            return Error(E);<br>
>            const Expr *LHSExpr = LHSValue.Base.dyn_cast<const Expr*>();<br>
>            const Expr *RHSExpr = RHSValue.Base.dyn_cast<const Expr*>();<br>
>            if (!LHSExpr || !RHSExpr)<br>
> -            return false;<br>
> +            return Error(E);<br>
>            const AddrLabelExpr *LHSAddrExpr =<br>
> dyn_cast<AddrLabelExpr>(LHSExpr);<br>
>            const AddrLabelExpr *RHSAddrExpr =<br>
> dyn_cast<AddrLabelExpr>(RHSExpr);<br>
>            if (!LHSAddrExpr || !RHSAddrExpr)<br>
> -            return false;<br>
> +            return Error(E);<br>
>            // Make sure both labels come from the same function.<br>
>            if (LHSAddrExpr->getLabel()->getDeclContext() !=<br>
>                RHSAddrExpr->getLabel()->getDeclContext())<br>
> -            return false;<br>
> -          Result = APValue(LHSAddrExpr, RHSAddrExpr);<br>
> -          return true;<br>
> +            return Error(E);<br>
> +          return Success(APValue(LHSAddrExpr, RHSAddrExpr), E);<br>
>          }<br>
>          // Inequalities and subtractions between unrelated pointers have<br>
>          // unspecified or undefined behavior.<br>
> @@ -7375,8 +7384,9 @@ bool IntExprEvaluator::VisitBinaryOperat<br>
>          APSInt TrueResult = (LHS - RHS) / ElemSize;<br>
>          APSInt Result = TrueResult.trunc(Info.Ctx.getIntWidth(E-<br>
> >getType()));<br>
><br>
> -        if (Result.extend(65) != TrueResult)<br>
> -          HandleOverflow(Info, E, TrueResult, E->getType());<br>
> +        if (Result.extend(65) != TrueResult &&<br>
> +            !HandleOverflow(Info, E, TrueResult, E->getType()))<br>
> +          return false;<br>
>          return Success(Result, E);<br>
>        }<br>
><br>
> @@ -7662,9 +7672,10 @@ bool IntExprEvaluator::VisitUnaryOperato<br>
>        return false;<br>
>      if (!Result.isInt()) return Error(E);<br>
>      const APSInt &Value = Result.getInt();<br>
> -    if (Value.isSigned() && Value.isMinSignedValue())<br>
> -      HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),<br>
> -                     E->getType());<br>
> +    if (Value.isSigned() && Value.isMinSignedValue() &&<br>
> +        !HandleOverflow(Info, E, -Value.extend(Value.getBitWidth() + 1),<br>
> +                        E->getType()))<br>
> +      return false;<br>
>      return Success(-Value, E);<br>
>    }<br>
>    case UO_Not: {<br>
> @@ -8863,7 +8874,9 @@ bool Expr::EvaluateAsInitializer(APValue<br>
>    Expr::EvalStatus EStatus;<br>
>    EStatus.Diag = &Notes;<br>
><br>
> -  EvalInfo InitInfo(Ctx, EStatus, EvalInfo::EM_ConstantFold);<br>
> +  EvalInfo InitInfo(Ctx, EStatus, VD->isConstexpr()<br>
> +                                      ? EvalInfo::EM_ConstantExpression<br>
> +                                      : EvalInfo::EM_ConstantFold);<br>
>    InitInfo.setEvaluatingDecl(VD, Value);<br>
><br>
>    LValue LVal;<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=254574&r1=254573&r2=254574<br>
> &view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Dec  2 19:36:22 2015<br>
> @@ -8547,7 +8547,7 @@ void Sema::CheckArrayAccess(const Expr *<br>
>      return;<br>
><br>
>    llvm::APSInt index;<br>
> -  if (!IndexExpr->EvaluateAsInt(index, Context))<br>
> +  if (!IndexExpr->EvaluateAsInt(index, Context,<br>
> Expr::SE_AllowSideEffects))<br>
>      return;<br>
>    if (IndexNegated)<br>
>      index = -index;<br>
><br>
> Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/test/CXX/expr/expr.const/p2-<br>
> 0x.cpp?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)<br>
> +++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Wed Dec  2 19:36:22 2015<br>
> @@ -601,11 +601,11 @@ namespace rdar13090123 {<br>
>    typedef __INTPTR_TYPE__ intptr_t;<br>
><br>
>    constexpr intptr_t f(intptr_t x) {<br>
> -    return (((x) >> 21) * 8); // expected-note{{subexpression not valid<br>
> in a constant expression}}<br>
> +    return (((x) >> 21) * 8);<br>
>    }<br>
><br>
>    extern "C" int foo;<br>
><br>
>    constexpr intptr_t i = f((intptr_t)&foo - 10); // expected-<br>
> error{{constexpr variable 'i' must be initialized by a constant<br>
> expression}} \<br>
> -  // expected-note{{in call to 'f((char*)&foo + -10)'}}<br>
> +  // expected-note{{reinterpret_cast}}<br>
>  }<br>
><br>
> Modified: cfe/trunk/test/CodeGen/complex-init-list.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/complex-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/complex-</a><br>
> init-list.c?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGen/complex-init-list.c (original)<br>
> +++ cfe/trunk/test/CodeGen/complex-init-list.c Wed Dec  2 19:36:22 2015<br>
> @@ -4,8 +4,8 @@<br>
>  // of a complex number individually using an initialization list.  (There<br>
> is a<br>
>  // extensive description and test in test/Sema/complex-init-list.c.)<br>
><br>
> -_Complex float x = { 1.0f, 1.0f/0.0f };<br>
> -// CHECK: @x = global { float, float } { float 1.000000e+00, float<br>
> 0x7FF0000000000000 }, align 4<br>
> +_Complex float x = { 1.0f, -1.0f };<br>
> +// CHECK: @x = global { float, float } { float 1.000000e+00, float -<br>
> 1.000000e+00 }, align 4<br>
><br>
>  _Complex float f(float x, float y) { _Complex float z = { x, y }; return<br>
> z; }<br>
>  // CHECK-LABEL: define <2 x float> @f<br>
><br>
> Added: cfe/trunk/test/CodeGen/ubsan-conditional.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ubsan-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ubsan-</a><br>
> conditional.c?rev=254574&view=auto<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/CodeGen/ubsan-conditional.c (added)<br>
> +++ cfe/trunk/test/CodeGen/ubsan-conditional.c Wed Dec  2 19:36:22 2015<br>
> @@ -0,0 +1,10 @@<br>
> +// RUN: %clang_cc1 %s -emit-llvm -fsanitize=float-divide-by-zero -o - |<br>
> FileCheck %s<br>
> +<br>
> +_Bool b;<br>
> +// CHECK: @f(<br>
> +double f() {<br>
> +  // CHECK: %[[B:.*]] = load {{.*}} @b<br>
> +  // CHECK: %[[COND:.*]] = trunc {{.*}} %[[B]] to i1<br>
> +  // CHECK: br i1 %[[COND]]<br>
> +  return b ? 0.0 / 0.0 : 0.0;<br>
> +}<br>
><br>
> Modified: cfe/trunk/test/PCH/floating-literal.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/floating-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/floating-</a><br>
> literal.c?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/PCH/floating-literal.c (original)<br>
> +++ cfe/trunk/test/PCH/floating-literal.c Wed Dec  2 19:36:22 2015<br>
> @@ -15,5 +15,5 @@ long double foo = 1.0E4000L;<br>
>  double bar = 1.0E300;<br>
>  // CHECK: double bar = 1.0000000000000001E+300;<br>
><br>
> -float wibble = 1.0E40;<br>
> -// CHECK: float wibble = 1.0E+40;<br>
> +float wibble = 2.0E38;<br>
> +// CHECK: float wibble = 2.0E+38;<br>
><br>
> Modified: cfe/trunk/test/Sema/const-eval.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-</a><br>
> eval.c?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/Sema/const-eval.c (original)<br>
> +++ cfe/trunk/test/Sema/const-eval.c Wed Dec  2 19:36:22 2015<br>
> @@ -129,7 +129,7 @@ extern struct Test50S Test50;<br>
>  EVAL_EXPR(50, &Test50 < (struct Test50S*)((unsigned)&Test50 + 10)) //<br>
> expected-error {{must have a constant size}}<br>
><br>
>  // <rdar://problem/11874571><br>
> -EVAL_EXPR(51, 0 != (float)1e99)<br>
> +EVAL_EXPR(51, 0 != (float)1e38)<br>
><br>
>  // PR21945<br>
>  void PR21945() { int i = (({}), 0l); }<br>
><br>
> Modified: cfe/trunk/test/Sema/integer-overflow.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-</a><br>
> overflow.c?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/Sema/integer-overflow.c (original)<br>
> +++ cfe/trunk/test/Sema/integer-overflow.c Wed Dec  2 19:36:22 2015<br>
> @@ -7,6 +7,7 @@ uint64_t f1(uint64_t, uint32_t);<br>
>  uint64_t f2(uint64_t, ...);<br>
><br>
>  static const uint64_t overflow = 1 * 4608 * 1024 * 1024; // expected-<br>
> warning {{overflow in expression; result is 536870912 with type 'int'}}<br>
> +// expected-error@-1 {{not a compile-time constant}}<br>
><br>
>  uint64_t check_integer_overflows(int i) {<br>
>  // expected-warning@+1 {{overflow in expression; result is 536870912 with<br>
> type 'int'}}<br>
><br>
> Modified: cfe/trunk/test/Sema/switch-1.c<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/switch-</a><br>
> 1.c?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/Sema/switch-1.c (original)<br>
> +++ cfe/trunk/test/Sema/switch-1.c Wed Dec  2 19:36:22 2015<br>
> @@ -55,5 +55,8 @@ int f(int i) {<br>
><br>
>  // rdar://18405357<br>
>  unsigned long long l = 65536 * 65536; // expected-warning {{overflow in<br>
> expression; result is 0 with type 'int'}}<br>
> +#ifndef __cplusplus<br>
> +// expected-error@-2 {{not a compile-time constant}}<br>
> +#endif<br>
>  unsigned long long l2 = 65536 * (unsigned)65536;<br>
>  unsigned long long l3 = 65536 * 65536ULL;<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-</a><br>
> expression-cxx11.cpp?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Dec  2<br>
> 19:36:22 2015<br>
> @@ -327,7 +327,7 @@ struct Str {<br>
>  };<br>
><br>
>  extern char externalvar[];<br>
> -constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; //<br>
> expected-error {{must be initialized by a constant expression}}<br>
> +constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; //<br>
> expected-error {{must be initialized by a constant expression}} expected-<br>
> note {{reinterpret_cast}}<br>
>  constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be<br>
> initialized by a constant expression}} expected-warning {{unspecified}}<br>
>  static_assert(0 != "foo", "");<br>
><br>
> @@ -1874,10 +1874,9 @@ namespace NeverConstantTwoWays {<br>
>          0;<br>
>    }<br>
><br>
> -  // FIXME: We should diagnose the cast to long here, not the division by<br>
> zero.<br>
>    constexpr int n = // expected-error {{must be initialized by a constant<br>
> expression}}<br>
> -      (int *)(long)&n == &n ?<br>
> -        1 / 0 : // expected-warning {{division by zero}} expected-note<br>
> {{division by zero}}<br>
> +      (int *)(long)&n == &n ? // expected-note {{reinterpret_cast}}<br>
> +        1 / 0 : // expected-warning {{division by zero}}<br>
>          0;<br>
>  }<br>
><br>
><br>
> Modified: cfe/trunk/test/SemaCXX/constexpr-printing.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-" target="_blank">
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-</a><br>
> printing.cpp?rev=254574&r1=254573&r2=254574&view=diff<br>
> ==========================================================================<br>
> ====<br>
> --- cfe/trunk/test/SemaCXX/constexpr-printing.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/constexpr-printing.cpp Wed Dec  2 19:36:22 2015<br>
> @@ -90,10 +90,12 @@ constexpr wchar_t wc = get(L"test\0\\\"\<br>
><br>
>  constexpr char32_t c32_err = get(U"\U00110000"); // expected-error<br>
> {{invalid universal character}}<br>
><br>
> +#define fold(x) (__builtin_constant_p(x) ? (x) : (x))<br>
> +<br>
>  typedef decltype(sizeof(int)) LabelDiffTy;<br>
>  constexpr LabelDiffTy mulBy3(LabelDiffTy x) { return x * 3; } //<br>
> expected-note {{subexpression}}<br>
>  void LabelDiffTest() {<br>
> -  static_assert(mulBy3((LabelDiffTy)&&a-(LabelDiffTy)&&b) == 3, ""); //<br>
> expected-error {{constant expression}} expected-note {{call to 'mulBy3(&&a<br>
> - &&b)'}}<br>
> +  static_assert(mulBy3(fold((LabelDiffTy)&&a-(LabelDiffTy)&&b)) == 3,<br>
> ""); // expected-error {{constant expression}} expected-note {{call to<br>
> 'mulBy3(&&a - &&b)'}}<br>
>    a:b:return;<br>
>  }<br>
><br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank">
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>