diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7d6796dd9d359..c8d4258333f8f 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2805,9 +2805,9 @@ static bool CheckedIntArithmetic(EvalInfo &Info, const Expr *E, } /// Perform the given binary integer operation. -static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, - BinaryOperatorKind Opcode, APSInt RHS, - APSInt &Result) { +static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E, + const APSInt &LHS, APSInt RHS, APSInt &Result) { + BinaryOperatorKind Opcode = E->getOpcode(); bool HandleOverflowResult = true; switch (Opcode) { default: @@ -2828,7 +2828,8 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, 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) + << E->getRHS()->getSourceRange(); return false; } // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. APSInt supports @@ -3072,8 +3073,8 @@ static bool handleVectorVectorBinOp(EvalInfo &Info, const BinaryOperator *E, 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(), RHSElt.getInt(), + EltResult); if (!Success) { Info.FFDiag(E); @@ -4473,7 +4474,7 @@ struct CompoundAssignSubobjectHandler { if (RHS.isInt()) { APSInt LHS = HandleIntToIntCast(Info, E, PromotedLHSType, SubobjType, Value); - if (!handleIntIntBinOp(Info, E, LHS, Opcode, RHS.getInt(), LHS)) + if (!handleIntIntBinOp(Info, E, LHS, RHS.getInt(), LHS)) return false; Value = HandleIntToIntCast(Info, E, SubobjType, PromotedLHSType, LHS); return true; @@ -12892,8 +12893,7 @@ bool DataRecursiveIntBinOpEvaluator:: // FIXME: Don't do this in the cases where we can deduce it. APSInt Value(Info.Ctx.getIntWidth(E->getType()), E->getType()->isUnsignedIntegerOrEnumerationType()); - if (!handleIntIntBinOp(Info, E, LHSVal.getInt(), E->getOpcode(), - RHSVal.getInt(), Value)) + if (!handleIntIntBinOp(Info, E, LHSVal.getInt(), RHSVal.getInt(), Value)) return false; return Success(Value, E, Result); } diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 4da5985e3b3d6..9d7a9af01e8d1 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -148,8 +148,9 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS, 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; } diff --git a/clang/test/Misc/constexpr-source-ranges.cpp b/clang/test/Misc/constexpr-source-ranges.cpp index c4f83cbb0e23a..b493fb37fb70d 100644 --- a/clang/test/Misc/constexpr-source-ranges.cpp +++ b/clang/test/Misc/constexpr-source-ranges.cpp @@ -13,3 +13,15 @@ constexpr int I = 12; constexpr const int *P = &I; constexpr long L = (long)P; // CHECK: constexpr-source-ranges.cpp:14:20:{14:20-14:27} + +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:23:15:{23:15-23:31} +// CHECK: constexpr-source-ranges.cpp:21:12:{21:14-21:20}