From d4a58883c470214a8aded30cfa8274f26083f8c6 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 22 Mar 2012 10:39:29 +0100 Subject: [vpm] avoid verifyerror: leave jump to tail-pos label the following commit deals with the fall-out in basicblocks (double closing of blocks in ignore mode) --- src/compiler/scala/tools/nsc/transform/TailCalls.scala | 9 +++++++-- test/files/run/virtpatmat_tailcalls_verifyerror.check | 1 + test/files/run/virtpatmat_tailcalls_verifyerror.flags | 1 + test/files/run/virtpatmat_tailcalls_verifyerror.scala | 13 +++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 test/files/run/virtpatmat_tailcalls_verifyerror.check create mode 100644 test/files/run/virtpatmat_tailcalls_verifyerror.flags create mode 100644 test/files/run/virtpatmat_tailcalls_verifyerror.scala diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index ef76fe1b1c..9915f7e9fc 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -341,13 +341,18 @@ abstract class TailCalls extends Transform { else if (fun.symbol.isLabel && args.nonEmpty && args.tail.isEmpty && ctx.tailLabels(fun.symbol)) { // this is to detect tailcalls in translated matches // it's a one-argument call to a label that is in a tailposition and that looks like label(x) {x} - // thus, the argument to the call is in tailposition and we don't need to jump to the label, tail jump instead + // thus, the argument to the call is in tailposition val saved = ctx.tailPos ctx.tailPos = true debuglog("in tailpos label: "+ args.head) val res = transform(args.head) ctx.tailPos = saved - if (res ne args.head) res // we tail-called -- TODO: shield from false-positives where we rewrite but don't tail-call + if (res ne args.head) { + // we tail-called -- TODO: shield from false-positives where we rewrite but don't tail-call + // must leave the jump to the original tailpos-label (fun)! + // there might be *a* tailcall *in* res, but it doesn't mean res *always* tailcalls + treeCopy.Apply(tree, fun, List(res)) + } else rewriteApply(fun, fun, Nil, args) } else rewriteApply(fun, fun, Nil, args) diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.check b/test/files/run/virtpatmat_tailcalls_verifyerror.check new file mode 100644 index 0000000000..c508d5366f --- /dev/null +++ b/test/files/run/virtpatmat_tailcalls_verifyerror.check @@ -0,0 +1 @@ +false diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.flags b/test/files/run/virtpatmat_tailcalls_verifyerror.flags new file mode 100644 index 0000000000..9769db9257 --- /dev/null +++ b/test/files/run/virtpatmat_tailcalls_verifyerror.flags @@ -0,0 +1 @@ + -Yvirtpatmat -Xexperimental diff --git a/test/files/run/virtpatmat_tailcalls_verifyerror.scala b/test/files/run/virtpatmat_tailcalls_verifyerror.scala new file mode 100644 index 0000000000..1ee613f09e --- /dev/null +++ b/test/files/run/virtpatmat_tailcalls_verifyerror.scala @@ -0,0 +1,13 @@ +// shouldn't result in a verify error when run... +object Test extends App { + @annotation.tailrec + final def test(meh: Boolean): Boolean = { + Some("a") match { + case x => + x match { + case _ => if(meh) test(false) else false + } + } + } + println(test(true)) +} \ No newline at end of file -- cgit v1.2.3