diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 08e308909452..a6473a1c5c4c 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6496,11 +6496,12 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, return InvalidOperands(Loc, LHS, RHS); // Check for division by zero. - if (IsDiv && - RHS.get()->isNullPointerConstant(Context, - Expr::NPC_ValueDependentIsNotNull)) - DiagRuntimeBehavior(Loc, RHS.get(), PDiag(diag::warn_division_by_zero) - << RHS.get()->getSourceRange()); + llvm::APSInt RHSValue; + if (IsDiv && !RHS.get()->isValueDependent() && + RHS.get()->EvaluateAsInt(RHSValue, Context) && RHSValue == 0) + DiagRuntimeBehavior(Loc, RHS.get(), + PDiag(diag::warn_division_by_zero) + << RHS.get()->getSourceRange()); return compType; } @@ -6525,10 +6526,12 @@ QualType Sema::CheckRemainderOperands( return InvalidOperands(Loc, LHS, RHS); // Check for remainder by zero. - if (RHS.get()->isNullPointerConstant(Context, - Expr::NPC_ValueDependentIsNotNull)) - DiagRuntimeBehavior(Loc, RHS.get(), PDiag(diag::warn_remainder_by_zero) - << RHS.get()->getSourceRange()); + llvm::APSInt RHSValue; + if (!RHS.get()->isValueDependent() && + RHS.get()->EvaluateAsInt(RHSValue, Context) && RHSValue == 0) + DiagRuntimeBehavior(Loc, RHS.get(), + PDiag(diag::warn_remainder_by_zero) + << RHS.get()->getSourceRange()); return compType; } diff --git a/clang/test/SemaCXX/warn-div-or-rem-by-zero.cpp b/clang/test/SemaCXX/warn-div-or-rem-by-zero.cpp new file mode 100644 index 000000000000..44b877eb1bc4 --- /dev/null +++ b/clang/test/SemaCXX/warn-div-or-rem-by-zero.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++1y -verify %s + +void div() { + (void)(42 / 0); // expected-warning{{division by zero is undefined}} + (void)(42 / false); // expected-warning{{division by zero is undefined}} + (void)(42 / !1); // expected-warning{{division by zero is undefined}} + (void)(42 / (1 - 1)); // expected-warning{{division by zero is undefined}} + (void)(42 / !(1 + 1)); // expected-warning{{division by zero is undefined}} + (void)(42 / (int)(0.0)); // expected-warning{{division by zero is undefined}} +} + +void rem() { + (void)(42 % 0); // expected-warning{{remainder by zero is undefined}} + (void)(42 % false); // expected-warning{{remainder by zero is undefined}} + (void)(42 % !1); // expected-warning{{remainder by zero is undefined}} + (void)(42 % (1 - 1)); // expected-warning{{remainder by zero is undefined}} + (void)(42 % !(1 + 1)); // expected-warning{{remainder by zero is undefined}} + (void)(42 % (int)(0.0)); // expected-warning{{remainder by zero is undefined}} +}