Skip to content

Fix integer-pointer cast extension to match GCC semantics - #9231

Open
tautschnig wants to merge 1 commit into
diffblue:developfrom
tautschnig:kiro/9212-ptr-int-extend
Open

tautschnig wants to merge 1 commit into
diffblue:developfrom
tautschnig:kiro/9212-ptr-int-extend

Conversation

@tautschnig

Copy link
Copy Markdown
Collaborator

The SAT and SMT2 back ends disagreed on how to extend integer-to-pointer
and pointer-to-integer casts when the types have different widths:

  • SAT: zero-extended in both directions
  • SMT2: sign-extended in both directions

GCC documents that integer-to-pointer conversion extends according to
the signedness of the source integer type, and pointer-to-integer
conversion sign-extends. Neither back end matched GCC on all cases.

Fix SAT back end (bv_pointers.cpp):

  • Integer to pointer: sign-extend for signed sources, zero-extend for
    unsigned sources (was: always zero-extend).
  • Pointer to integer: sign-extend (was: zero-extend).

Fix SMT2 back end (smt2_conv.cpp):

  • Integer to pointer: extend according to source signedness (was:
    always sign-extend).
  • Pointer to integer: already correct (sign-extend), no change.

Fixes #9212

  • 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.
  • White-space or formatting changes outside the feature-related changed lines are in commits of their own.

The SAT and SMT2 back ends disagreed on how to extend integer-to-pointer
and pointer-to-integer casts when the types have different widths:
- SAT: zero-extended in both directions
- SMT2: sign-extended in both directions

GCC documents that integer-to-pointer conversion extends according to
the signedness of the source integer type, and pointer-to-integer
conversion sign-extends. Neither back end matched GCC on all cases.

Fix SAT back end (bv_pointers.cpp):
- Integer to pointer: sign-extend for signed sources, zero-extend for
  unsigned sources (was: always zero-extend).
- Pointer to integer: sign-extend (was: zero-extend).

Fix SMT2 back end (smt2_conv.cpp):
- Integer to pointer: extend according to source signedness (was:
  always sign-extend).
- Pointer to integer: already correct (sign-extend), no change.

Fixes diffblue#9212

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 20, 2026 19:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@codecov

codecov Bot commented Oct 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 80.90%. Comparing base (266f438) to head (4e1ca5a).

Files with missing lines Patch % Lines
src/solvers/flattening/bv_pointers.cpp 88.88% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #9231      +/-   ##
===========================================
- Coverage    80.91%   80.90%   -0.01%     
===========================================
  Files         1718     1718              
  Lines       190266   190272       +6     
  Branches        73       73              
===========================================
- Hits        153952   153941      -11     
- Misses       36314    36331      +17     

☔ View full report in Codecov by Harness.
📢 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.

@kroening

Copy link
Copy Markdown
Collaborator

This semantics feels extremely compiler and target-specific. The C-frontend should lower the cast to the specific target semantics based on compiler and architecture setting.

tautschnig added a commit to tautschnig/cbmc that referenced this pull request Oct 28, 2026
The extract upper index for narrowing an integer to a pointer used
to_width instead of to_width-1, producing a bit-vector of to_width+1
bits rather than to_width bits.  This caused solver sort errors
whenever the source integer was wider than the pointer type, e.g.
long long to pointer on --32, or __int128 to pointer on --64.

SMT-LIB 2.6 extract semantics: ((_ extract i j) bv) yields bits i
downto j inclusive, so the result width is i-j+1.  Using to_width as
the upper index gave to_width+1 bits; the fix uses to_width-1.

This composes with PR diffblue#9231 (which changes the extension direction
for narrower-to-wider integer-to-pointer casts but does not touch
the narrowing path).

Reported by Jeroen Robben (https://reports.robben.io/methodology/).

Fixes diffblue#9369

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SAT and SMT2 backends disagree on extending integer-to-pointer and pointer-to-integer casts

3 participants