Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linear Two-Variable Equalities Analysis #1297

Merged
merged 274 commits into from
Mar 25, 2024

Conversation

alina-weber
Copy link
Collaborator

@alina-weber alina-weber commented Dec 17, 2023

Linear Two-Variable Equalities Analysis

This pull request introduces an analysis for linear two variable equalities (ref: A. Flexeder, M. Petter, and H. Seidl Fast Interprocedural Linear Two-Variable Equalities). The structure of the analysis implementation is mostly based on the affine equality analysis (affeq).

The supported equalities are of the form x = y + c, where x is a variable and c is a constant. We also perform partial evaluation in some cases, e.g. when there is an assignment of the form x_1 = x_2 + x_3 - x_4 and we know that x_3 == x_2 and x_4 == x_2, then it follows that x_1 == x_2.

To enable the analysis, the parameter --set ana.activated[+] lin2vareq needs to be added.

Domain

Abstract states in this domain are represented by structs containing an optional array and an apron environment.
The bottom element is represented by a struct with "None" instead of the array.

The arrays are modeled as proposed in the paper: Each variable is assigned to an index and each array element represents a linear relationship that must hold at the corresponding program point.
The apron environment is used to organize the order of columns and variables.

The length of the array always corresponds to the number of variables in the environment.
If for example in the array at index j we store the element (Some i, k), this means that our analysis found out that x_i = x_j + k. If the array entry at index j is (None, k), it means that x_j = k, where k is a constant and x_i and x_j are variables.

Overflow handling

The overflow handling in affeq was spread over multiple files and wasn't very precise. We rewrote it in a more readable way and we exploited the interval analysis to check if there is an overflow in a certain expression.

The query MaySignedOverflow was added to the base analysis to handle possible overflow of signed integer expressions. Each subexpression is analyzed to see if an overflow happened. For each operator in the expression, we use the query EvalInt to approximate the bounds of each operand and we compute if in the worst case there could be an overflow.

This query is used by the domains affeq and lin2vareq in order to find expressions that possibly contain an overflow.

Casting

We found a bug in the analysis affeq, where casts where not properly handled. We fixed the bug for affeq and for our domain.

Refactoring of affeq

In order to have less code duplication, we moved some functions from affineEqualityDomain to sharedFunctions, such that affineEqualityDomain and our linearTwoVarEqualityDomain can both use them.

jennieliangga and others added 30 commits December 6, 2023 00:14
changed the condition for implication of a single equality in 
the less or equal function.
A conjunction of equalities might represent a set of states that is a subset of another set of states and its corresponding representation as a conjunction of equalities.
In particular, an assignment to a variable only consisting of a constant offset implies, say, the trivial equality, which is satisfied for any assignment to the same variable. 
The change correctly classifies this kind of implication.
@michael-schwarz

This comment has been minimized.

@michael-schwarz
Copy link
Member

For unreach-call, we gain 3 successful tasks and lose 3. One of the ones we lose is of this form:

// PARAM: --set ana.activated[+] apron --set sem.int.signed_overflow assume_none --enable ana.int.interval
#include <goblint.h>

int main() {
    unsigned int n, r;
    r = n;

    __goblint_check(r == n); // works
    __goblint_check(-n + r == 0); // does not work

    return 0;
}

This seems justified, as there is an overflow coded into the assertion and our relational analysis in general is not overflow fit.

@michael-schwarz
Copy link
Member

For valid-memsafety we lose 3 tasks.

src/analyses/base.ml Outdated Show resolved Hide resolved
@michael-schwarz
Copy link
Member

I have now started a run for this on server01 so we can verify that we fixed the issue globally. After this, I think it would be a very good idea to land this.

@DrMichaelPetter DrMichaelPetter merged commit f6709dd into goblint:master Mar 25, 2024
12 checks passed
sim642 added a commit that referenced this pull request Mar 26, 2024
sim642 added a commit that referenced this pull request Mar 26, 2024
sim642 added a commit to sim642/opam-repository that referenced this pull request Aug 2, 2024
CHANGES:

* Remove unmaintained analyses: spec, file (goblint/analyzer#1281).
* Add linear two-variable equalities analysis (goblint/analyzer#1297, goblint/analyzer#1412, goblint/analyzer#1466).
* Add callstring, loopfree callstring and context gas analyses (goblint/analyzer#1038, goblint/analyzer#1340, goblint/analyzer#1379, goblint/analyzer#1427, goblint/analyzer#1439).
* Add non-relational thread-modular value analyses with thread IDs (goblint/analyzer#1366, goblint/analyzer#1398, goblint/analyzer#1399).
* Add NULL byte array domain (goblint/analyzer#1076).
* Fix spurious overflow warnings from internal evaluations (goblint/analyzer#1406, goblint/analyzer#1411, goblint/analyzer#1511).
* Refactor non-definite mutex handling to fix unsoundness (goblint/analyzer#1430, goblint/analyzer#1500, goblint/analyzer#1503, goblint/analyzer#1409).
* Fix non-relational thread-modular value analysis unsoundness with ambiguous points-to sets (goblint/analyzer#1457, goblint/analyzer#1458).
* Fix mutex type analysis unsoundness and enable it by default (goblint/analyzer#1414, goblint/analyzer#1416, goblint/analyzer#1510).
* Add points-to set refinement on mutex path splitting (goblint/analyzer#1287, goblint/analyzer#1343, goblint/analyzer#1374, goblint/analyzer#1396, goblint/analyzer#1407).
* Improve narrowing operators (goblint/analyzer#1502, goblint/analyzer#1540, goblint/analyzer#1543).
* Extract automatic configuration tuning for soundness (goblint/analyzer#1369).
* Fix many locations in witnesses (goblint/analyzer#1355, goblint/analyzer#1372, goblint/analyzer#1400, goblint/analyzer#1403).
* Improve output readability (goblint/analyzer#1294, goblint/analyzer#1312, goblint/analyzer#1405, goblint/analyzer#1497).
* Refactor logging (goblint/analyzer#1117).
* Modernize all library function specifications (goblint/analyzer#1029, goblint/analyzer#688, goblint/analyzer#1174, goblint/analyzer#1289, goblint/analyzer#1447, goblint/analyzer#1487).
* Remove OCaml 4.10, 4.11, 4.12 and 4.13 support (goblint/analyzer#1448).
avsm pushed a commit to avsm/opam-repository that referenced this pull request Sep 5, 2024
CHANGES:

* Remove unmaintained analyses: spec, file (goblint/analyzer#1281).
* Add linear two-variable equalities analysis (goblint/analyzer#1297, goblint/analyzer#1412, goblint/analyzer#1466).
* Add callstring, loopfree callstring and context gas analyses (goblint/analyzer#1038, goblint/analyzer#1340, goblint/analyzer#1379, goblint/analyzer#1427, goblint/analyzer#1439).
* Add non-relational thread-modular value analyses with thread IDs (goblint/analyzer#1366, goblint/analyzer#1398, goblint/analyzer#1399).
* Add NULL byte array domain (goblint/analyzer#1076).
* Fix spurious overflow warnings from internal evaluations (goblint/analyzer#1406, goblint/analyzer#1411, goblint/analyzer#1511).
* Refactor non-definite mutex handling to fix unsoundness (goblint/analyzer#1430, goblint/analyzer#1500, goblint/analyzer#1503, goblint/analyzer#1409).
* Fix non-relational thread-modular value analysis unsoundness with ambiguous points-to sets (goblint/analyzer#1457, goblint/analyzer#1458).
* Fix mutex type analysis unsoundness and enable it by default (goblint/analyzer#1414, goblint/analyzer#1416, goblint/analyzer#1510).
* Add points-to set refinement on mutex path splitting (goblint/analyzer#1287, goblint/analyzer#1343, goblint/analyzer#1374, goblint/analyzer#1396, goblint/analyzer#1407).
* Improve narrowing operators (goblint/analyzer#1502, goblint/analyzer#1540, goblint/analyzer#1543).
* Extract automatic configuration tuning for soundness (goblint/analyzer#1369).
* Fix many locations in witnesses (goblint/analyzer#1355, goblint/analyzer#1372, goblint/analyzer#1400, goblint/analyzer#1403).
* Improve output readability (goblint/analyzer#1294, goblint/analyzer#1312, goblint/analyzer#1405, goblint/analyzer#1497).
* Refactor logging (goblint/analyzer#1117).
* Modernize all library function specifications (goblint/analyzer#1029, goblint/analyzer#688, goblint/analyzer#1174, goblint/analyzer#1289, goblint/analyzer#1447, goblint/analyzer#1487).
* Remove OCaml 4.10, 4.11, 4.12 and 4.13 support (goblint/analyzer#1448).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature precision relational Relational analyses (Apron, affeq, lin2var) student-job
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants