Skip to content

Fix for #1758#1761

Merged
sim642 merged 5 commits intogoblint:masterfrom
Robotechnic:master
Jun 30, 2025
Merged

Fix for #1758#1761
sim642 merged 5 commits intogoblint:masterfrom
Robotechnic:master

Conversation

@Robotechnic
Copy link
Copy Markdown
Contributor

This fixes issue #1758. It might need some benchmarks, but it works and passes all the tests.

@sim642 sim642 self-requested a review June 19, 2025 11:36
@sim642 sim642 added this to the v2.6.0 milestone Jun 19, 2025
@sim642 sim642 linked an issue Jun 19, 2025 that may be closed by this pull request
@sim642
Copy link
Copy Markdown
Member

sim642 commented Jun 20, 2025

At least on sv-benchmarks this has no measurable impact OLS regression on CPU time gives $$y = 0.98x + 0.01$$ without outliars. It's also the case that sv-benchmarks uses library functions a lot less than real-world programs would.

Still, we need to do this to be sound, there's no way around it. If this turns out to negatively impact some realistic benchmarks, we might want to optimize something, but that's a separate matter.

@michael-schwarz michael-schwarz self-requested a review June 24, 2025 01:58
Copy link
Copy Markdown
Member

@michael-schwarz michael-schwarz left a comment

Choose a reason for hiding this comment

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

Thank you for submitting this PR, it's quite a surprise that this stayed hidden for such a long time!

Here's some remarks:

  • There are some library functions that explicitly do not evaluate their arguments (or at least not with the usual semantics (such as the sizeof operator which iirc we map to a library function). Do we need to account for those?
  • This adds such evaluation to the base analysis. Do other analyses also need it?
  • Is eval_rv always the right thing to do? Do arguments to library functions not sometimes act as lvals?
  • We may want to add a comment where we call eval_rv purely for its side-effects.
  • In #1758, you have more examples. Why not add them as tests?

I would also be interested to see the effect of this on a larger set of benchmarks, say the concrat suite...

@sim642
Copy link
Copy Markdown
Member

sim642 commented Jun 25, 2025

To comment on a few of these:

  • There are some library functions that explicitly do not evaluate their arguments (or at least not with the usual semantics (such as the sizeof operator which iirc we map to a library function). Do we need to account for those?

SizeOfE is actually a constructor in Cil.exp, so that shouldn't be the problem.

  • This adds such evaluation to the base analysis. Do other analyses also need it?

Only if they produce warnings from domains during expression evaluation, but I don't know if that is the case anywhere else.
The other obvious candidate is relation analysis, but it doesn't even do structural evaluation.
The access/race analysis already covers this, e.g. 04-mutex/20-stdfun_rc.

  • Is eval_rv always the right thing to do? Do arguments to library functions not sometimes act as lvals?

To act as an lval, the argument needs to be AddrOf lval, not just lval. And anyway we have to evaluate things in lvals as well, e.g. pointer arithmetic under * or indexing expressions.

@Robotechnic
Copy link
Copy Markdown
Contributor Author

I can add more tests if you'd like, but we can put whatever we want in the printf arguments, and it will cause the bug to happen again. I put some more examples because I wasn't sure about the cause of the issue.

@sim642 sim642 requested a review from michael-schwarz June 25, 2025 11:01
@sim642
Copy link
Copy Markdown
Member

sim642 commented Jun 27, 2025

I would also be interested to see the effect of this on a larger set of benchmarks, say the concrat suite...

Using the setup now at goblint/bench#69, the total number of evals changes 2300528 → 2305052, which is an increase of 4524, i.e. 0.2%.

@sim642 sim642 merged commit 6b1f72b into goblint:master Jun 30, 2025
11 checks passed
sim642 added a commit to sim642/opam-repository that referenced this pull request Sep 5, 2025
CHANGES:

* Add division by zero analysis (goblint/analyzer#1764).
* Add bitfield domain (goblint/analyzer#1623).
* Add weakly-relational C-2PO pointer analysis (goblint/analyzer#1485).
* Add widening delay (goblint/analyzer#1358, goblint/analyzer#1442, goblint/analyzer#1483).
* Add narrowing of globals to top-down solver (goblint/analyzer#1636).
* Add weak dependencies to top-down solver (goblint/analyzer#1746, goblint/analyzer#1747).
* Add YAML ghost witness generation (goblint/analyzer#1394).
* Remove GraphML witness generation (goblint/analyzer#1732, goblint/analyzer#1733, goblint/analyzer#1738).
* Use C standard option for preprocessing (goblint/analyzer#1807).
* Add bash completion for array options (goblint/analyzer#1670, goblint/analyzer#1705, goblint/analyzer#1750).
* Make `malloc(0)` semantics configurable (goblint/analyzer#1418, goblint/analyzer#1777).
* Update path-sensitive analyses (goblint/analyzer#1785, goblint/analyzer#1791, goblint/analyzer#1792).
* Fix evaluation of library function arguments (goblint/analyzer#1758, goblint/analyzer#1761).
* Optimize affine equalities analysis using sparse matrices (goblint/analyzer#1459, goblint/analyzer#1625).
* Prepare for parallelism (goblint/analyzer#1708, goblint/analyzer#1744, goblint/analyzer#1748, goblint/analyzer#1781, goblint/analyzer#1790).
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.

Printf arguments are not evaluated

3 participants