Misc internal and test work towards enum type checks (#726).

This commit is contained in:
Wilson Snyder 2022-01-01 22:14:46 -05:00
parent 9bda91b3bf
commit bf972963f4
7 changed files with 76 additions and 11 deletions

View File

@ -1699,7 +1699,7 @@ public:
editCountInc();
}
}
void dtypeFrom(AstNode* fromp) {
void dtypeFrom(const AstNode* fromp) {
if (fromp) dtypep(fromp->dtypep());
}
void dtypeChgSigned(bool flag = true);

View File

@ -101,9 +101,17 @@ std::ostream& operator<<(std::ostream& str, const Determ& rhs) {
return str << s_det[rhs];
}
enum Castable : uint8_t { UNSUPPORTED, COMPATIBLE, DYNAMIC_ENUM, DYNAMIC_CLASS, INCOMPATIBLE };
enum Castable : uint8_t {
UNSUPPORTED,
COMPATIBLE,
ENUM_EXPLICIT,
ENUM_IMPLICIT,
DYNAMIC_CLASS,
INCOMPATIBLE
};
std::ostream& operator<<(std::ostream& str, const Castable& rhs) {
static const char* const s_det[] = {"UNSUP", "COMPAT", "DYN_ENUM", "DYN_CLS", "INCOMPAT"};
static const char* const s_det[]
= {"UNSUP", "COMPAT", "ENUM_EXP", "ENUM_IMP", "DYN_CLS", "INCOMPAT"};
return str << s_det[rhs];
}
@ -1665,7 +1673,7 @@ private:
if (castable == DYNAMIC_CLASS) {
// Keep in place, will compute at runtime
return;
} else if (castable == DYNAMIC_ENUM) {
} else if (castable == ENUM_EXPLICIT || castable == ENUM_IMPLICIT) {
// TODO is from is a constant we could simplify, though normal constant
// elimination should do much the same
// Form: "( ((v > size) ? false : enum_valid[v[N:0]])
@ -1760,7 +1768,8 @@ private:
<< toDtp->prettyDTypeNameQ() << " from "
<< fromDtp->prettyDTypeNameQ());
bad = true;
} else if (castable == COMPATIBLE || castable == DYNAMIC_ENUM) {
} else if (castable == COMPATIBLE || castable == ENUM_IMPLICIT
|| castable == ENUM_EXPLICIT) {
; // Continue
} else if (castable == DYNAMIC_CLASS) {
nodep->v3error("Dynamic, not static cast, required to cast "
@ -6277,7 +6286,8 @@ private:
if (VN_IS(toDtp, BasicDType) || VN_IS(toDtp, NodeUOrStructDType)) {
if (fromNumericable) return COMPATIBLE;
} else if (VN_IS(toDtp, EnumDType)) {
if (fromNumericable) return DYNAMIC_ENUM;
if (VN_IS(fromBaseDtp, EnumDType) && toDtp->sameTree(fromDtp)) return ENUM_IMPLICIT;
if (fromNumericable) return ENUM_EXPLICIT;
} else if (VN_IS(toDtp, ClassRefDType) && VN_IS(fromConstp, Const)) {
if (VN_IS(fromConstp, Const) && VN_AS(fromConstp, Const)->num().isNull())
return COMPATIBLE;

View File

@ -59,7 +59,7 @@ module t (/*AUTOARG*/
end
//
else if (cyc == 20) begin
e <= 'h11; // Unknown
e <= my_t'('h11); // Unknown
end
else if (cyc == 21) begin
`checks(e.name, ""); // Unknown

View File

@ -42,7 +42,7 @@ module t (/*AUTOARG*/
e <= E01;
end
else if (cyc==20) begin
e <= 'h11; // Unknown
e <= my_t'('h11); // Unknown
end
else if (cyc==21) begin
`checks(e.name, ""); // Unknown

View File

@ -0,0 +1,18 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2022 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(vlt => 1);
lint(
fails => 0, # But should fail
);
ok(1);
1;

View File

@ -0,0 +1,37 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2022 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t;
typedef enum {ZERO, ONE, TWO} e_t;
typedef enum {THREE=3, FOUR, FIVE} o_t;
typedef struct packed {
e_t m_e;
o_t m_o;
} struct_t;
initial begin
e_t e;
o_t o;
struct_t str;
e = ONE;
e = e_t'(1);
e = e;
e = 1; // Bad
o = e; // Bad
str.m_e = ONE;
str.m_o = THREE;
e = str.m_e;
o = str.m_o;
o = str.m_e; // Bad
end
endmodule

View File

@ -92,9 +92,9 @@ module t (clk);
v_string <= cyc[0] ? "foo" : "bar";
v_arr_real[0] <= v_arr_real[0] + 0.2;
v_arr_real[1] <= v_arr_real[1] + 0.3;
v_enumed <= v_enumed + 1;
v_enumed2 <= v_enumed2 + 2;
v_enumb <= v_enumb - 1;
v_enumed <= enumed_t'(v_enumed + 1);
v_enumed2 <= enumed_t'(v_enumed2 + 2);
v_enumb <= enumb_t'(v_enumb - 3'd1);
v_enumb2_str <= {v_enumb, v_enumb};
for (integer b=3; b<=4; b++) begin
v_arru[b] <= ~v_arru[b];