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