From 5b54681d0360616efdb2a561ce9201fbd67e7288 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 23 May 2013 00:28:45 -0700 Subject: SI-7473 Bad for expr crashes postfix This commit makes building PostfixSelect robust against a bad pos on its operand, which can happen if a bad for expression results in an EmptyTree. --- src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 9 ++++----- src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 6 ++++++ test/files/neg/t7473.check | 7 +++++++ test/files/neg/t7473.scala | 7 +++++++ 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 test/files/neg/t7473.check create mode 100644 test/files/neg/t7473.scala diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index b8791c15dc..50398824e1 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1474,8 +1474,9 @@ self => * }}} */ def postfixExpr(): Tree = { - val base = opstack - var top = prefixExpr() + val start = in.offset + val base = opstack + var top = prefixExpr() while (isIdent) { top = reduceStack(isExpr = true, base, top, precedence(in.name), leftAssoc = treeInfo.isLeftAssoc(in.name)) @@ -1493,9 +1494,7 @@ self => val topinfo = opstack.head opstack = opstack.tail val od = stripParens(reduceStack(isExpr = true, base, topinfo.operand, 0, leftAssoc = true)) - return atPos(od.pos.startOrPoint, topinfo.offset) { - new PostfixSelect(od, topinfo.operator.encode) - } + return makePostfixSelect(start, topinfo.offset, od, topinfo.operator) } } reduceStack(isExpr = true, base, top, 0, leftAssoc = true) diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala index b5771454f8..e92c3e1654 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala @@ -245,6 +245,12 @@ abstract class TreeBuilder { Assign(lhs, rhs) } + /** Tree for `od op`, start is start0 if od.pos is borked. */ + def makePostfixSelect(start0: Int, end: Int, od: Tree, op: Name): Tree = { + val start = if (od.pos.isDefined) od.pos.startOrPoint else start0 + atPos(r2p(start, end, end)) { new PostfixSelect(od, op.encode) } + } + /** A type tree corresponding to (possibly unary) intersection type */ def makeIntersectionTypeTree(tps: List[Tree]): Tree = if (tps.tail.isEmpty) tps.head diff --git a/test/files/neg/t7473.check b/test/files/neg/t7473.check new file mode 100644 index 0000000000..bc8c29d463 --- /dev/null +++ b/test/files/neg/t7473.check @@ -0,0 +1,7 @@ +t7473.scala:6: error: '<-' expected but '=' found. + (for (x = Option(i); if x == j) yield 42) toList + ^ +t7473.scala:6: error: illegal start of simple expression + (for (x = Option(i); if x == j) yield 42) toList + ^ +two errors found diff --git a/test/files/neg/t7473.scala b/test/files/neg/t7473.scala new file mode 100644 index 0000000000..593231d5f2 --- /dev/null +++ b/test/files/neg/t7473.scala @@ -0,0 +1,7 @@ + +object Foo { + val i,j = 3 + //for (x = Option(i); if x == j) yield 42 //t7473.scala:4: error: '<-' expected but '=' found. + // evil postfix! + (for (x = Option(i); if x == j) yield 42) toList +} -- cgit v1.2.3