From 2e62da09ed1ed0725a14185ae76a683da73b32f4 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 10 Nov 2016 10:05:15 -0800 Subject: Throw exceptions for cloneType failures - fix #358 Add a Builder.exception() method for those cases where continuing is likely to mask the initial error. --- .../src/main/scala/chisel3/core/Aggregate.scala | 4 +- .../src/main/scala/chisel3/internal/Builder.scala | 10 ++++ .../MissingCloneBindingExceptionSpec.scala | 57 ++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index de7af462..68fe0bb5 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -408,12 +408,12 @@ class Bundle extends Aggregate { constructor.newInstance(_parent.get).asInstanceOf[this.type] } catch { case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException => - Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " + + Builder.exception(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " + "an anonymous Bundle object that captures external state and hence is un-cloneTypeable") this } case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException => - Builder.error(s"Parameterized Bundle ${this.getClass} needs cloneType method") + Builder.exception(s"Parameterized Bundle ${this.getClass} needs cloneType method") this } } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index b4b0e028..32ba248c 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -188,6 +188,16 @@ private[chisel3] object Builder { def warning(m: => String): Unit = errors.warning(m) def deprecated(m: => String): Unit = errors.deprecated(m) + /** Record an exception as an error, and throw it. + * + * @param m exception message + */ + @throws(classOf[ChiselException]) + def exception(m: => String): Unit = { + error(m) + throwException(m) + } + def build[T <: Module](f: => T): Circuit = { dynamicContextVar.withValue(Some(new DynamicContext())) { errors.info("Elaborating design...") diff --git a/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala b/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala new file mode 100644 index 00000000..fd48206e --- /dev/null +++ b/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala @@ -0,0 +1,57 @@ +// See LICENSE for license details. + +package chiselTests +import Chisel.ChiselException +import org.scalatest._ + +class MissingCloneBindingExceptionSpec extends FlatSpec with Matchers { + behavior of "missing cloneType in Chisel3" + ( the[ChiselException] thrownBy { + import chisel3._ + + class TestIO(w: Int) extends Bundle { + val a = Vec(4, UInt(width = w)).asInput + + //override def cloneType = (new TestIO(w)).asInstanceOf[this.type] + } + + class Test extends Module { + val io = IO(new TestIO(32)) + } + + class TestTop extends Module { + val io = IO(new Bundle {}) + + val subs = Vec.fill(2) { + Module(new Test).io + } + } + + val dummy = new TestTop + }).getMessage should include("needs cloneType method") + + behavior of "missing cloneType in Chisel2" + ( the[ChiselException] thrownBy { + import Chisel._ + + class TestIO(w: Int) extends Bundle { + val a = Vec(4, UInt(width = w)).asInput + + //override def cloneType = (new TestIO(w)).asInstanceOf[this.type] + } + + class Test extends Module { + val io = IO(new TestIO(32)) + } + + class TestTop extends Module { + val io = IO(new Bundle {}) + + val subs = Vec.fill(2) { + Module(new Test).io + } + } + + val dummy = new TestTop + }).getMessage should include("needs cloneType method") +} -- cgit v1.2.3 From b936f5e7f906f45ab635ad6e5c45cfec6726f716 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 10 Nov 2016 10:07:59 -0800 Subject: Replace "throw new Exception" with throwException (consistency). --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 32ba248c..381626c5 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -165,7 +165,7 @@ private[chisel3] object Builder { } def forcedModule: Module = currentModule match { case Some(module) => module - case None => throw new Exception( + case None => throwException( "Error: Not in a Module. Likely cause: Missed Module() wrap or bare chisel API call." // A bare api call is, e.g. calling Wire() from the scala console). ) -- cgit v1.2.3 From 1b53d893816d349f5ea18fa0ed13325b9f1b6917 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 14 Nov 2016 09:58:52 -0800 Subject: Avoid dynamicContext issues - use ChiselRunners.elaborate() --- src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala b/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala index fd48206e..719484ac 100644 --- a/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala +++ b/src/test/scala/chiselTests/MissingCloneBindingExceptionSpec.scala @@ -4,7 +4,7 @@ package chiselTests import Chisel.ChiselException import org.scalatest._ -class MissingCloneBindingExceptionSpec extends FlatSpec with Matchers { +class MissingCloneBindingExceptionSpec extends ChiselFlatSpec with Matchers { behavior of "missing cloneType in Chisel3" ( the[ChiselException] thrownBy { import chisel3._ @@ -27,7 +27,7 @@ class MissingCloneBindingExceptionSpec extends FlatSpec with Matchers { } } - val dummy = new TestTop + elaborate(new TestTop) }).getMessage should include("needs cloneType method") behavior of "missing cloneType in Chisel2" @@ -52,6 +52,6 @@ class MissingCloneBindingExceptionSpec extends FlatSpec with Matchers { } } - val dummy = new TestTop + elaborate(new TestTop) }).getMessage should include("needs cloneType method") } -- cgit v1.2.3