Skip to content

Commit dd9b62e

Browse files
Add immutable for primitive values (#32)
## Description Primitive values had annotation of `SHARED` which would prevent us to add other primitive values in calls to Unique objects. Now they are `IMMUTABLE`, they could also be just `PRIMITIVE` that would mean the same. This annotation is NOT available to be used, is used only internally to identify the permissions of these primitive variables. ## Example ```java class PQNode{ PQNode(int value, @free PQNode next) { this.value = value; this.next = next; } int value; @unique PQNode next; void insert(int v) { if (v < this.value) { PQNode nxt = this.next; this.next = null; PQNode newNode = new PQNode(this.value, nxt); // would be an error because this.value would be shared, now is possible and this example passes ``` ## Type of change - [x] Bug fix - [x] New feature - [ ] Documentation update - [ ] Code refactoring ## How Has This Been Tested? Added a test
1 parent 378fcd5 commit dd9b62e

File tree

6 files changed

+60
-6
lines changed

6 files changed

+60
-6
lines changed

latte/src/main/java/context/PermissionEnvironment.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ public boolean usePermissionAs(SymbolicValue v, UniquenessAnnotation vPerm, Uniq
117117
return true;
118118
}
119119
break;
120+
case IMMUTABLE:
121+
if (vPerm.isGreaterEqualThan(Uniqueness.IMMUTABLE)){
122+
return true;
123+
}
124+
break;
120125
case SHARED:
121126
if (vPerm.annotationEquals(Uniqueness.SHARED) || vPerm.annotationEquals(Uniqueness.FREE)){
122127
add(v, new UniquenessAnnotation(Uniqueness.SHARED));

latte/src/main/java/context/Uniqueness.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ public enum Uniqueness {
55
SHARED (2),
66
UNIQUE (3),
77
BORROWED (4),
8-
FREE (5);
8+
IMMUTABLE(5),
9+
FREE (6);
910
// ALIAS (6),
1011

1112
private final int order;

latte/src/main/java/context/UniquenessAnnotation.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
import spoon.reflect.declaration.CtAnnotation;
66
import spoon.reflect.declaration.CtElement;
7+
import spoon.reflect.declaration.CtTypedElement;
8+
import spoon.reflect.reference.CtTypeReference;
79

810
/**
911
* Matched the annotation to the uniqueness enum type type
@@ -30,9 +32,19 @@ else if (an.contentEquals("specification.Free")) {
3032
}
3133

3234
}
35+
if (element instanceof CtTypedElement){ // TODO: change for typed param here when changing java version
36+
CtTypedElement<?> typed = (CtTypedElement<?>) element;
37+
CtTypeReference<?> typeRef = typed.getType();
38+
if(typeRef != null && typeRef.isPrimitive())
39+
this.annotation = Uniqueness.IMMUTABLE;
40+
}
3341
if (annotation == null) this.annotation = Uniqueness.SHARED; //Default
3442
}
3543

44+
public static UniquenessAnnotation forPrimitives() {
45+
return new UniquenessAnnotation(Uniqueness.IMMUTABLE);
46+
}
47+
3648
public UniquenessAnnotation(Uniqueness at) {
3749
annotation = at;
3850
}
@@ -66,6 +78,10 @@ public boolean isBottom() {
6678
return annotation.equals(Uniqueness.BOTTOM);
6779
}
6880

81+
public boolean isImmutable() {
82+
return annotation.equals(Uniqueness.IMMUTABLE);
83+
}
84+
6985
public boolean isLessEqualThan(Uniqueness other) {
7086
return annotation.isLessEqualThan(other);
7187
}

latte/src/main/java/typechecking/LatteTypeChecker.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -665,15 +665,15 @@ public <T> void visitCtLiteral(CtLiteral<T> literal) {
665665

666666
super.visitCtLiteral(literal);
667667

668-
// Get a fresh symbolic value and add it to the environment with a shared default value
668+
// Get a fresh symbolic value and add it to the environment with an immutable default value
669669
SymbolicValue sv = symbEnv.getFresh();
670-
UniquenessAnnotation ua = new UniquenessAnnotation(Uniqueness.SHARED);
671-
670+
UniquenessAnnotation ua = new UniquenessAnnotation(Uniqueness.IMMUTABLE);
671+
672672
if (literal.getValue() == null)
673673
ua = new UniquenessAnnotation(Uniqueness.FREE); // its a null literal
674674

675675

676-
// Add the symbolic value to the environment with a shared default value
676+
// Add the symbolic value to the environment with an immutable default value
677677
permEnv.add(sv, ua);
678678

679679
// Store the symbolic value in metadata
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package examples;
2+
3+
import specification.Free;
4+
import specification.Unique;
5+
6+
7+
class PQNode {
8+
// @Refinement("min(this) == value")
9+
PQNode(int value, @Free PQNode next) {
10+
this.value = value;
11+
this.next = next;
12+
}
13+
14+
int value;
15+
16+
//@Refinement("this.next == null || min(this.next) < this.value")
17+
@Unique PQNode next;
18+
19+
// @Refinement(@Borrowed PQNode this, "min(this) <= v")
20+
void insert(int v) {
21+
if (v < this.value) {
22+
PQNode nxt = this.next;
23+
this.next = null;
24+
PQNode newNode = new PQNode(this.value, nxt);
25+
this.value = v;
26+
this.next = newNode; // note: if we swap this with the statement above, the refinement is briefly violated
27+
} else {
28+
next.insert(v);
29+
}
30+
}
31+
}

latte/src/test/java/AppTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ private static Stream<Arguments> provideCorrectTestCases() {
4545
Arguments.of("src/test/examples/MyNodeIfNoElse.java"),
4646
Arguments.of("src/test/examples/MyNodeIfPermissionCheck.java"),
4747
Arguments.of("src/test/examples/MyNodeInvocationIf.java"),
48-
Arguments.of("src/test/examples/MyNodeIfInvocationPermission.java")
48+
Arguments.of("src/test/examples/MyNodeIfInvocationPermission.java"),
49+
Arguments.of("src/test/examples/PQNode.java")
4950
);
5051
}
5152

0 commit comments

Comments
 (0)