diff --git a/source/ast/types/Type.cpp b/source/ast/types/Type.cpp index abf00af64..fab0de8e1 100644 --- a/source/ast/types/Type.cpp +++ b/source/ast/types/Type.cpp @@ -426,10 +426,9 @@ bool Type::isMatching(const Type& rhs) const { if (l == r) return true; - if (l->getSyntax() && l->getSyntax() == r->getSyntax() && - l->getParentScope() == r->getParentScope()) { + if (l->getSyntax() && l->getSyntax() == r->getSyntax() && l->getParentScope() && + l->getParentScope() == r->getParentScope()) return true; - } // Special casing for type synonyms: real/realtime if (l->isFloating() && r->isFloating()) { diff --git a/tests/unittests/ast/TypeTests.cpp b/tests/unittests/ast/TypeTests.cpp index eb6a51356..29aa2d84a 100644 --- a/tests/unittests/ast/TypeTests.cpp +++ b/tests/unittests/ast/TypeTests.cpp @@ -2244,3 +2244,31 @@ TEST_CASE("Virtual interface element select of member") { compilation.addSyntaxTree(tree); NO_COMPILATION_ERRORS; } + +TEST_CASE("Hierarchy-dependent type equivalence") { + auto tree = SyntaxTree::fromText(R"( + interface iface #(parameter int WIDTH = 1)(); + typedef struct packed { + bit [3:0] op; + } t; + t [WIDTH-1:0] ready; + endinterface + + module top(); + iface #(.WIDTH(1)) if1(); + iface #(.WIDTH(2)) if2(); + endmodule +)"); + + Compilation compilation; + compilation.addSyntaxTree(tree); + NO_COMPILATION_ERRORS; + + const InstanceBodySymbol& top = compilation.getRoot().lookupName("top").body; + const Type* type1 = + &top.lookupName("if1").body.lookupName("ready").getType(); + const Type* type2 = + &top.lookupName("if2").body.lookupName("ready").getType(); + + CHECK(!type1->isEquivalent(*type2)); +}