From 0bbde64d74653d1cbc04eb7f4bf5c2085214d089 Mon Sep 17 00:00:00 2001 From: willpartcl Date: Wed, 21 Oct 2026 10:31:10 -0700 Subject: [PATCH] Check full replication width before truncation and constant folding --- .../ast/expressions/OperatorExpressions.cpp | 2 +- tests/unittests/ast/ExpressionTests.cpp | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/source/ast/expressions/OperatorExpressions.cpp b/source/ast/expressions/OperatorExpressions.cpp index 87dbfd76d..fe826735d 100644 --- a/source/ast/expressions/OperatorExpressions.cpp +++ b/source/ast/expressions/OperatorExpressions.cpp @@ -2274,7 +2274,7 @@ Expression& ReplicationExpression::fromSyntax(Compilation& compilation, } auto width = context.requireValidBitWidth( - SVInt(32, uint64_t(*count), true) * right->type->getBitWidth(), syntax.sourceRange()); + SVInt(64, uint64_t(*count), true) * right->type->getBitWidth(), syntax.sourceRange()); if (!width) return badExpr(compilation, result); diff --git a/tests/unittests/ast/ExpressionTests.cpp b/tests/unittests/ast/ExpressionTests.cpp index 2d1e4561f..99a985bc2 100644 --- a/tests/unittests/ast/ExpressionTests.cpp +++ b/tests/unittests/ast/ExpressionTests.cpp @@ -3894,3 +3894,35 @@ endmodule compilation.addSyntaxTree(tree); NO_COMPILATION_ERRORS; } + +TEST_CASE("Replication widths are checked before uint32 truncation") { + for (const auto [count, width] : + {std::pair{16777216, 256}, std::pair{16777217, 256}, std::pair{33554432, 256}, + std::pair{8388608, 512}, std::pair{4194304, 1024}, std::pair{16777215, 256}, + std::pair{2147483647, 2}}) { + for (auto bit : {"0", "1", "x"}) { + CAPTURE(count, width, bit); + auto tree = SyntaxTree::fromText("module m(output logic o); assign o = ^{ " + + std::to_string(count) + "{ {" + std::to_string(width) + + "{1'b" + bit + "}} } }; endmodule"); + Compilation compilation; + compilation.addSyntaxTree(tree); + auto& diags = compilation.getAllDiagnostics(); + REQUIRE(diags.size() == 1); + CHECK(diags[0].code == diag::ValueExceedsMaxBitWidth); + } + } +} + +TEST_CASE("Replication accepts the maximum supported vector width") { + auto tree = SyntaxTree::fromText(R"( +module m(input logic [16777214:0] v, output logic [16777214:0] o, + output logic [255:0] small_value); + assign o = {1{v}}; + assign small_value = {2{128'h1234}}; +endmodule +)"); + Compilation compilation; + compilation.addSyntaxTree(tree); + NO_COMPILATION_ERRORS; +}