r254574 - PR17381: Treat undefined behavior during expression evaluation as an unmodeled
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 7 19:25:00 PST 2015
I've amended this change to permit constant-foldable UB in C variable
initializers again in r254992.
On Mon, Dec 7, 2015 at 6:45 PM, Robinson, Paul via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> 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
>
That is the behavior required by the C++11 standard, but we used to accept
GNU constant folding here as an extension.
....
>
> (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 };
> ~~~~~~~^~~~~~~~
>
That change would be unrelated to the one at hand -- this is the way we've
always behaved. Consider for instance:
int n;
int foo[2] = { n, n };
If you wanted to make us report the other ones, the relevant code is in
Expr::isConstantInitializer and Sema::CheckForConstantInitializer.
1 error generated.
>
> Thanks,
> --paulr
>
> > -----Original Message-----
> > From: cfe-commits [mailto:cfe-commits-bounces at lists.llvm.org] On Behalf
> Of
> > Richard Smith via cfe-commits
> > Sent: Wednesday, December 02, 2015 5:36 PM
> > To: cfe-commits at 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 at -1 {{not a compile-time constant}}
> >
> > uint64_t check_integer_overflows(int i) {
> > // expected-warning at +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 at -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 at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151207/b9d1d833/attachment-0001.html>
More information about the cfe-commits
mailing list