From 147e9eaf3814738f339b020e701a160ba2f68b60 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 31 Jan 2012 08:21:34 -0800 Subject: Improved warning for insensible comparisons. Utilize knowledge of case class synthetic equals to rule out some comparisons statically. Closes SI-5426. --- test/files/neg/checksensible.check | 5 ++++- test/files/neg/t5426.check | 13 +++++++++++++ test/files/neg/t5426.flags | 1 + test/files/neg/t5426.scala | 10 ++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/files/neg/t5426.check create mode 100644 test/files/neg/t5426.flags create mode 100644 test/files/neg/t5426.scala (limited to 'test/files/neg') diff --git a/test/files/neg/checksensible.check b/test/files/neg/checksensible.check index 0881205bb4..d785179a56 100644 --- a/test/files/neg/checksensible.check +++ b/test/files/neg/checksensible.check @@ -28,6 +28,9 @@ checksensible.scala:27: error: comparing values of types Int and Unit using `==' checksensible.scala:29: error: comparing values of types Int and String using `==' will always yield false 1 == "abc" ^ +checksensible.scala:33: error: comparing values of types Some[Int] and Int using `==' will always yield false + Some(1) == 1 // as above + ^ checksensible.scala:38: error: comparing a fresh object using `==' will always yield false new AnyRef == 1 ^ @@ -94,4 +97,4 @@ checksensible.scala:84: error: comparing values of types EqEqRefTest.this.C3 and checksensible.scala:95: error: comparing values of types Unit and Int using `!=' will always yield true while ((c = in.read) != -1) ^ -32 errors found +33 errors found diff --git a/test/files/neg/t5426.check b/test/files/neg/t5426.check new file mode 100644 index 0000000000..d9e192d3f0 --- /dev/null +++ b/test/files/neg/t5426.check @@ -0,0 +1,13 @@ +t5426.scala:2: error: comparing values of types Some[Int] and Int using `==' will always yield false + def f1 = Some(5) == 5 + ^ +t5426.scala:3: error: comparing values of types Int and Some[Int] using `==' will always yield false + def f2 = 5 == Some(5) + ^ +t5426.scala:8: error: comparing values of types Int and Some[Int] using `==' will always yield false + (x1 == x2) + ^ +t5426.scala:9: error: comparing values of types Some[Int] and Int using `==' will always yield false + (x2 == x1) + ^ +four errors found diff --git a/test/files/neg/t5426.flags b/test/files/neg/t5426.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/t5426.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/t5426.scala b/test/files/neg/t5426.scala new file mode 100644 index 0000000000..f2fb5cc12c --- /dev/null +++ b/test/files/neg/t5426.scala @@ -0,0 +1,10 @@ +class A { + def f1 = Some(5) == 5 + def f2 = 5 == Some(5) + + val x1 = 5 + val x2 = Some(5) + + (x1 == x2) + (x2 == x1) +} -- cgit v1.2.3 From 37bcff7956451cd74d08899e0e49c8b569d3a882 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 31 Jan 2012 09:03:32 -0800 Subject: Test case closes SI-5352. --- test/files/neg/t5352.check | 13 +++++++++++++ test/files/neg/t5352.flags | 1 + test/files/neg/t5352.scala | 15 +++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 test/files/neg/t5352.check create mode 100644 test/files/neg/t5352.flags create mode 100644 test/files/neg/t5352.scala (limited to 'test/files/neg') diff --git a/test/files/neg/t5352.check b/test/files/neg/t5352.check new file mode 100644 index 0000000000..d24b0e8ee1 --- /dev/null +++ b/test/files/neg/t5352.check @@ -0,0 +1,13 @@ +t5352.scala:11: error: type mismatch; + found : boop.Bar + required: boop.BarF + (which expands to) AnyRef{def f(): Int} + x = xs.head + ^ +t5352.scala:14: error: method f in class Bar1 cannot be accessed in boop.Bar1 + Access to protected method f not permitted because + enclosing object boop is not a subclass of + class Bar1 in object boop where target is defined + (new Bar1).f + ^ +two errors found diff --git a/test/files/neg/t5352.flags b/test/files/neg/t5352.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/neg/t5352.flags @@ -0,0 +1 @@ +-Xfatal-warnings \ No newline at end of file diff --git a/test/files/neg/t5352.scala b/test/files/neg/t5352.scala new file mode 100644 index 0000000000..6ee41f5680 --- /dev/null +++ b/test/files/neg/t5352.scala @@ -0,0 +1,15 @@ +object boop { + abstract class Bar { protected def f(): Any } + class Bar1 extends Bar { protected def f(): Int = 5 } + class Bar2 extends Bar { protected def f(): Int = 5 } + + val xs = List(new Bar1, new Bar2) + + type BarF = { def f(): Int } + + var x: BarF = _ + x = xs.head + x.f + + (new Bar1).f +} -- cgit v1.2.3 From 264ff5d5e8dbec4ae2e13bf52e66a965d884b25c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Tue, 31 Jan 2012 00:14:47 -0800 Subject: Fix for parser OOM. The scanner performs some sketchy heuristics when it sees an ascii 1A since it may be EOF or it may be part of a literal. Due to this, it failed to detect an unterminated string literal if the opening quote was unicode-escaped, leading to memory exhaustion as it read SUs until the universe ended. We're parsing a fixed input with known length! There's no reason to be guessing about whether a char is EOF. If we're at the end of the file, it's the end of file. Otherwise, it is not the end of the file. --- src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 10 ++++++---- test/files/neg/unicode-unterminated-quote.check | 4 ++++ test/files/neg/unicode-unterminated-quote.scala | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 test/files/neg/unicode-unterminated-quote.check create mode 100644 test/files/neg/unicode-unterminated-quote.scala (limited to 'test/files/neg') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 4478fb6128..dae264fffe 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -84,6 +84,8 @@ trait Scanners extends ScannersCommon { abstract class Scanner extends CharArrayReader with TokenData with ScannerCommon { private def isDigit(c: Char) = java.lang.Character isDigit c + + def isAtEnd = charOffset >= buf.length def flush = { charOffset = offset; nextChar(); this } @@ -449,7 +451,7 @@ trait Scanners extends ScannersCommon { case ']' => nextChar(); token = RBRACKET case SU => - if (charOffset >= buf.length) token = EOF + if (isAtEnd) token = EOF else { syntaxError("illegal character") nextChar() @@ -771,10 +773,10 @@ trait Scanners extends ScannersCommon { putChar(ch) } - private def getLitChars(delimiter: Char) = - while (ch != delimiter && (ch != CR && ch != LF && ch != SU || isUnicodeEscape)) { + private def getLitChars(delimiter: Char) = { + while (ch != delimiter && !isAtEnd && (ch != SU && ch != CR && ch != LF || isUnicodeEscape)) getLitChar() - } + } /** read fractional part and exponent of floating point number * if one is present. diff --git a/test/files/neg/unicode-unterminated-quote.check b/test/files/neg/unicode-unterminated-quote.check new file mode 100644 index 0000000000..fc5caa6d7e --- /dev/null +++ b/test/files/neg/unicode-unterminated-quote.check @@ -0,0 +1,4 @@ +unicode-unterminated-quote.scala:2: error: unclosed string literal + val x = /u0022 + ^ +one error found diff --git a/test/files/neg/unicode-unterminated-quote.scala b/test/files/neg/unicode-unterminated-quote.scala new file mode 100644 index 0000000000..bb6eab667f --- /dev/null +++ b/test/files/neg/unicode-unterminated-quote.scala @@ -0,0 +1,2 @@ +class A { + val x = \u0022 \ No newline at end of file -- cgit v1.2.3