Skip to content

Commit 1855bc4

Browse files
committed
marks permissions as being ordered
1 parent e2b141a commit 1855bc4

File tree

4 files changed

+36
-10
lines changed

4 files changed

+36
-10
lines changed

src/main/scala/viper/gobra/frontend/info/implementation/property/Orderability.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
package viper.gobra.frontend.info.implementation.property
88

9-
import viper.gobra.ast.internal.StringT
9+
import viper.gobra.ast.internal.{PermissionT, StringT}
1010
import viper.gobra.frontend.info.base.Type._
1111
import viper.gobra.frontend.info.implementation.TypeInfoImpl
1212

@@ -15,6 +15,7 @@ trait Orderability extends BaseProperty { this: TypeInfoImpl =>
1515
lazy val orderedType: Property[Type] = createBinaryProperty("ordered") {
1616
case Single(st) => underlyingType(st) match {
1717
case _: IntT => true
18+
case _: PermissionT => true
1819
case _: FloatT => true
1920
case _: StringT => true
2021
case _ => false

src/main/scala/viper/gobra/frontend/info/implementation/typing/ExprTyping.scala

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import viper.gobra.frontend.info.implementation.TypeInfoImpl
1616
import viper.gobra.util.TypeBounds.{BoundedIntegerKind, UnboundedInteger}
1717
import viper.gobra.util.{Constants, TypeBounds, Violation}
1818

19+
import scala.annotation.nowarn
20+
1921
trait ExprTyping extends BaseTyping { this: TypeInfoImpl =>
2022

2123
import viper.gobra.util.Violation._
@@ -479,19 +481,20 @@ trait ExprTyping extends BaseTyping { this: TypeInfoImpl =>
479481
(n, exprOrTypeType(n.left), exprOrTypeType(n.right)) match {
480482
case (_: PEquals | _: PUnequals | _: PLess | _: PAtMost | _: PGreater | _: PAtLeast | _: PAnd | _: POr, l, r) =>
481483
// from the spec: "first operand must be assignable to the type of the second operand, or vice versa"
482-
val fstAssignable = assignableTo.errors(exprOrTypeType(n.left), exprOrTypeType(n.right), mayInit)(n)
483-
val sndAssignable = assignableTo.errors(exprOrTypeType(n.right), exprOrTypeType(n.left), mayInit)(n)
484+
val fstAssignable = assignableTo.errors(l, r, mayInit)(n)
485+
val sndAssignable = assignableTo.errors(r, l, mayInit)(n)
484486
val assignable = if (fstAssignable.isEmpty || sndAssignable.isEmpty) noMessages
485487
else error(n, s"neither operand is assignable to the type of the other operand")
488+
@nowarn("msg=not.*?exhaustive")
486489
val applicable = if (assignable.isEmpty) {
487-
(n, exprOrTypeType(n.left), exprOrTypeType(n.right)) match {
488-
case (_: PEquals | _: PUnequals, l, r) =>
490+
n match {
491+
case _: PEquals | _: PUnequals =>
489492
// from the spec: "The equality operators == and != apply to operands of comparable types"
490493
comparableTypes.errors(l, r)(n)
491-
case (_: PLess | _: PAtMost | _: PGreater | _: PAtLeast, l, r) =>
494+
case _: PLess | _: PAtMost | _: PGreater | _: PAtLeast =>
492495
// from the spec: "The ordering operators <, <=, >, and >= apply to operands of ordered types"
493-
orderedType.errors(l)(n) ++ orderedType.errors(r)(n)
494-
case (_: PAnd | _: POr, l, r) =>
496+
orderedType.errors(l)(n.left) ++ orderedType.errors(r)(n.right)
497+
case _: PAnd | _: POr =>
495498
// from the spec: "Logical operators apply to boolean values", which we extend from boolean to assertion values:
496499
assignableTo.errors(l, AssertionT, mayInit)(n.left) ++
497500
assignableTo.errors(r, AssertionT, mayInit)(n.right)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
4+
package ints
5+
6+
func test1() {
7+
var j uint16
8+
for i := 0; i < 256; i++ {
9+
//:: ExpectedOutput(type_error)
10+
if i < j { // Go compiler reports "invalid operation: i < j (mismatched types int and uint16)"
11+
j = 42
12+
}
13+
}
14+
}
15+
16+
func test2() {
17+
invariant 0 <= i && i <= 256
18+
//:: ExpectedOutput(type_error)
19+
invariant forall j uint16 :: 0 <= j && j < i ==> true
20+
decreases 256 - i
21+
for i := 0; i < 256; i++ {}
22+
}

src/test/resources/same_package/pkg_init/byte/byte.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ var byteCache /*@@@*/ [256]*Byte
1313

1414
func init() {
1515
// @ invariant 0 <= i && i <= 256 && acc(&byteCache)
16-
// @ invariant (forall j, k uint16 :: 0 <= j && j < k && k < i ==>
16+
// @ invariant (forall j, k int :: 0 <= j && j < k && k < i ==>
1717
// @ byteCache[j] != byteCache[k])
18-
// @ invariant (forall j uint16 :: 0 <= j && j < i ==>
18+
// @ invariant (forall j int :: 0 <= j && j < i ==>
1919
// @ acc(byteCache[j]) && byteCache[j].value == byte(j) - 128)
2020
// @ decreases 256 - i
2121
for i := 0; i < 256; i++ {

0 commit comments

Comments
 (0)