Skip to content

Make octagon based on Apron useable#196

Merged
sim642 merged 129 commits intomasterfrom
octagon_apron
May 28, 2021
Merged

Make octagon based on Apron useable#196
sim642 merged 129 commits intomasterfrom
octagon_apron

Conversation

@ivanazuzic
Copy link
Copy Markdown
Contributor

@ivanazuzic ivanazuzic commented Apr 22, 2021

  • OctApron analysis and OctApronDomain are added
  • Update_suite.rb distinguishes UNKNOWN (can be unknown) and UNKNOWN! (must be unknown)
  • Base analysis takes into account the assertion results from other analysis that answer to AssertionResult
  • AssertionResult is added as a new query
  • Function signatures regarding ranges of data types are added to the interface of IntDomain.Size
  • zip is moved from base.ml to goblintutil.ml because it's also used from octApron.ml

@sim642
Copy link
Copy Markdown
Member

sim642 commented May 27, 2021

OctApron fails two new tests which I extracted from existing non-apron tests:

Expected unknown!, but registered fail on branch:11
    assert(i == 2); // UNKNOWN!
24/19 octagon/branch failed!

Expected unknown!, but registered success on float:16
    assert(top == top); //UNKNOWN!
24/20 octagon/float failed!

branch

In the branch test, the octApron state in the if is flipped from what it should be! It states [|i-1.>=0; -i+1.>=0|] which essentially is i-1==0. In general the branch function isn't flipped (removing a not makes other octApron tests fail). But I think the issue is in this code:

let rec assert_inv d x b =
try
(* if assert(x) then convert it to assert(x != 0) *)
let x = match x with
| Lval (Var v,NoOffset) when isArithmeticType v.vtype ->
BinOp (Ne, x, (Const (CInt64(Int64.of_int 0, IInt, None))), intType)
| _ -> x in

The != 0 extension shouldn't just be done to single variables, but whatever expression. Making it unconditional causes some stack overflow though. Maybe it needs to be somehow conditional like: if it's already a "boolean" expression, don't do it, otherwise do.

This is quite crucial because it's unsound. By constructing the linear constraint from i-1 it by default means i-1==0 if I understand the Apron stuff correctly.

float

I think octApron also tries to handle floats because Apron supposedly does. But it seems like it's oblivious to NaN, causing the same failure as varEq in #141.

Copy link
Copy Markdown
Member

@sim642 sim642 left a comment

Choose a reason for hiding this comment

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

I think it should be in mergeable condition now. The optional Apron dependency and build seems to work. Octagon tests are skipped by default to not cause failures for anyone who doesn't build with Apron. Nevertheless, they can be explicitly executed (using the group "feature") and the CI also builds with Apron and runs them.

I realized just now that because Apron is included in the opam lockfile, such that the CI would install it for testing, it will also be installed thanks to the lockfile via make dev. So any new developers would still have Apron. But the optional dependency means that this PR at least doesn't cause build failures for existing developers. Not sure if we want to change that (remove apron from lockfile and install apron manually in CI script)?

@sim642 sim642 requested a review from michael-schwarz May 28, 2021 09:16
@vogler
Copy link
Copy Markdown
Collaborator

vogler commented May 28, 2021

I realized just now that because Apron is included in the opam lockfile, such that the CI would install it for testing, it will also be installed thanks to the lockfile via make dev. So any new developers would still have Apron.

You mean make deps (and make setup)?
Does Apron have any extra system dependencies?
If it doesn't complicate installation, it's probably fine to have it in the lockfile.
So it's only optional for a release to opam or if someone installs without --locked?
For CI and benchmarks --locked makes sense, but for user installations we could also do without. That would also test if the package constraints are set right. But maybe not worth dealing with if everyone just installs it in a local switch without problems anyway.

@michael-schwarz
Copy link
Copy Markdown
Member

michael-schwarz commented May 28, 2021

Something else that springs to mind:

What is the relationship with the other octagon analysis made by a student when it comes to the tests?
The tests in folder 24 used to be for that, but now octApron somehow reuses them removing any tests for the old one?
Should the tests for octApron not be their own thing (in a new folder) that leave the other tests alone? (At least until we decide to remove the other octagons?)

@vogler
Copy link
Copy Markdown
Collaborator

vogler commented May 28, 2021

What is the relationship with the other octagon analysis made by a student when it comes to the tests?
The tests in folder 24 used to be for that, but now octApron somehow reuses them removing any tests for the old one?
Should the tests for octApron not be their own thing (in a new folder) that leave the other tests alone? (At least until we decide to remove the other octagons?)

Probably yes.
We should have a way to check the same test with multiple configurations to avoid duplicating files.
Would also be good to run several solvers on the same test. E.g. https://github.com/goblint/analyzer/blob/master/tests/regression/34-localization/01-nested.c should now also be tested with td3 after cf11c4b.

We could just have several lines starting with PARAM: or something like PARAM+: which just appends/overrides the previous config.

@sim642
Copy link
Copy Markdown
Member

sim642 commented May 28, 2021

You mean make deps (and make setup)?
Does Apron have any extra system dependencies?
If it doesn't complicate installation, it's probably fine to have it in the lockfile.

Sorry, yes, make setup. It has the extra libmpfr-dev system dependency, but that's also listed with make setup (and installed in CI), so that shouldn't be a problem.

So it's only optional for a release to opam or if someone installs without --locked?
For CI and benchmarks --locked makes sense, but for user installations we could also do without. That would also test if the package constraints are set right. But maybe not worth dealing with if everyone just installs it in a local switch without problems anyway.

Yes. User installations being without lockfile is an interesting idea too. Because if everyone's using the lockfile, then no dependency will ever get updated and we end up with unnecessarily ancient (and possibly more buggy) versions of things.

What is the relationship with the other octagon analysis made by a student when it comes to the tests?
The tests in folder 24 used to be for that, but now octApron somehow reuses them removing any tests for the old one?
Should the tests for octApron not be their own thing (in a new folder) that leave the other tests alone? (At least until we decide to remove the other octagons?)

Yes, right now all of them are just used to test octApron instead. I can make the octApron tests a separate copy if that's desired. But realistically I think we won't end up maintaining that octagon analysis anyway. And currently the old apronDomain/poly stuff is also around, but given how octApronDomain/octApron is more or less a fixed copy, the old one should probably get removed as well (and the fixed one generalized to any Apron domain eventually).

We should have a way to check the same test with multiple configurations to avoid duplicating files.

I've thought about this for a while. But the octApron case is further complicated by the fact that the availability and testability of its configuration depends on whether apron is installed.

@michael-schwarz
Copy link
Copy Markdown
Member

michael-schwarz commented May 28, 2021

I can make the octApron tests a separate copy if that's desired.

I would go with this for now, given that afaik we have not tested the octApron for anything but toy examples?

But realistically I think we won't end up maintaining that octagon analysis anyway.

I agree. Once we are happy with octApron we probably want to remove the other one.

Ah, just saw you did that already


let branch ctx e b =
if D.is_bot ctx.local then
D.bot ()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why not raise Deadcode?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

To be honest, every one of the transfer functions (already in poly) starts with if D.is_bot ctx.local then D.bot () for some reason. I don't know why this is because transfer functions shouldn't be called on already dead states anyway. For example, we don't do that sort of extra check in base.

Maybe @ivanazuzic knows why (or whether at all) these are necessary.

@sim642 sim642 merged commit 21438cc into master May 28, 2021
@sim642 sim642 deleted the octagon_apron branch May 28, 2021 12:26
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.

4 participants