From e0d4122daeae7b69def13a26013ebe092d74b154 Mon Sep 17 00:00:00 2001 From: MikePopoloski Date: Sun, 24 Sep 2023 00:52:28 -0400 Subject: [PATCH] Allow implicitly typed parameters with range declarations to be assignment-like contexts --- source/ast/Expression.cpp | 18 ++++++++++-------- tests/unittests/ast/TypeTests.cpp | 10 ++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/source/ast/Expression.cpp b/source/ast/Expression.cpp index 7142a1141..f761ca9cb 100644 --- a/source/ast/Expression.cpp +++ b/source/ast/Expression.cpp @@ -358,18 +358,19 @@ std::tuple Expression::bindImplicitParam( const DataTypeSyntax& typeSyntax, const ExpressionSyntax& rhs, SourceLocation location, const ASTContext& exprContext, const ASTContext& typeContext, bitmask extraFlags) { - Compilation& comp = exprContext.getCompilation(); - Expression& expr = create(comp, rhs, exprContext, extraFlags); - const Type* lhsType = expr.type; - // Rules are described in [6.20.2]. + Compilation& comp = exprContext.getCompilation(); auto& it = typeSyntax.as(); if (!it.dimensions.empty()) { // If we have a range provided, the result is always an integral value // of the provided width -- getType() will do what we want here. - lhsType = &comp.getType(typeSyntax, typeContext); + auto lhsType = &comp.getType(typeSyntax, typeContext); + return {&bindRValue(*lhsType, rhs, location, exprContext, extraFlags), lhsType}; } - else if (it.signing) { + + Expression& expr = create(comp, rhs, exprContext, extraFlags); + const Type* lhsType = expr.type; + if (it.signing) { // If signing is provided, the result is always integral but we infer the width. // If the type is non-integral or unsized, infer a width of 32. bitwidth_t bits = lhsType->getBitWidth(); @@ -859,8 +860,9 @@ Expression& Expression::create(Compilation& compilation, const ExpressionSyntax& context); break; case SyntaxKind::TimingControlExpression: - // Valid cases of this expression type are handled in AssignmentExpression. If we reach - // this block here, the expression is invalid so always report an error. + // Valid cases of this expression type are handled in AssignmentExpression. + // If we reach this block here, the expression is invalid so always report + // an error. context.addDiag(diag::TimingControlNotAllowed, syntax.sourceRange()); result = &badExpr(compilation, nullptr); break; diff --git a/tests/unittests/ast/TypeTests.cpp b/tests/unittests/ast/TypeTests.cpp index 4d1e33977..b2ac1dad3 100644 --- a/tests/unittests/ast/TypeTests.cpp +++ b/tests/unittests/ast/TypeTests.cpp @@ -2130,3 +2130,13 @@ endmodule compilation.addSyntaxTree(tree); NO_COMPILATION_ERRORS; } + +TEST_CASE("Inferred parameter type with range specification -- assignment-like context") { + auto tree = SyntaxTree::fromText(R"( +localparam [1:0][7:0] VALUES_0 = '{1, 2}; +)"); + + Compilation compilation; + compilation.addSyntaxTree(tree); + NO_COMPILATION_ERRORS; +}