Skip to content

Fix --nan-check false positive for finite/+INFINITY division#8745

Open
tautschnig wants to merge 2 commits into
diffblue:developfrom
tautschnig:fix-8634-inf-nan
Open

Fix --nan-check false positive for finite/+INFINITY division#8745
tautschnig wants to merge 2 commits into
diffblue:developfrom
tautschnig:fix-8634-inf-nan

Conversation

@tautschnig
Copy link
Copy Markdown
Collaborator

@tautschnig tautschnig commented Nov 29, 2025

Depends-on: #9020

  • Update NaN check condition to require infinity in nominator
  • Add regression tests to validate IEEE 754 infinity arithmetic

Fixes: #8634

  • Each commit message has a non-empty body, explaining why the change was made.
  • n/a Methods or procedures I have added are documented, following the guidelines provided in CODING_STANDARD.md.
  • n/a The feature or user visible behaviour I have added or modified has been documented in the User Guide in doc/cprover-manual/
  • Regression or unit tests are included, or existing tests cover the modified code (in this case I have detailed which ones those are in the commit message).
  • n/a My commit message includes data points confirming performance improvements (if claimed).
  • My PR is restricted to a single feature or bugfix.
  • n/a White-space or formatting changes outside the feature-related changed lines are in commits of their own.

@tautschnig tautschnig marked this pull request as draft November 30, 2025 22:41
@tautschnig tautschnig force-pushed the fix-8634-inf-nan branch 2 times, most recently from 81bf5e7 to 4e48600 Compare December 2, 2025 03:24
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 2, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.59%. Comparing base (01ebe42) to head (73ed258).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8745      +/-   ##
===========================================
- Coverage    80.59%   80.59%   -0.01%     
===========================================
  Files         1711     1711              
  Lines       189454   189461       +7     
  Branches        73       73              
===========================================
+ Hits        152697   152702       +5     
- Misses       36757    36759       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tautschnig tautschnig force-pushed the fix-8634-inf-nan branch 3 times, most recently from 1871271 to 5578125 Compare December 2, 2025 14:02
@tautschnig tautschnig marked this pull request as ready for review December 3, 2025 14:23
Copilot AI review requested due to automatic review settings March 10, 2026 09:15
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a --nan-check false positive by aligning division NaN detection with IEEE 754 rules (finite/∞ is ±0, only ∞/∞ yields NaN), and adds regressions around infinity arithmetic.

Changes:

  • Update NaN-check logic for division to flag only 0/0 and inf/inf.
  • Extend SMT2 parser support with fp.isNegative / fp.isPositive.
  • Add/adjust regression tests and math-library stubs for __isfinite*.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/util/ieee_float.cpp Updates division comment to reflect IEEE 754 behavior.
src/solvers/smt2/smt2_parser.cpp Adds parsing for fp.isNegative and fp.isPositive.
src/ansi-c/library_check.sh Excludes __isfinite* symbols from library check list.
src/ansi-c/library/math.c Adds __isfinite, __isfinitef, __isfinitel wrappers.
src/ansi-c/goto-conversion/goto_check_c.cpp Fixes NaN check condition for division (inf/inf only).
src/ansi-c/c_typecheck_expr.cpp Treats __builtin_isfinite as a special function.
regression/cbmc/float-nan-check/test.desc Updates expected NaN-check failure pattern for division.
regression/cbmc/float-nan-check/main.c Adjusts regression to use inf/inf instead of n/inf.
regression/cbmc/float-inf-div-inf/test.desc Adds new regression expectations for inf/inf NaN checks.
regression/cbmc/float-inf-div-inf/main.c New test exercising ±inf / ±inf producing NaN.
regression/cbmc/float-finite-div-infinity/test.desc New regression ensuring finite/∞ does not trigger NaN checks.
regression/cbmc/float-finite-div-infinity/main.c New test asserting finite/∞ results in signed zero.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread regression/cbmc/float-finite-div-infinity/main.c
Comment thread src/ansi-c/c_typecheck_expr.cpp Outdated
Comment thread src/solvers/smt2/smt2_parser.cpp Outdated
Comment thread src/solvers/smt2/smt2_parser.cpp Outdated
tautschnig and others added 2 commits May 29, 2026 17:06
BSD systems appear to use `__` prefixed variants of several functions.
Define these as needed. Also, avoid handling some GCC-style
`__builtin_`-prefixed functions via models when others are done directly
in the type checker: do all of them in the type checker.

In addition to `__builtin_isfinite`, recognise its older glibc
internal aliases `__builtin_finite`, `__builtin_finitef` and
`__builtin_finitel` in the same isfinite_exprt branch of the type
checker.  Some glibc `<bits/mathcalls-helper-functions.h>` headers
expose the legacy `finite()` API via these builtins, and without
recognition CBMC would otherwise treat them as body-less functions
returning nondet.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Two fixes in goto_check_ct::nan_check:

1. Division: the existing condition treated x/inf as a NaN-producing
   operation, but per IEEE 754-2019 Section 6.1, finite/inf is +/-0,
   not NaN. The only div operations that produce NaN are 0/0 and
   inf/inf. Replace the over-broad isinf(op1) check with the
   conjunction isinf(op0) && isinf(op1).

2. Multiplication: the zero_times_inf clause was a copy-paste of
   inf_times_zero (both compared op1 against zero and op0 against
   isinf), so --nan-check failed to flag '0 * inf' when the zero
   was on the LHS. Fix by swapping the operand sides in
   zero_times_inf.

The companion ieee_float.cpp comment update brings the runtime
constant evaluator's comment in line with the now-correct semantics
(it already evaluated both directions correctly; only the comment
was misleading).

New regression tests:
- regression/cbmc/float-finite-div-infinity: positive test that
  finite/inf produces +/-0.0 with --nan-check enabled, no NaN
  assertion fired.
- regression/cbmc/float-inf-div-inf: positive test that inf/inf is
  flagged as NaN under all four sign permutations.
- regression/cbmc/float-nan-check: replace the (now-incorrect) n/inf
  case with inf/inf, and add a 'myzero * myinf' assertion that the
  buggy mult-branch was missing -- without fix 2, that assertion is
  not generated and the test fails.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Divide by +INFINITY raises NaN failure with --nan-check even when numerator is a finite number

3 participants