Commit 3c8e94bc authored by Corentin Jabot's avatar Corentin Jabot Committed by Aaron Ballman
Browse files

Disallow narrowing conversions to bool in noexcept specififers

Completes the support for P1401R5.
parent 3189dd20
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -82,11 +82,11 @@ def err_typecheck_converted_constant_expression_indirect : Error<
  "bind reference to a temporary">;
def err_expr_not_cce : Error<
  "%select{case value|enumerator value|non-type template argument|"
  "array size|explicit specifier argument}0 "
  "array size|explicit specifier argument|noexcept specifier argument}0 "
  "is not a constant expression">;
def ext_cce_narrowing : ExtWarn<
  "%select{case value|enumerator value|non-type template argument|"
  "array size|explicit specifier argument}0 "
  "array size|explicit specifier argument|noexcept specifier argument}0 "
  "%select{cannot be narrowed from type %2 to %3|"
  "evaluates to %2, which cannot be narrowed to type %3}1">,
  InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
+7 −6
Original line number Diff line number Diff line
@@ -3503,7 +3503,8 @@ public:
    CCEK_Enumerator,   ///< Enumerator value with fixed underlying type.
    CCEK_TemplateArg,  ///< Value of a non-type template parameter.
    CCEK_ArrayBound,   ///< Array bound in array declarator or new-expression.
    CCEK_ExplicitBool ///< Condition in an explicit(bool) specifier.
    CCEK_ExplicitBool, ///< Condition in an explicit(bool) specifier.
    CCEK_Noexcept      ///< Condition in a noexcept(bool) specifier.
  };
  ExprResult CheckConvertedConstantExpression(Expr *From, QualType T,
                                              llvm::APSInt &Value, CCEKind CCE);
@@ -5904,7 +5905,7 @@ public:
  /// Check the given noexcept-specifier, convert its expression, and compute
  /// the appropriate ExceptionSpecificationType.
  ExprResult ActOnNoexceptSpec(SourceLocation NoexceptLoc, Expr *NoexceptExpr,
  ExprResult ActOnNoexceptSpec(Expr *NoexceptExpr,
                               ExceptionSpecificationType &EST);
  /// Check the given exception-specification and update the
+1 −1
Original line number Diff line number Diff line
@@ -3837,7 +3837,7 @@ Parser::tryParseExceptionSpecification(bool Delayed,
    NoexceptExpr = ParseConstantExpression();
    T.consumeClose();
    if (!NoexceptExpr.isInvalid()) {
      NoexceptExpr = Actions.ActOnNoexceptSpec(KeywordLoc, NoexceptExpr.get(),
      NoexceptExpr = Actions.ActOnNoexceptSpec(NoexceptExpr.get(),
                                               NoexceptType);
      NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());
    } else {
+12 −8
Original line number Diff line number Diff line
@@ -78,14 +78,21 @@ bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) {
      .Default(false);
}

ExprResult Sema::ActOnNoexceptSpec(SourceLocation NoexceptLoc,
                                   Expr *NoexceptExpr,
ExprResult Sema::ActOnNoexceptSpec(Expr *NoexceptExpr,
                                   ExceptionSpecificationType &EST) {
  // FIXME: This is bogus, a noexcept expression is not a condition.
  ExprResult Converted = CheckBooleanCondition(NoexceptLoc, NoexceptExpr);

  if (NoexceptExpr->isTypeDependent() ||
      NoexceptExpr->containsUnexpandedParameterPack()) {
    EST = EST_DependentNoexcept;
    return NoexceptExpr;
  }

  llvm::APSInt Result;
  ExprResult Converted = CheckConvertedConstantExpression(
      NoexceptExpr, Context.BoolTy, Result, CCEK_Noexcept);

  if (Converted.isInvalid()) {
    EST = EST_NoexceptFalse;

    // Fill in an expression of 'false' as a fixup.
    auto *BoolExpr = new (Context)
        CXXBoolLiteralExpr(false, Context.BoolTy, NoexceptExpr->getBeginLoc());
@@ -99,9 +106,6 @@ ExprResult Sema::ActOnNoexceptSpec(SourceLocation NoexceptLoc,
    return Converted;
  }

  llvm::APSInt Result;
  Converted = VerifyIntegerConstantExpression(
      Converted.get(), &Result, diag::err_noexcept_needs_constant_expression);
  if (!Converted.isInvalid())
    EST = !Result ? EST_NoexceptFalse : EST_NoexceptTrue;
  return Converted;
+1 −1
Original line number Diff line number Diff line
@@ -5635,7 +5635,7 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
  //  expression is a constant expression and the implicit conversion
  //  sequence contains only [... list of conversions ...].
  ImplicitConversionSequence ICS =
      CCE == Sema::CCEK_ExplicitBool
      (CCE == Sema::CCEK_ExplicitBool || CCE == Sema::CCEK_Noexcept)
          ? TryContextuallyConvertToBool(S, From)
          : TryCopyInitialization(S, From, T,
                                  /*SuppressUserConversions=*/false,
Loading