Skip to content

Value Set Analysis#6

Open
Andre-PierreLamarche wants to merge 90 commits into
acieroid:masterfrom
Andre-PierreLamarche:pointer-analysis
Open

Value Set Analysis#6
Andre-PierreLamarche wants to merge 90 commits into
acieroid:masterfrom
Andre-PierreLamarche:pointer-analysis

Conversation

@Andre-PierreLamarche

Copy link
Copy Markdown

No description provided.

… of memory variable addresses from one store to the other
match bf with
| Top -> false
| Bottom -> true
| Bit {ones = o; zeros = z} -> Int32.(not ((z lor o) = 0b11111111111111111111111111111111l))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

est-ce correct ? Si z = 0b11..11, o = 0b11..11, alors z lor o = 0b11..11, donc (not ((z lor o) = 0b11..11) est faux, et ce n'est pas considéré comme bottom.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Oui c'est correct. En fait, dans ton exemple, si z=0b11111... et o=0b11111..., alors tous les bits sont indéterminés (peuvent être 0 ou 1), donc ça représente toutes les valeurs possibles. C'est donc Top, et non Bottom. C'est donc normal que is_bottom retourne faux. En fait, le calcul (not ((z lor o) = 0b11111111111111111111111111111111l)) retourne vrai ssi il y a un bit qui n'est ni 0 ni 1. Dans ce cas, le bitfield ne représente aucun entier valide et doit être considéré comme bottom.

Comment on lines +128 to +131
let one = Bit {zeros = (-2l); ones = 1l}

let zero = Bit {zeros = (-1l); ones = 0l}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

c'est étrange de définir ça avec (-2l) ou (-1l), utiliser des 0b... serait plus lisible

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Je suis d'accord, je vais changer ça pour une notation hexadécimale

[NegInfinity + Infinity]). *)
let plus (x : t) (y : t) : t =
match x, y with
| Infinity, NegInfinity | NegInfinity, Infinity -> failwith "Invalid_argument \"ExtendedInt.plus: Infinity + NegInfinity is undefined\""

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

plutôt que failwith, tu veux probablement utiliser la fonction invalid_arg : string -> 'a ici qui fait exactement ça

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Merci pour la suggestion, je viens de changer ça

Comment on lines +92 to +95
| ValueSet x, Boolean {numeric_value = y; _} | Boolean {numeric_value = x; _}, ValueSet y -> ValueSet (RIC.join x y)
| ValueSet x, Bitfield y | Bitfield y, ValueSet x -> ValueSet (RIC.join x (RIC.of_bitfield y))
| Boolean {numeric_value = x; _}, Bitfield y
| Bitfield y, Boolean {numeric_value = x; _} -> ValueSet (RIC.join x (RIC.of_bitfield y))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

c'est voulu que meet soit implémenté en terme de join ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Absolument pas. J'ai probablement fait un copier/coller le la fonction join pour garder la structure, et j'ai oublié de changer quelques join en meet. Je viens de corriger.
mais de toute façon, c'était dans les cas qui n'arrivent jamais en pratique.

Comment on lines +751 to +754
| Top, _ | _, Top -> Top
| Bottom, Bottom -> Bottom
| Bottom, _ -> ric2
| _, Bottom -> ric1

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

généralement bottom et absorbant. Il me semble que c'est nécessaire pour la soundness. Ici, bottom + x retourne x plutôt que bottom.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

En effet. Je viens de corriger. Je ne me souviens plus s'il y avait une raison pour que j'aie fait ça comme ça, mais en réalité, dans le reste de l'analyse, je considère que si je tombe sur un Bottom, alors je dois forcément être dans une branche qui est soit le retour d'une boucle pas encore initialisée, ou dans une branche inaccessible. Dans les deux cas, je n'ai certainement pas besoin que Bottom + x soit égal à x, donc je n'avais sans doute pas une raison valable pour implémenter ça ainsi.

Comment on lines +253 to +254
let i32_sub (x : t) (y : t) : t =
i32_add (negative x) y

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

i32_sub x y calcule ((- x) + y), ce qui n'est pas (x - y), c'est voulu ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

c'est louche, en effet, je vais aller voir si j'avais un bon motif pour les inverser

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Je viens de vérifier, et il n'y avait pas d'erreur. Je crois que je l'avais mis dans cet ordre à cause de l'ordre des arguments sur la pile. Si la pile est x::y::_, alors on doit soustraire x à y (x étant au sommet de la pile), raison pour laquelle j'ai mis ça dans cet ordre. Je crois que ça semblait plus naturel comme ça à partir du site d'appel de la fonction. Mais j'avoue que lorsqu'on sort la fonction de son contexte, ça a l'air bizarre de mettre les paramètres dans cet ordre. Crois-tu qu'il serait préférable que j'inverse ça?

[Top] is neutral; [Bottom] is absorbing. *)
let and_ (bf1 : t) (bf2 : t) : t =
match bf1, bf2 with
| Top, x | x, Top -> x

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Il me semble que Top and_ x devrait être Top.
Par exemple, avec un bitfield de taille 1: Top signifie 0b0 ou 0b1. Top and_ 0b1 devrait retourner le join de 0b0 and_ 0b1 (= 0b0) et 0b1 and_ 0b1 (= 0b1), donc ça devrait retourner Top et pas le second argument tel quel,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

faisons un exemple sur 4 bits, avec des X pour signifier 0 ou 1.

par exemple, faisons le and de Top avec une autre valeur x

Top = XXXX
x = 1X01
----------
XX0X

Finalement, le résultat recherché est ni Top, ni x. Je vais aller corriger ça maintenant.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Il en va de même pour le or :

Top = XXXX
x = 01X0
----------
X1XX

j'ai donc modifié les deux fonctions:

let and_ (bf1 : t) (bf2 : t) : t =
match bf1, bf2 with
| Bottom, _ | _, Bottom -> Bottom
| Top, Top -> Top
| Top, Bit {ones; _} | Bit {ones; _}, Top -> Bit {ones; zeros=0xFFFFFFFFl}
| Bit bf1, Bit bf2 ->
Bit {zeros = Int32.(bf1.zeros lor bf2.zeros); ones = Int32.(bf1.ones land bf2.ones)}

let or_ (bf1 : t) (bf2 : t) : t =
match bf1, bf2 with
|Bottom, _ | _, Bottom -> Bottom
| Top, Top -> Top
| Top, Bit {zeros; _} | Bit {zeros; _}, Top -> Bit {ones=0xFFFFFFFFl; zeros}
| Bit bf1, Bit bf2 ->
Bit {zeros = Int32.(bf1.zeros land bf2.zeros);
ones = Int32.(bf1.ones lor bf2.ones)}

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.

2 participants