r254574 - PR17381: Treat undefined behavior during expression evaluation as an unmodeled

Robinson, Paul via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 7 18:45:37 PST 2015


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-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


More information about the cfe-commits mailing list