Repository: apple/swift
File: lib/SILOptimizer/Utils/ConstantFolding.cpp (C++)

Code before:
  }

  // Check for overflow.
  if (OverflowError) {
    // If we are not asked to emit overflow diagnostics, just return nullptr on
    // overflow.
    if (!ResultsInError.has_value())
      return nullptr;

    SILLocation Loc = BI->getLoc();
    SILModule &M = BI->getModule();
    const ApplyExpr *CE = Loc.getAsASTNode<ApplyExpr>();
    Type UserSrcTy;
    Type UserDstTy;
    // Primitive heuristics to get the user-written type.
    // Eventually we might be able to use SILLocation (when it contains info
    // about inlined call chains).
    if (CE) {
      if (auto *unaryArg = CE->getArgs()->getUnaryExpr()) {
        UserSrcTy = unaryArg->getType();
        UserDstTy = CE->getType();
      }
    } else if (auto *ILE = Loc.getAsASTNode<IntegerLiteralExpr>()) {
      UserDstTy = ILE->getType();
    } else if (auto *E = Loc.getAsASTNode<Expr>()) {
      UserDstTy = E->getType();
    }

    // Assume that we're converting from a literal if the source type is
    // IntegerLiteral.  Is there a better way to identify this if we start
    // using Builtin.IntegerLiteral in an exposed type?
    bool Literal = isa<BuiltinIntegerLiteralType>(SrcTy);

    // FIXME: This will prevent hard error in cases the error is coming
    // from ObjC interoperability code. Currently, we treat NSUInteger as
    // Int.
    if (Loc.getSourceLoc().isInvalid()) {
      // Otherwise emit the appropriate diagnostic and set ResultsInError.
      if (Literal)
        diagnose(M.getASTContext(), Loc.getSourceLoc(),
                 diag::integer_literal_overflow_warn,
                 UserDstTy.isNull() ? DstTy : UserDstTy);
      else
        diagnose(M.getASTContext(), Loc.getSourceLoc(),
                 diag::integer_conversion_overflow_warn,
                 UserSrcTy.isNull() ? SrcTy : UserSrcTy,
                 UserDstTy.isNull() ? DstTy : UserDstTy);

      ResultsInError = std::optional<bool>(true);
      return nullptr;
    }

Review comment (suggestion):
`IntegerLiteralExpr` is also a `Expr` so if `Expr` here is fine, you can remove `IntegerLiteralExpr` branch.
But I'm not really a person to review this area, so I'm not certain we can use arbitrary `Expr` here. So I'll defer to @eeckstein for the review.

Code after:
  }

  // Check for overflow.
  if (OverflowError) {
    // If we are not asked to emit overflow diagnostics, just return nullptr on
    // overflow.
    if (!ResultsInError.has_value())
      return nullptr;

    SILLocation Loc = BI->getLoc();
    SILModule &M = BI->getModule();
    const ApplyExpr *CE = Loc.getAsASTNode<ApplyExpr>();
    Type UserSrcTy;
    Type UserDstTy;
    // Primitive heuristics to get the user-written type.
    // Eventually we might be able to use SILLocation (when it contains info
    // about inlined call chains).
    if (CE) {
      if (auto *unaryArg = CE->getArgs()->getUnaryExpr()) {
        UserSrcTy = unaryArg->getType();
        UserDstTy = CE->getType();
      }
    } else if (auto *E = Loc.getAsASTNode<Expr>()) {
      UserDstTy = E->getType();
    }

    // Assume that we're converting from a literal if the source type is
    // IntegerLiteral.  Is there a better way to identify this if we start
    // using Builtin.IntegerLiteral in an exposed type?
    bool Literal = isa<BuiltinIntegerLiteralType>(SrcTy);

    // FIXME: This will prevent hard error in cases the error is coming
    // from ObjC interoperability code. Currently, we treat NSUInteger as
    // Int.
    if (Loc.getSourceLoc().isInvalid()) {
      // Otherwise emit the appropriate diagnostic and set ResultsInError.
      if (Literal)
        diagnose(M.getASTContext(), Loc.getSourceLoc(),
                 diag::integer_literal_overflow_warn,
                 UserDstTy.isNull() ? DstTy : UserDstTy);
      else
        diagnose(M.getASTContext(), Loc.getSourceLoc(),
                 diag::integer_conversion_overflow_warn,
                 UserSrcTy.isNull() ? SrcTy : UserSrcTy,
                 UserDstTy.isNull() ? DstTy : UserDstTy);

      ResultsInError = std::optional<bool>(true);
      return nullptr;
    }

    // Otherwise report the overflow error.