From b3d4654935db38990d6cc4976eed7ddc14cf60fd Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Mon, 9 Mar 2020 20:00:27 -0700 Subject: Check for module name conflicts * Fixes #1436 --- src/main/scala/firrtl/passes/Checks.scala | 6 ++++++ src/test/scala/firrtlTests/CheckSpec.scala | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'src') diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala index e176bcc4..8717ffec 100644 --- a/src/main/scala/firrtl/passes/Checks.scala +++ b/src/main/scala/firrtl/passes/Checks.scala @@ -33,6 +33,8 @@ trait CheckHighFormLike { this: Pass => s"$info: [module $mname] Register $name cannot be a bundle type with flips.") class InvalidAccessException(info: Info, mname: String) extends PassException( s"$info: [module $mname] Invalid access to non-reference.") + class ModuleNameNotUniqueException(info: Info, mname: String) extends PassException( + s"$info: Repeat definition of module $mname") class ModuleNotDefinedException(info: Info, mname: String, name: String) extends PassException( s"$info: Module $name is not defined.") class IncorrectNumArgsException(info: Info, mname: String, op: String, n: Int) extends PassException( @@ -73,6 +75,10 @@ trait CheckHighFormLike { this: Pass => val moduleGraph = new ModuleGraph val moduleNames = (c.modules map (_.name)).toSet + c.modules.view.groupBy(_.name).filter(_._2.length > 1).flatMap(_._2).foreach { + m => errors.append(new ModuleNameNotUniqueException(m.info, m.name)) + } + def checkHighFormPrimop(info: Info, mname: String, e: DoPrim): Unit = { def correctNum(ne: Option[Int], nc: Int): Unit = { ne match { diff --git a/src/test/scala/firrtlTests/CheckSpec.scala b/src/test/scala/firrtlTests/CheckSpec.scala index 9a384d21..f03b6611 100644 --- a/src/test/scala/firrtlTests/CheckSpec.scala +++ b/src/test/scala/firrtlTests/CheckSpec.scala @@ -307,6 +307,32 @@ class CheckSpec extends FlatSpec with Matchers { } } } + + s"Duplicate module names" should "throw an exception" in { + val input = + s"""|circuit bar : + | module bar : + | input i : UInt<8> + | output o : UInt<8> + | o <= i + | module dup : + | input i : UInt<8> + | output o : UInt<8> + | o <= i + | module dup : + | input i : UInt<8> + | output o : UInt<8> + | o <= not(i) + |""".stripMargin + assertThrows[CheckHighForm.ModuleNameNotUniqueException] { + try { + checkHighInput(input) + } catch { + case e: firrtl.passes.PassExceptions => throw e.exceptions.head + } + } + } + } object CheckSpec { -- cgit v1.2.3 From e41936d5283ba8caae2a23602e8e1a2baea391cb Mon Sep 17 00:00:00 2001 From: Albert Magyar Date: Mon, 9 Mar 2020 20:02:06 -0700 Subject: Check for collision of defnames with Module names * Fixes #1096 --- src/main/scala/firrtl/passes/Checks.scala | 9 +++++++++ src/test/scala/firrtlTests/CheckSpec.scala | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'src') diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala index 8717ffec..3c9a7eda 100644 --- a/src/main/scala/firrtl/passes/Checks.scala +++ b/src/main/scala/firrtl/passes/Checks.scala @@ -35,6 +35,8 @@ trait CheckHighFormLike { this: Pass => s"$info: [module $mname] Invalid access to non-reference.") class ModuleNameNotUniqueException(info: Info, mname: String) extends PassException( s"$info: Repeat definition of module $mname") + class DefnameConflictException(info: Info, mname: String, defname: String) extends PassException( + s"$info: defname $defname of extmodule $mname conflicts with an existing module") class ModuleNotDefinedException(info: Info, mname: String, name: String) extends PassException( s"$info: Module $name is not defined.") class IncorrectNumArgsException(info: Info, mname: String, op: String, n: Int) extends PassException( @@ -75,10 +77,17 @@ trait CheckHighFormLike { this: Pass => val moduleGraph = new ModuleGraph val moduleNames = (c.modules map (_.name)).toSet + val intModuleNames = c.modules.view.collect({ case m: Module => m.name }).toSet + c.modules.view.groupBy(_.name).filter(_._2.length > 1).flatMap(_._2).foreach { m => errors.append(new ModuleNameNotUniqueException(m.info, m.name)) } + c.modules.collect { + case ExtModule(info, name, _, defname, _) if (intModuleNames.contains(defname)) => + errors.append(new DefnameConflictException(info, name, defname)) + } + def checkHighFormPrimop(info: Info, mname: String, e: DoPrim): Unit = { def correctNum(ne: Option[Int], nc: Int): Unit = { ne match { diff --git a/src/test/scala/firrtlTests/CheckSpec.scala b/src/test/scala/firrtlTests/CheckSpec.scala index f03b6611..aa154bab 100644 --- a/src/test/scala/firrtlTests/CheckSpec.scala +++ b/src/test/scala/firrtlTests/CheckSpec.scala @@ -333,6 +333,23 @@ class CheckSpec extends FlatSpec with Matchers { } } + s"Defnames that conflict with pure-FIRRTL module names" should "throw an exception" in { + val input = + s"""|circuit bar : + | module bar : + | input i : UInt<8> + | output o : UInt<8> + | o <= i + | extmodule dup : + | input i : UInt<8> + | output o : UInt<8> + | defname = bar + |""".stripMargin + assertThrows[CheckHighForm.DefnameConflictException] { + checkHighInput(input) + } + } + } object CheckSpec { -- cgit v1.2.3