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