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

Split Class into ByReferenceClass and ByValueClass #1227

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d52394f
Create separate classes for by reference and by value classes
superaxander May 14, 2024
b01df4d
Use ADT encoding for ByValueClasses
superaxander Jun 11, 2024
1666b35
Add some axioms that speed up pointer verification
superaxander Jun 17, 2024
0dfde7c
Do no copy in expressions which do not yield TByValueClass
superaxander Jun 18, 2024
be64b27
Enable use of methods on by-value classes
superaxander Jun 18, 2024
aed3ba6
Set --useOldAxiomatization to test which test failures are because of…
superaxander Jun 19, 2024
53f19a8
Improve struct encoding, rewrite tests for new permission syntax
superaxander Jul 18, 2024
7b50ef3
Make the pointer for struct fields implicit simplifying most locations
superaxander Jul 19, 2024
28eaee6
Merge remote-tracking branch 'origin/dev' into class-by-value
superaxander Jul 19, 2024
1a31edd
Fix the type numbers
superaxander Jul 19, 2024
3f9f02b
Replaced type numbers with constants for ByValueClass
superaxander Jul 19, 2024
bcd96b5
Temporarily set a fork of silicon in build.sc to test in CI
superaxander Jul 19, 2024
24197b8
Update silver, clean up unused ByValueClass axioms
superaxander Jul 23, 2024
653cd5f
First working version pointer casts
superaxander Jul 24, 2024
88305b8
Also get rid of casts from Object to another class
superaxander Jul 24, 2024
d736fdd
Ignore quantifier in SimplifyNestedQuantifiers if it has a trigger an…
superaxander Jul 25, 2024
2615361
Fix compilation error
superaxander Jul 25, 2024
6c8be0a
Reduce code duplication in adtPointer, remove all non-pointer casts i…
superaxander Jul 25, 2024
e141bcf
Fix duplicate OptGet and add asType function to primitive pointer arrays
superaxander Jul 25, 2024
401c3d9
Get rid of more 'unknown' names in the C frontend
superaxander Jul 25, 2024
a1773b7
Remove Viper field access from trigger with top-level PointerSubscrip…
superaxander Jul 25, 2024
98dde38
Merge remote-tracking branch 'origin/dev' into class-by-value
superaxander Aug 19, 2024
42aca99
Implement basic pointer casts
superaxander Aug 21, 2024
9b96b33
Add pointer cast helpers in loops
superaxander Aug 22, 2024
800f1dd
Add type checking for pointer casts
superaxander Aug 22, 2024
c7a723e
Add back blame erroneously removed by the previous commit
superaxander Aug 22, 2024
f025706
Fix unsupported cast test
superaxander Aug 26, 2024
d85b6b4
Fix unsoundness in pointer cast encoding
superaxander Sep 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ object external extends Module {
object viper extends ScalaModule {
object silverGit extends GitModule {
def url = T { "https://github.com/viperproject/silver.git" }
def commitish = T { "4a8065758868eae3414f86f3d96e843a283444fc" }
def commitish = T { "93bc9b7516a710c8f01438e430058c4a54e20512" }
def filteredRepo = T {
val workspace = repo()
os.remove.all(workspace / "src" / "test")
Expand All @@ -50,8 +50,8 @@ object viper extends ScalaModule {
}

object siliconGit extends GitModule {
def url = T { "https://github.com/viperproject/silicon.git" }
def commitish = T { "4033dd21614b3bbba9c7615655e41c6cf0b9d80b" }
def url = T { "https://github.com/superaxander/silicon.git" }
def commitish = T { "c63989f64eb759f33bde68c330ce07d6e34134fa" }
def filteredRepo = T {
val workspace = repo()
os.remove.all(workspace / "src" / "test")
Expand Down
90 changes: 90 additions & 0 deletions examples/concepts/c/pointer_casts.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <stdbool.h>

struct A {
int integer;
bool boolean;
};

struct B {
struct A struct_a;
};

void canCastToInteger() {
struct B struct_b;
struct_b.struct_a.integer = 5;
int *pointer_to_integer = (int *)&struct_b;
//@ assert *pointer_to_integer == 5;
//@ assert pointer_to_integer == &struct_b.struct_a.integer;
//@ assert pointer_to_integer == (int *)&struct_b.struct_a;
// The following is not implemented yet
// assert pointer_to_integer == &struct_b
// assert pointer_to_integer == &struct_b.struct_a
*pointer_to_integer = 10;
//@ assert struct_b.struct_a.integer == 10;
}


void castRemainsValidInLoop() {
struct B struct_b;
struct_b.struct_a.integer = 10;

int *pointer_to_integer = (int *)&struct_b;

//@ loop_invariant 0 <= i && i <= 10;
//@ loop_invariant Perm(&struct_b, write);
//@ loop_invariant Perm(struct_b, write);
//@ loop_invariant pointer_to_integer == (int *)&struct_b;
//@ loop_invariant *pointer_to_integer == 10 - i;
for (int i = 0; i < 10; i++) {
*pointer_to_integer = *pointer_to_integer - 1;
}

//@ assert struct_b.struct_a.integer == 0;
struct_b.struct_a.integer = 10;

// We can also specify the permission through the pointer
//@ loop_invariant 0 <= i && i <= 10;
//@ loop_invariant Perm(pointer_to_integer, write);
//@ loop_invariant *pointer_to_integer == 10 - i;
for (int i = 0; i < 10; i++) {
*pointer_to_integer = *pointer_to_integer - 1;
}

//@ assert struct_b.struct_a.integer == 0;
}

void castRemainsValidInParBlock() {
struct B struct_b;
struct_b.struct_a.integer = 10;

int *pointer_to_integer = (int *)&struct_b;

//@ context i == 8 ==> Perm(pointer_to_integer, write);
//@ ensures i == 8 ==> *pointer_to_integer == 0;
for (int i = 0; i < 10; i++) {
if (i == 8) {
*pointer_to_integer = *pointer_to_integer - 10;
}
}

// Unfortunately we don't support a par block where we specify permission to the struct and then access through the cast (the generated cast helper is put too far away)

//@ assert struct_b.struct_a.integer == 0;
}

//@ requires a != NULL;
//@ context Perm(a, write);
//@ ensures *a == \old(*a) + 1;
void increaseByOne(int *a) {
*a += 1;
}

void callWithCast() {
struct B struct_b;
struct_b.struct_a.integer = 15;

int *pointer_to_integer = (int *)&struct_b;
increaseByOne(pointer_to_integer);

//@ assert struct_b.struct_a.integer == 16;
}
15 changes: 8 additions & 7 deletions examples/concepts/c/structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ struct linked_list{

/*@
context p != NULL ** Perm(p, write);
context Perm(p->x, write);
context Perm(p->y, write);
context Perm(&p->x, write);
context Perm(&p->y, write);
ensures p->x == 0;
ensures p->y == 0;
ensures \old(*p) == *p;
Expand All @@ -44,14 +44,15 @@ void alter_struct_1(struct point *p){
}

/*@
context Perm(p.x, 1\1);
context Perm(p.y, 1\1);
context Perm(&p.x, 1\1);
context Perm(&p.y, 1\1);
@*/
void alter_copy_struct(struct point p){
p.x = 0;
p.y = 0;
}

// TODO: Should be auto-generated
/*@
context Perm(p, 1\1);
@*/
Expand All @@ -75,7 +76,7 @@ int avr_x(struct triangle *r){
requires inp != NULL && \pointer_length(inp) >= n;
requires (\forall* int i; 0 <= i && i < n; Perm(&inp[i], 1\10));
requires (\forall int i, int j; 0<=i && i<n && 0<=j && j<n; i != j ==> {:inp[i]:} != {:inp[j]:});
requires (\forall* int i; 0 <= i && i < n; Perm(inp[i].x, 1\10));
requires (\forall* int i; 0 <= i && i < n; Perm(&inp[i].x, 1\10));
ensures |\result| == n;
ensures (\forall int i; 0 <= i && i < n; \result[i] == inp[i].x);
//ensures n>0 ==> \result == inp_to_seq(inp, n-1) + [inp[n-1].x];
Expand Down Expand Up @@ -132,7 +133,7 @@ int main(){
struct point *pp;
pp = &p;

//@ assert (pp[0] != NULL );
/* //@ assert (pp[0] != NULL ); */
assert (pp != NULL );

p.x = 1;
Expand Down Expand Up @@ -168,4 +169,4 @@ int main(){
assert(avr_pol == 2);

return 0;
}
}
7 changes: 6 additions & 1 deletion res/universal/res/adt/pointer.pvl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ adt `pointer` {
pure `pointer` pointer_of(`block` b, int offset);
pure `block` pointer_block(`pointer` p);
pure int pointer_offset(`pointer` p);
pure `pointer` pointer_inv(ref r);

// the block offset is valid wrt the length of the block
axiom (∀ `pointer` p;
Expand All @@ -26,6 +27,10 @@ adt `pointer` {
axiom (∀`block` b, int offset;
{:pointer_block(pointer_of(b, offset)):} == b &&
{:pointer_offset(pointer_of(b, offset)):} == offset);

axiom (∀ ref r; ptr_deref({:pointer_inv(r):}) == r);

axiom (∀ `pointer` p; pointer_inv({:ptr_deref(p):}) == p);
}

decreases;
Expand All @@ -38,4 +43,4 @@ requires `pointer`.pointer_offset(p) + offset < `block`.block_length(`pointer`.p
pure `pointer` ptr_add(`pointer` p, int offset) =
`pointer`.pointer_of(
`pointer`.pointer_block(p),
`pointer`.pointer_offset(p) + offset);
`pointer`.pointer_offset(p) + offset);
Loading
Loading