<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">I've amended this change to permit constant-foldable UB in C variable initializers again in r254992.</div><div class="gmail_quote"><br></div><div class="gmail_quote">On Mon, Dec 7, 2015 at 6:45 PM, Robinson, Paul via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">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). </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
$ 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<br></blockquote><div><br></div><div>That is the behavior required by the C++11 standard, but we used to accept GNU constant folding here as an extension.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
....<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>
~~~~~~~^~~~~~~~<br></blockquote><div><br></div><div>That change would be unrelated to the one at hand -- this is the way we've always behaved. Consider for instance:</div><div><br></div><div> int n;</div><div> int foo[2] = { n, n };</div><div><br></div><div>If you wanted to make us report the other ones, the relevant code is in Expr::isConstantInitializer and Sema::CheckForConstantInitializer.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
1 error generated.<br>
<br>
Thanks,<br>
--paulr<br>
<span class="im"><br>
> -----Original Message-----<br>
> From: cfe-commits [mailto:<a href="mailto:cfe-commits-bounces@lists.llvm.org">cfe-commits-bounces@lists.llvm.org</a>] On Behalf Of<br>
> Richard Smith via cfe-commits<br>
</span><div class=""><div class="h5">> 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" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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-" rel="noreferrer" 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" rel="noreferrer" 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" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>