Skip to content

Commit

Permalink
Fix potentially unbounded loop of resolving bind directives that plac…
Browse files Browse the repository at this point in the history
…e new bind directives into the same scope
  • Loading branch information
MikePopoloski committed Nov 26, 2024
1 parent 81a1cfd commit 2fc9f8d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions scripts/diagnostics.txt
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ error VirtualInterfaceIfaceMember "virtual interfaces cannot be used as the type
error DefparamBadHierarchy "defparam in a hierarchy in or under a generate block, array of instances, or bind instantiation cannot change a parameter value outside that hierarchy"
error BindTargetPrimitive "cannot bind a primitive"
error BindUnderBind "cannot bind an instance underneath the scope of another bind instance"
error DuplicateBind "bind directive targeting the same scope instantiated more than once"
error UdpWrongInputCount "incorrect number of input fields in table row; have {} but expect {}"
error UdpDupDiffOutput "primitive table row duplicates a set of inputs with a different specified output value"
error UdpAllX "primitive table row has all 'x' inputs so its output must also be 'x'"
Expand Down
6 changes: 6 additions & 0 deletions source/ast/Scope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1123,8 +1123,14 @@ void Scope::elaborate() const {
// If there are bind directives, reach up into the instance body
// and pull out the extra bind metadata from its override node.
if (hasBinds) {
SmallSet<const BindDirectiveSyntax*, 4> seenBindDirectives;
ASTContext context(*this, LookupLocation::max);
auto handleBind = [&](const BindDirectiveInfo& info) {
if (!seenBindDirectives.emplace(info.bindSyntax).second) {
addDiag(diag::DuplicateBind, info.bindSyntax->sourceRange());
return;
}

SmallVector<const Symbol*> instances;
SmallVector<const Symbol*> implicitNets;
if (info.bindSyntax->instantiation->kind == SyntaxKind::CheckerInstantiation) {
Expand Down
17 changes: 17 additions & 0 deletions tests/unittests/ast/HierarchyTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1732,6 +1732,23 @@ bind p program p(s
compilation.getAllDiagnostics();
}

TEST_CASE("Bind corner case crash regress 4") {
auto tree = SyntaxTree::fromText(R"(
module m3;
module m2;
bind m2 m2 mc();
endmodule
endmodule
)");

Compilation compilation;
compilation.addSyntaxTree(tree);

auto& diags = compilation.getAllDiagnostics();
REQUIRE(diags.size() == 1);
CHECK(diags[0].code == diag::DuplicateBind);
}

TEST_CASE("Nested modules with binds, parameterized, info task") {
auto tree = SyntaxTree::fromText(R"(
module m #(parameter P);
Expand Down

0 comments on commit 2fc9f8d

Please sign in to comment.