Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -2810,7 +2810,8 @@ /// Perform the given binary integer operation. static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, BinaryOperatorKind Opcode, APSInt RHS, - APSInt &Result) { + APSInt &Result, + SourceRange RHSRange = SourceRange()) { bool HandleOverflowResult = true; switch (Opcode) { default: @@ -2831,7 +2832,7 @@ case BO_Div: case BO_Rem: if (RHS == 0) { - Info.FFDiag(E, diag::note_expr_divide_by_zero); + Info.FFDiag(E, diag::note_expr_divide_by_zero) << RHSRange; return false; } // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. APSInt supports @@ -3070,8 +3071,9 @@ else if (BinaryOperator::isComparisonOp(Opcode)) Success = handleCompareOpForVector(LHSElt, Opcode, RHSElt, EltResult); else - Success = handleIntIntBinOp(Info, E, LHSElt.getInt(), Opcode, - RHSElt.getInt(), EltResult); + Success = + handleIntIntBinOp(Info, E, LHSElt.getInt(), Opcode, RHSElt.getInt(), + EltResult, E->getRHS()->getSourceRange()); if (!Success) { Info.FFDiag(E); @@ -12892,7 +12894,7 @@ APSInt Value(Info.Ctx.getIntWidth(E->getType()), E->getType()->isUnsignedIntegerOrEnumerationType()); if (!handleIntIntBinOp(Info, E, LHSVal.getInt(), E->getOpcode(), - RHSVal.getInt(), Value)) + RHSVal.getInt(), Value, E->getRHS()->getSourceRange())) return false; return Success(Value, E, Result); } Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -152,8 +152,9 @@ template bool CheckDivRem(InterpState &S, CodePtr OpPC, const T &LHS, const T &RHS) { if (RHS.isZero()) { - const SourceInfo &Loc = S.Current->getSource(OpPC); - S.FFDiag(Loc, diag::note_expr_divide_by_zero); + const auto *Op = cast(S.Current->getExpr(OpPC)); + S.FFDiag(Op, diag::note_expr_divide_by_zero) + << Op->getRHS()->getSourceRange(); return false; } Index: clang/test/Misc/constexpr-source-ranges.cpp =================================================================== --- clang/test/Misc/constexpr-source-ranges.cpp +++ clang/test/Misc/constexpr-source-ranges.cpp @@ -23,3 +23,16 @@ } static_assert(ints(1, div(true, false), 2, div(false, true)) == 1, ""); // CHECK: constexpr-source-ranges.cpp:24:23:{24:23-24:39} + + +constexpr int zero() { + return 0; +} +constexpr int divByZero() { + return 1 / zero(); +} +static_assert(divByZero() == 0, ""); +/// We see this twice. Once from sema and once when +/// evaluating the static_assert above. +// CHECK: constexpr-source-ranges.cpp:32:12:{32:14-32:20} +// CHECK: constexpr-source-ranges.cpp:32:12:{32:14-32:20}