Detect comparisons with NAN constants

Currently `cmp_nan` lint doesn't detect comparisons with NaN's
if the operands are consts variables so to fix this we evaluate
the const variables first before testing for NaN.
This commit is contained in:
Krishna Veera Reddy
2019-12-17 18:51:30 -08:00
parent c62396dbf4
commit eb0408ea65
3 changed files with 117 additions and 30 deletions

View File

@@ -343,12 +343,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
ExprKind::Binary(ref cmp, ref left, ref right) => {
let op = cmp.node;
if op.is_comparison() {
if let ExprKind::Path(QPath::Resolved(_, ref path)) = left.kind {
check_nan(cx, path, expr);
}
if let ExprKind::Path(QPath::Resolved(_, ref path)) = right.kind {
check_nan(cx, path, expr);
}
check_nan(cx, left, expr.span);
check_nan(cx, right, expr.span);
check_to_owned(cx, left, right);
check_to_owned(cx, right, left);
}
@@ -444,17 +440,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
}
}
fn check_nan(cx: &LateContext<'_, '_>, path: &Path, expr: &Expr) {
if !in_constant(cx, expr.hir_id) {
if let Some(seg) = path.segments.last() {
if seg.ident.name == sym!(NAN) {
span_lint(
cx,
CMP_NAN,
expr.span,
"doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead",
);
}
fn check_nan(cx: &LateContext<'_, '_>, expr: &Expr, cmp_span: Span) {
if let Some((value, _)) = constant(cx, cx.tables, expr) {
let needs_lint = match value {
Constant::F32(num) => num.is_nan(),
Constant::F64(num) => num.is_nan(),
_ => false,
};
if needs_lint {
span_lint(
cx,
CMP_NAN,
cmp_span,
"doomed comparison with NAN, use `std::{f32,f64}::is_nan()` instead",
);
}
}
}