Skip to content

Commit

Permalink
Report an error for select expressions after a range select
Browse files Browse the repository at this point in the history
  • Loading branch information
MikePopoloski committed Nov 25, 2023
1 parent e9a9243 commit a31e602
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 6 deletions.
1 change: 1 addition & 0 deletions scripts/diagnostics.txt
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@ error SpecifyPathBadReference "cannot refer to '{}' in state-dependent path cond
error PathPulseInExpr "PATHPULSE$ specparams cannot be used in expressions"
error InterfacePortInvalidExpression "invalid expression for interface port connection"
error AssignmentPatternLValueDynamic "lvalue assignment patterns cannot be assigned from dynamic arrays"
error SelectAfterRangeSelect "cannot chain select expressions after a range select"
warning ignored-slice IgnoredSlice "slice size ignored for left-to-right streaming operator"
warning unsized-concat UnsizedInConcat "unsized integer in concat; using a width of {}"
warning width-expand WidthExpand "implicit conversion expands from {} to {} bits"
Expand Down
5 changes: 5 additions & 0 deletions source/ast/Expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,11 @@ Expression& Expression::bindSelector(Compilation& compilation, Expression& value
return badExpr(compilation, nullptr);
}

if (value.kind == ExpressionKind::RangeSelect) {
context.addDiag(diag::SelectAfterRangeSelect, syntax.sourceRange()) << value.sourceRange;
return badExpr(compilation, nullptr);
}

// The full source range of the expression includes the value and the selector syntax.
SourceRange fullRange = {value.sourceRange.start(), syntax.sourceRange().end()};

Expand Down
8 changes: 8 additions & 0 deletions source/ast/Lookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,7 @@ const Symbol* Lookup::selectChild(const Symbol& initialSymbol,
std::span<const ElementSelectSyntax* const> selectors,
const ASTContext& context, LookupResult& result) {
const Symbol* symbol = &initialSymbol;
const SyntaxNode* prevRangeSelect = nullptr;
for (const ElementSelectSyntax* syntax : selectors) {
if (symbol->kind != SymbolKind::InstanceArray &&
symbol->kind != SymbolKind::GenerateBlockArray) {
Expand All @@ -1226,6 +1227,12 @@ const Symbol* Lookup::selectChild(const Symbol& initialSymbol,
if (!syntax->selector)
return selectorError();

if (prevRangeSelect) {
result.addDiag(*context.scope, diag::SelectAfterRangeSelect, syntax->sourceRange())
<< prevRangeSelect->sourceRange();
return nullptr;
}

switch (syntax->selector->kind) {
case SyntaxKind::BitSelect:
symbol = selectSingleChild(*symbol, syntax->selector->as<BitSelectSyntax>(),
Expand All @@ -1236,6 +1243,7 @@ const Symbol* Lookup::selectChild(const Symbol& initialSymbol,
case SyntaxKind::SimpleRangeSelect:
case SyntaxKind::AscendingRangeSelect:
case SyntaxKind::DescendingRangeSelect:
prevRangeSelect = syntax;
if (symbol->kind != SymbolKind::InstanceArray)
return selectorError();

Expand Down
22 changes: 21 additions & 1 deletion tests/unittests/ast/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2799,7 +2799,7 @@ module m;
function automatic int f1;
int a = -1;
int b = y[a+:3][0];
int b[] = y[a+:3];
w[0:1] = {1,1};
endfunction
Expand Down Expand Up @@ -3143,3 +3143,23 @@ endmodule
CHECK(diags[0].code == diag::ExpressionNotAssignable);
CHECK(diags[1].code == diag::AssignmentPatternLValueDynamic);
}

TEST_CASE("Invalid select after range select") {
auto tree = SyntaxTree::fromText(R"(
module m;
function int foo; return 1; endfunction
int i;
int j = i[3:0][0];
int k = foo()[3:0][0];
endmodule
)");

Compilation compilation;
compilation.addSyntaxTree(tree);

auto& diags = compilation.getAllDiagnostics();
REQUIRE(diags.size() == 2);
CHECK(diags[0].code == diag::SelectAfterRangeSelect);
CHECK(diags[1].code == diag::SelectAfterRangeSelect);
}
12 changes: 7 additions & 5 deletions tests/unittests/ast/LookupTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -529,13 +529,14 @@ module m;
I arrayInv [-4:a] ();
always_comb arrayInv[-4:-1][0].foo = 1;
always_comb array[-4:a][0].foo = 1;
always_comb array[-4:-1][0].foo = 1;
always_comb array[-4:a].foo = 1;
always_comb array[-1:-4][0].foo = 1;
always_comb array[-1+:-4][0].foo = 1;
always_comb array[-1+:4][0].foo = 1;
always_comb array[-1:-4].foo = 1;
always_comb array[-1+:-4].foo = 1;
always_comb array[-1+:4].foo = 1;
always_comb array[-2147483647-:3][0].foo = 1;
always_comb array[-2147483647-:3].foo = 1;
endmodule
)");

Expand All @@ -548,6 +549,7 @@ endmodule
CHECK((it++)->code == diag::InvalidScopeIndexExpression);
CHECK((it++)->code == diag::ScopeNotIndexable);
CHECK((it++)->code == diag::UndeclaredIdentifier);
CHECK((it++)->code == diag::SelectAfterRangeSelect);
CHECK((it++)->code == diag::UndeclaredIdentifier);
CHECK((it++)->code == diag::InstanceArrayEndianMismatch);
CHECK((it++)->code == diag::ValueMustBePositive);
Expand Down

0 comments on commit a31e602

Please sign in to comment.