Skip to content

Commit

Permalink
Disallow ref args in fork-join_any/_none blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
MikePopoloski committed Apr 6, 2024
1 parent 0836f13 commit ddc950d
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 3 deletions.
3 changes: 2 additions & 1 deletion bindings/python/ASTBindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ void registerAST(py::module_& m) {
.value("LAndRValue", ASTFlags::LAndRValue)
.value("NoReference", ASTFlags::NoReference)
.value("ConfigParam", ASTFlags::ConfigParam)
.value("TypeOperator", ASTFlags::TypeOperator);
.value("TypeOperator", ASTFlags::TypeOperator)
.value("ForkJoinAnyNone", ASTFlags::ForkJoinAnyNone);

py::class_<EvaluatedDimension>(m, "EvaluatedDimension")
.def_readonly("kind", &EvaluatedDimension::kind)
Expand Down
7 changes: 5 additions & 2 deletions include/slang/ast/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,12 @@ enum class SLANG_EXPORT ASTFlags : uint64_t {
ConfigParam = 1ull << 41,

/// AST binding is for the contents of the type() operator.
TypeOperator = 1ull << 42
TypeOperator = 1ull << 42,

/// AST binding is inside a fork-join_any or fork-join_none block.
ForkJoinAnyNone = 1ull << 43
};
SLANG_BITMASK(ASTFlags, TypeOperator)
SLANG_BITMASK(ASTFlags, ForkJoinAnyNone)

// clang-format off
#define DK(x) \
Expand Down
1 change: 1 addition & 0 deletions scripts/diagnostics.txt
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ error LocalFormalVarMultiAssign "cannot bind local variable '{}' to more than on
error InterconnectReference "cannot reference interconnect net '{}' outside of a net port connection"
error UserDefPartialDriver "net '{}' with user-defined nettype cannot be partially driven"
error LocalVarEventExpr "local variable '{}' cannot be referenced in an event expression"
error RefArgForkJoin "cannot refer to 'ref' argument '{}' inside fork-join_any or fork-join_none block"
error PatternTaggedType "expected pattern type {} is not a tagged union"
error PatternStructType "structure pattern type {} is not a struct"
error PatternStructTooFew "structure pattern has too few members for target type {}"
Expand Down
3 changes: 3 additions & 0 deletions source/ast/Statements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,9 @@ Statement& BlockStatement::fromSyntax(Compilation& comp, const BlockStatementSyn
if (addInitializers)
bindScopeInitializers(context, buffer);

if (blockKind == StatementBlockKind::JoinAny || blockKind == StatementBlockKind::JoinNone)
context.flags |= ASTFlags::ForkJoinAnyNone;

for (auto item : syntax.items) {
if (StatementSyntax::isKind(item->kind)) {
auto& stmt = Statement::bind(item->as<StatementSyntax>(), context, stmtCtx,
Expand Down
7 changes: 7 additions & 0 deletions source/ast/expressions/MiscExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ Expression& ValueExpressionBase::fromSymbol(const ASTContext& context, const Sym
context.addDiag(diag::LocalVarEventExpr, sourceRange) << symbol.name;
return badExpr(comp, nullptr);
}
else if (flags.has(ASTFlags::ForkJoinAnyNone) && !var.flags.has(VariableFlags::RefStatic) &&
symbol.kind == SymbolKind::FormalArgument &&
symbol.as<FormalArgumentSymbol>().direction == ArgumentDirection::Ref) {
// Can't refer to ref args in fork-join_any/none
context.addDiag(diag::RefArgForkJoin, sourceRange) << symbol.name;
return badExpr(comp, nullptr);
}
}
else if (symbol.kind == SymbolKind::ConstraintBlock) {
if (!symbol.as<ConstraintBlockSymbol>().isStatic)
Expand Down
23 changes: 23 additions & 0 deletions tests/unittests/ast/StatementTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1979,3 +1979,26 @@ endclass
REQUIRE(diags.size() == 1);
CHECK(diags[0].code == diag::UnusedResult);
}

TEST_CASE("Ref args in fork-join blocks") {
auto options = optionsFor(LanguageVersion::v1800_2023);
auto tree = SyntaxTree::fromText(R"(
function automatic foo(ref a, ref static b);
fork
automatic int k = a;
begin : foo
$display(a);
$display(b);
end
join_none
endfunction
)",
options);

Compilation compilation(options);
compilation.addSyntaxTree(tree);

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

0 comments on commit ddc950d

Please sign in to comment.