Skip to content

Commit

Permalink
Be better about preserving the types of packed structs and unions use…
Browse files Browse the repository at this point in the history
…d in binary operators
  • Loading branch information
MikePopoloski committed May 26, 2024
1 parent cabaf18 commit 0e6a1a2
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 6 deletions.
13 changes: 8 additions & 5 deletions source/ast/expressions/OperatorExpressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ const Type* Expression::binaryOperatorType(Compilation& compilation, const Type*
if (!lt->isNumeric() || !rt->isNumeric())
return &compilation.getErrorType();

// If both sides are the same type just use that type.
// NOTE: This specifically ignores the forceFourState option for enums,
// as that better matches expectations. This area of the LRM is underspecified.
if (lt->isMatching(*rt)) {
if (!forceFourState || lt->isFourState() || lt->isEnum())
return lt;
}

// Figure out what the result type of an arithmetic binary operator should be. The rules are:
// - If either operand is real, the result is real
// - Otherwise, if either operand is shortreal, the result is shortreal
Expand All @@ -131,11 +139,6 @@ const Type* Expression::binaryOperatorType(Compilation& compilation, const Type*
result = &compilation.getShortRealType();
}
}
else if (lt->isEnum() && rt->isEnum() && lt->isMatching(*rt)) {
// If both sides are the same enum type, preserve that in the output type.
// NOTE: This specifically ignores the forceFourState option.
return lt;
}
else {
bitwidth_t width = std::max(lt->getBitWidth(), rt->getBitWidth());

Expand Down
2 changes: 1 addition & 1 deletion tests/unittests/ast/ExpressionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ TEST_CASE("Expression types") {
CHECK(typeof("su2 == su2") == "bit");
CHECK(typeof("EVAL1 + 5") == "int");
CHECK(typeof("up + 5") == "logic[31:0]");
CHECK(typeof("up + up") == "logic[1:0]");
CHECK(typeof("up + up") == "union packed{logic[1:0] a;bit[0:1] b;}u$1");

// Unpacked arrays
declare("bit [7:0] arr1 [2];");
Expand Down
21 changes: 21 additions & 0 deletions tests/unittests/ast/WarningTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,3 +944,24 @@ endmodule
CHECK(diags[4].code == diag::SignCompare);
CHECK(diags[5].code == diag::BitwiseOpMismatch);
}

TEST_CASE("Binary operator with struct type preserves the type") {
auto tree = SyntaxTree::fromText(R"(
module top;
typedef struct packed {
logic [1:0] a;
logic [1:0] b;
} s_t;
s_t a, b, c, d;
always_comb begin
d = a | b | c;
end
endmodule
)");

Compilation compilation;
compilation.addSyntaxTree(tree);
NO_COMPILATION_ERRORS;
}

0 comments on commit 0e6a1a2

Please sign in to comment.