Commit 8ca9d1b9 authored by Rodolphe Lepigre's avatar Rodolphe Lepigre Committed by Michael Sammler
Browse files

Progress towards tracking pointer provenance in integers

parent d10403a3
Pipeline #45749 passed with stage
in 29 minutes and 4 seconds
...@@ -2,19 +2,49 @@ ...@@ -2,19 +2,49 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
[[rc::args("&own<int<i32>>")]] //@rc::inlined
[[rc::returns("int<size_t>")]] //@Notation "P ? l : r" :=
size_t int_ptr(int* p){ //@ (if bool_decide P then l else r)
size_t i = (size_t) p; //@ (at level 100, l at next level, r at next level).
//@rc::end
/**** Casting a pointer to an integer ***************************************/
// Cast a pointer to an integer, keeping the provenance.
[[rc::parameters("l : loc")]]
[[rc::args("l @ &own<int<i32>>")]]
[[rc::returns("l @ intptr<uintptr_t>")]]
uintptr_t int_ptr1(int* p){
uintptr_t i = (uintptr_t) p;
// return (i + 0); ← Does not work (provenance dropped by arithmetic).
return i;
}
// Cast a pointer to an integer, but losing the provenance.
[[rc::parameters("l : loc")]]
[[rc::args("l @ &own<int<i32>>")]]
[[rc::returns("{l.2} @ int<uintptr_t>")]]
uintptr_t int_ptr2(int* p){
uintptr_t i = (uintptr_t) p;
return i; return i;
} }
// Cast a pointer to an integer, but losing the provenance.
[[rc::parameters("l : loc")]]
[[rc::args("l @ &own<int<i32>>")]]
[[rc::returns("{l.2} @ int<uintptr_t>")]]
uintptr_t int_ptr3(int* p){
uintptr_t i = (uintptr_t) p;
return i + 0; // ← We can do arithmetic (provenance not required).
}
// Weird function working on integers obtained from pointers.
[[rc::parameters("p1 : loc", "p2 : loc")]] [[rc::parameters("p1 : loc", "p2 : loc")]]
[[rc::args("p1 @ &own<int<i32>>", "p2 @ &own<int<i32>>")]] [[rc::args("p1 @ &own<int<i32>>", "p2 @ &own<int<i32>>")]]
[[rc::returns("{p1.2 `min` p2.2} @ int<size_t>")]] [[rc::returns("{p1.2 `min` p2.2} @ int<uintptr_t>")]]
size_t min_ptr_val(int *p1, int *p2){ uintptr_t min_ptr_val1(int *p1, int *p2){
size_t i1 = (size_t) p1; uintptr_t i1 = (uintptr_t) p1;
size_t i2 = (size_t) p2; uintptr_t i2 = (uintptr_t) p2;
if(i1 <= i2){ if(i1 <= i2){
return i1; return i1;
...@@ -23,53 +53,106 @@ size_t min_ptr_val(int *p1, int *p2){ ...@@ -23,53 +53,106 @@ size_t min_ptr_val(int *p1, int *p2){
return i2; return i2;
} }
// The same but keeping the provenance.
[[rc::parameters("p1 : loc", "p2 : loc")]]
[[rc::args("p1 @ &own<int<i32>>", "p2 @ &own<int<i32>>")]]
[[rc::returns("{p1.2 ≤ p2.2 ? p1 : p2} @ intptr<uintptr_t>")]]
uintptr_t min_ptr_val2(int *p1, int *p2){
uintptr_t i1 = (uintptr_t) p1;
uintptr_t i2 = (uintptr_t) p2;
if(i1 <= i2){
return i1;
}
return i2;
}
/**** Casting an integer to a pointer ***************************************/
// Simple roundtrip cast.
[[rc::parameters("p : loc")]] [[rc::parameters("p : loc")]]
[[rc::args("p @ &own<int<i32>>")]] [[rc::args("p @ &own<int<i32>>")]]
[[rc::returns("{(None, p.2)} @ &own<place<{(None, p.2)}>>")]] [[rc::returns("p @ &own<place<p>>")]]
int* roundtrip1(int* p){ int* roundtrip1(int* p){
size_t i = (size_t) p; uintptr_t i = (uintptr_t) p;
void *q = (void*) i; void *q = (void*) i; // ← The provenance transfered back.
return q;
}
// Roundtrip cast with dummy arithmetic.
[[rc::parameters("p : loc")]]
[[rc::args("p @ &own<int<i32>>")]]
[[rc::exists("id : {option alloc_id}")]] // ← Only ∃ on provenance.
[[rc::returns("{(id, p.2)} @ &own<place<{(id, p.2)}>>")]]
int* roundtrip2(int* p){
uintptr_t i = (uintptr_t) p;
void *q = (void*) (i + 0); // ← The provenance is lost here.
return q; return q;
} }
// Roundtrip cast with dummy arithmetic and provenance recovery.
[[rc::parameters("p : loc", "n : Z")]] [[rc::parameters("p : loc", "n : Z")]]
[[rc::args("p @ &own<n @ int<i32>>")]] [[rc::args("p @ &own<n @ int<i32>>")]]
[[rc::returns("p @ &own<n @ int<i32>>")]] [[rc::returns("p @ &own<n @ int<i32>>")]]
[[rc::tactics("all: try solve_loc_eq.")]] int* roundtrip3(int* p){
int* roundtrip2(int* p){ uintptr_t i = (uintptr_t) p;
size_t i = (size_t) p; int *q = (void*) (i + 0); // ← The provenance is lost here.
int *q = (void*) i; return rc_copy_alloc_id(q, p); // ← Copy provenance from [p].
return rc_copy_alloc_id(q, p);
} }
// Roundrip cast with flow of ownership.
[[rc::parameters("l : loc", "n : Z")]] [[rc::parameters("l : loc", "n : Z")]]
[[rc::args("l @ &own<n @ int<i32>>")]] [[rc::args("l @ &own<n @ int<i32>>")]]
[[rc::returns("n @ int<i32>")]] [[rc::returns("n @ int<i32>")]]
[[rc::ensures("own l : n @ int<i32>")]] [[rc::ensures("own l : n @ int<i32>")]]
int roundtrip_and_read(int* p){ int roundtrip_and_read1(int* p){
size_t i = (size_t) p; uintptr_t i = (uintptr_t) p;
int *q = (int*) i; int *q = (int*) i;
int r = *q;
return r;
}
// Roundrip cast with flow of ownership and provenance recovery.
[[rc::parameters("l : loc", "n : Z")]]
[[rc::args("l @ &own<n @ int<i32>>")]]
[[rc::returns("n @ int<i32>")]]
[[rc::ensures("own l : n @ int<i32>")]]
int roundtrip_and_read2(int* p){
uintptr_t i = (uintptr_t) p;
int *q = (int*) (i * 1);
q = rc_copy_alloc_id(q, p); q = rc_copy_alloc_id(q, p);
int r = *q; int r = *q;
return r; return r;
} }
// Small variation in syntax (for testing).
[[rc::parameters("p : loc", "n : Z")]] [[rc::parameters("p : loc", "n : Z")]]
[[rc::args("p @ &own<n @ int<i32>>")]] [[rc::args("p @ &own<n @ int<i32>>")]]
[[rc::returns("n @ int<i32>")]] [[rc::returns("n @ int<i32>")]]
[[rc::ensures("own p : n @ int<i32>")]] [[rc::ensures("own p : n @ int<i32>")]]
int roundtrip_and_read2(int* p){ int roundtrip_and_read3(int* p){
uintptr_t i = (uintptr_t) p; uintptr_t i = (uintptr_t) p;
int *q = rc_copy_alloc_id((int*) i, p); int *q = rc_copy_alloc_id((int*) (i * 1), p);
return *q; return *q;
} }
// Another variant of the same example.
[[rc::parameters("p : loc", "n : Z")]] [[rc::parameters("p : loc", "n : Z")]]
[[rc::args("p @ &own<n @ int<i32>>")]] [[rc::args("p @ &own<n @ int<i32>>")]]
[[rc::returns("n @ int<i32>")]] [[rc::returns("n @ int<i32>")]]
[[rc::ensures("own p : n @ int<i32>")]] [[rc::ensures("own p : n @ int<i32>")]]
int roundtrip_and_read3(int* p){ int roundtrip_and_read4(int* p){
size_t i = (size_t) p; uintptr_t i = (uintptr_t) p;
int *q = (int*) i; int *q = (int*) (i * 1);
return *(rc_copy_alloc_id(q, p)); return *(rc_copy_alloc_id(q, p));
} }
// Copy the provenance from an int.
[[rc::parameters("p : loc")]]
[[rc::args("p @ intptr<uintptr_t>")]]
[[rc::returns("p @ &own<place<p>>")]]
void* int_to_ptr(uintptr_t p){
void *q = (void*) (p * 1);
return (rc_copy_alloc_id(q, p));
}
...@@ -111,7 +111,7 @@ size_t fsm_slot_for_key(size_t len, size_t key) { ...@@ -111,7 +111,7 @@ size_t fsm_slot_for_key(size_t len, size_t key) {
[[rc::ensures("{∃ x, items !! n = Some x ∧ probe_ref key items = Some (n, x)}")]] [[rc::ensures("{∃ x, items !! n = Some x ∧ probe_ref key items = Some (n, x)}")]]
[[rc::lemmas("lookup_lt_is_Some_2")]] [[rc::lemmas("lookup_lt_is_Some_2")]]
[[rc::tactics("all: try by eexists _; split => //; apply probe_ref_take_Some; naive_solver.")]] [[rc::tactics("all: try by eexists _; split => //; apply probe_ref_take_Some; naive_solver.")]]
[[rc::tactics("all: try by apply: probe_ref_go_next_take=> //i; intros Hi%lookup_rotate_r_Some; try lia; simplify_eq; naive_solver.")]] [[rc::tactics("all: try by apply: probe_ref_go_next_take => // ? /lookup_rotate_r_Some ?; try lia; simplify_eq; naive_solver.")]]
size_t fsm_probe(struct fixed_size_map *m, size_t key) { size_t fsm_probe(struct fixed_size_map *m, size_t key) {
size_t slot_idx = fsm_slot_for_key(m->length, key); size_t slot_idx = fsm_slot_for_key(m->length, key);
......
This diff is collapsed.
...@@ -4,23 +4,23 @@ From refinedc.examples.intptr Require Import generated_spec. ...@@ -4,23 +4,23 @@ From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type". Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *) (* Generated from [examples/intptr.c]. *)
Section proof_int_ptr. Section proof_int_ptr1.
Context `{!typeG Σ} `{!globalG Σ}. Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [int_ptr]. *) (* Typing proof for [int_ptr1]. *)
Lemma type_int_ptr : Lemma type_int_ptr1 :
typed_function impl_int_ptr type_of_int_ptr. typed_function impl_int_ptr1 type_of_int_ptr1.
Proof. Proof.
Open Scope printing_sugar. Open Scope printing_sugar.
start_function "int_ptr" ([]) => arg_p local_i. start_function "int_ptr1" (l) => arg_p local_i.
split_blocks (( split_blocks ((
)%I : gmap label (iProp Σ)) (( )%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)). )%I : gmap label (iProp Σ)).
- repeat liRStep; liShow. - repeat liRStep; liShow.
all: print_typesystem_goal "int_ptr" "#0". all: print_typesystem_goal "int_ptr1" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook. Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "int_ptr". all: print_sidecondition_goal "int_ptr1".
Qed. Qed.
End proof_int_ptr. End proof_int_ptr1.
...@@ -4,23 +4,23 @@ From refinedc.examples.intptr Require Import generated_spec. ...@@ -4,23 +4,23 @@ From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type". Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *) (* Generated from [examples/intptr.c]. *)
Section proof_min_ptr_val. Section proof_int_ptr2.
Context `{!typeG Σ} `{!globalG Σ}. Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [min_ptr_val]. *) (* Typing proof for [int_ptr2]. *)
Lemma type_min_ptr_val : Lemma type_int_ptr2 :
typed_function impl_min_ptr_val type_of_min_ptr_val. typed_function impl_int_ptr2 type_of_int_ptr2.
Proof. Proof.
Open Scope printing_sugar. Open Scope printing_sugar.
start_function "min_ptr_val" ([p1 p2]) => arg_p1 arg_p2 local_i2 local_i1. start_function "int_ptr2" (l) => arg_p local_i.
split_blocks (( split_blocks ((
)%I : gmap label (iProp Σ)) (( )%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)). )%I : gmap label (iProp Σ)).
- repeat liRStep; liShow. - repeat liRStep; liShow.
all: print_typesystem_goal "min_ptr_val" "#0". all: print_typesystem_goal "int_ptr2" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook. Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "min_ptr_val". all: print_sidecondition_goal "int_ptr2".
Qed. Qed.
End proof_min_ptr_val. End proof_int_ptr2.
...@@ -4,23 +4,23 @@ From refinedc.examples.intptr Require Import generated_spec. ...@@ -4,23 +4,23 @@ From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type". Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *) (* Generated from [examples/intptr.c]. *)
Section proof_roundtrip_and_read. Section proof_int_ptr3.
Context `{!typeG Σ} `{!globalG Σ}. Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [roundtrip_and_read]. *) (* Typing proof for [int_ptr3]. *)
Lemma type_roundtrip_and_read : Lemma type_int_ptr3 :
typed_function impl_roundtrip_and_read type_of_roundtrip_and_read. typed_function impl_int_ptr3 type_of_int_ptr3.
Proof. Proof.
Open Scope printing_sugar. Open Scope printing_sugar.
start_function "roundtrip_and_read" ([l n]) => arg_p local_i local_r local_q. start_function "int_ptr3" (l) => arg_p local_i.
split_blocks (( split_blocks ((
)%I : gmap label (iProp Σ)) (( )%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)). )%I : gmap label (iProp Σ)).
- repeat liRStep; liShow. - repeat liRStep; liShow.
all: print_typesystem_goal "roundtrip_and_read" "#0". all: print_typesystem_goal "int_ptr3" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook. Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "roundtrip_and_read". all: print_sidecondition_goal "int_ptr3".
Qed. Qed.
End proof_roundtrip_and_read. End proof_int_ptr3.
From refinedc.typing Require Import typing.
From refinedc.examples.intptr Require Import generated_code.
From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *)
Section proof_int_to_ptr.
Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [int_to_ptr]. *)
Lemma type_int_to_ptr :
typed_function impl_int_to_ptr type_of_int_to_ptr.
Proof.
Open Scope printing_sugar.
start_function "int_to_ptr" (p) => arg_p local_q.
split_blocks ((
)%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)).
- repeat liRStep; liShow.
all: print_typesystem_goal "int_to_ptr" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "int_to_ptr".
Qed.
End proof_int_to_ptr.
From refinedc.typing Require Import typing.
From refinedc.examples.intptr Require Import generated_code.
From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *)
Section proof_min_ptr_val1.
Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [min_ptr_val1]. *)
Lemma type_min_ptr_val1 :
typed_function impl_min_ptr_val1 type_of_min_ptr_val1.
Proof.
Open Scope printing_sugar.
start_function "min_ptr_val1" ([p1 p2]) => arg_p1 arg_p2 local_i2 local_i1.
split_blocks ((
)%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)).
- repeat liRStep; liShow.
all: print_typesystem_goal "min_ptr_val1" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "min_ptr_val1".
Qed.
End proof_min_ptr_val1.
From refinedc.typing Require Import typing.
From refinedc.examples.intptr Require Import generated_code.
From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *)
Section proof_min_ptr_val2.
Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [min_ptr_val2]. *)
Lemma type_min_ptr_val2 :
typed_function impl_min_ptr_val2 type_of_min_ptr_val2.
Proof.
Open Scope printing_sugar.
start_function "min_ptr_val2" ([p1 p2]) => arg_p1 arg_p2 local_i2 local_i1.
split_blocks ((
)%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)).
- repeat liRStep; liShow.
all: print_typesystem_goal "min_ptr_val2" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "min_ptr_val2".
Qed.
End proof_min_ptr_val2.
...@@ -12,7 +12,7 @@ Section proof_roundtrip2. ...@@ -12,7 +12,7 @@ Section proof_roundtrip2.
typed_function impl_roundtrip2 type_of_roundtrip2. typed_function impl_roundtrip2 type_of_roundtrip2.
Proof. Proof.
Open Scope printing_sugar. Open Scope printing_sugar.
start_function "roundtrip2" ([p n]) => arg_p local_i local_q. start_function "roundtrip2" (p) => arg_p local_i local_q.
split_blocks (( split_blocks ((
)%I : gmap label (iProp Σ)) (( )%I : gmap label (iProp Σ)) ((
...@@ -21,7 +21,6 @@ Section proof_roundtrip2. ...@@ -21,7 +21,6 @@ Section proof_roundtrip2.
- repeat liRStep; liShow. - repeat liRStep; liShow.
all: print_typesystem_goal "roundtrip2" "#0". all: print_typesystem_goal "roundtrip2" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook. Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: try solve_loc_eq.
all: print_sidecondition_goal "roundtrip2". all: print_sidecondition_goal "roundtrip2".
Qed. Qed.
End proof_roundtrip2. End proof_roundtrip2.
From refinedc.typing Require Import typing.
From refinedc.examples.intptr Require Import generated_code.
From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *)
Section proof_roundtrip3.
Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [roundtrip3]. *)
Lemma type_roundtrip3 :
typed_function impl_roundtrip3 type_of_roundtrip3.
Proof.
Open Scope printing_sugar.
start_function "roundtrip3" ([p n]) => arg_p local_i local_q.
split_blocks ((
)%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)).
- repeat liRStep; liShow.
all: print_typesystem_goal "roundtrip3" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "roundtrip3".
Qed.
End proof_roundtrip3.
From refinedc.typing Require Import typing.
From refinedc.examples.intptr Require Import generated_code.
From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *)
Section proof_roundtrip_and_read1.
Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [roundtrip_and_read1]. *)
Lemma type_roundtrip_and_read1 :
typed_function impl_roundtrip_and_read1 type_of_roundtrip_and_read1.
Proof.
Open Scope printing_sugar.
start_function "roundtrip_and_read1" ([l n]) => arg_p local_i local_r local_q.
split_blocks ((
)%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)).
- repeat liRStep; liShow.
all: print_typesystem_goal "roundtrip_and_read1" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "roundtrip_and_read1".
Qed.
End proof_roundtrip_and_read1.
...@@ -12,7 +12,7 @@ Section proof_roundtrip_and_read2. ...@@ -12,7 +12,7 @@ Section proof_roundtrip_and_read2.
typed_function impl_roundtrip_and_read2 type_of_roundtrip_and_read2. typed_function impl_roundtrip_and_read2 type_of_roundtrip_and_read2.
Proof. Proof.
Open Scope printing_sugar. Open Scope printing_sugar.
start_function "roundtrip_and_read2" ([p n]) => arg_p local_i local_q. start_function "roundtrip_and_read2" ([l n]) => arg_p local_i local_r local_q.
split_blocks (( split_blocks ((
)%I : gmap label (iProp Σ)) (( )%I : gmap label (iProp Σ)) ((
......
From refinedc.typing Require Import typing.
From refinedc.examples.intptr Require Import generated_code.
From refinedc.examples.intptr Require Import generated_spec.
Set Default Proof Using "Type".
(* Generated from [examples/intptr.c]. *)
Section proof_roundtrip_and_read4.
Context `{!typeG Σ} `{!globalG Σ}.
(* Typing proof for [roundtrip_and_read4]. *)
Lemma type_roundtrip_and_read4 :
typed_function impl_roundtrip_and_read4 type_of_roundtrip_and_read4.
Proof.
Open Scope printing_sugar.
start_function "roundtrip_and_read4" ([p n]) => arg_p local_i local_q.
split_blocks ((
)%I : gmap label (iProp Σ)) ((
)%I : gmap label (iProp Σ)).
- repeat liRStep; liShow.
all: print_typesystem_goal "roundtrip_and_read4" "#0".
Unshelve. all: sidecond_hook; prepare_sideconditions; normalize_and_simpl_goal; try solve_goal; unsolved_sidecond_hook.
all: print_sidecondition_goal "roundtrip_and_read4".
Qed.
End proof_roundtrip_and_read4.
...@@ -6,40 +6,76 @@ Set Default Proof Using "Type". ...@@ -6,40 +6,76 @@ Set Default Proof Using "Type".
Section spec. Section spec.
Context `{!typeG Σ} `{!globalG Σ}.