From d12b44a6fdc141b6cfe6c37b594377fb36bd32dd Mon Sep 17 00:00:00 2001 From: Regis Blanc <regwblanc@gmail.com> Date: Thu, 17 Mar 2016 13:13:05 +0100 Subject: [PATCH] more aliasing restrictions --- .../scala/leon/xlang/AntiAliasingPhase.scala | 7 ++++-- .../xlang/error/ObjectAliasing5.scala | 12 ++++++++++ .../xlang/error/ObjectAliasing6.scala | 14 ++++++++++++ .../xlang/error/ObjectAliasing7.scala | 22 +++++++++++++++++++ 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/regression/xlang/error/ObjectAliasing5.scala create mode 100644 src/test/resources/regression/xlang/error/ObjectAliasing6.scala create mode 100644 src/test/resources/regression/xlang/error/ObjectAliasing7.scala diff --git a/src/main/scala/leon/xlang/AntiAliasingPhase.scala b/src/main/scala/leon/xlang/AntiAliasingPhase.scala index 70163481f..9eaf5eb33 100644 --- a/src/main/scala/leon/xlang/AntiAliasingPhase.scala +++ b/src/main/scala/leon/xlang/AntiAliasingPhase.scala @@ -332,8 +332,11 @@ object AntiAliasingPhase extends TransformationPhase { def checkAliasing(fd: FunDef)(ctx: LeonContext): Unit = { def checkReturnValue(body: Expr, bindings: Set[Identifier]): Unit = { getReturnedExpr(body).foreach{ - case IsTyped(v@Variable(id), tpe) if isMutableType(tpe) && bindings.contains(id) => - ctx.reporter.fatalError(v.getPos, "Cannot return a shared reference to a mutable object: " + v) + case expr if isMutableType(expr.getType) => + findReceiverId(expr).foreach(id => + if(bindings.contains(id)) + ctx.reporter.fatalError(expr.getPos, "Cannot return a shared reference to a mutable object: " + expr) + ) case _ => () } } diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing5.scala b/src/test/resources/regression/xlang/error/ObjectAliasing5.scala new file mode 100644 index 000000000..c94656fdb --- /dev/null +++ b/src/test/resources/regression/xlang/error/ObjectAliasing5.scala @@ -0,0 +1,12 @@ +import leon.lang._ + +object ObjectAliasing5 { + + case class A(var x: Int) + case class B(a: A) + + def f1(b: B): A = { + b.a + } + +} diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing6.scala b/src/test/resources/regression/xlang/error/ObjectAliasing6.scala new file mode 100644 index 000000000..793b9815d --- /dev/null +++ b/src/test/resources/regression/xlang/error/ObjectAliasing6.scala @@ -0,0 +1,14 @@ +import leon.lang._ + +object ObjectAliasing6 { + + case class A(var x: Int) + case class B(a: A) + + def f1(b: B): Int = { + val a = b.a + a.x = 12 + b.a.x + } ensuring(_ == 12) + +} diff --git a/src/test/resources/regression/xlang/error/ObjectAliasing7.scala b/src/test/resources/regression/xlang/error/ObjectAliasing7.scala new file mode 100644 index 000000000..ea28fa5bb --- /dev/null +++ b/src/test/resources/regression/xlang/error/ObjectAliasing7.scala @@ -0,0 +1,22 @@ +package test.resources.regression.xlang.error + +import leon.lang._ + +object ObjectAliasing7 { + + case class A(var x: Int) + case class B(a: A) + + def f1(a1: A, a2: A): Int = { + val tmp = a1.x + a2.x = a1.x + a1.x = tmp + a1.x + a2.x + } + + def f(): Int = { + val b = B(A(10)) + f1(b.a, b.a) + } ensuring(_ == 20) + +} -- GitLab