diff --git a/frontends/p4/typeChecking/typeChecker.cpp b/frontends/p4/typeChecking/typeChecker.cpp index 7b5eaa0235b..a4052d6ff80 100644 --- a/frontends/p4/typeChecking/typeChecker.cpp +++ b/frontends/p4/typeChecking/typeChecker.cpp @@ -1386,11 +1386,7 @@ const IR::Node* TypeInference::postorder(IR::Type_Enum* type) { return type; } -const IR::Node* TypeInference::postorder(IR::Type_SerEnum* type) { - if (::errorCount()) - // If we failed to typecheck a SerEnumMember we do not - // want to set the type for the SerEnum either. - return type; +const IR::Node* TypeInference::preorder(IR::Type_SerEnum* type) { auto canon = setTypeType(type); for (auto e : *type->getDeclarations()) setType(e->getNode(), canon); @@ -1432,8 +1428,11 @@ const IR::Node* TypeInference::postorder(IR::Type_Set* type) { } const IR::Node* TypeInference::postorder(IR::SerEnumMember* member) { - if (done()) - return member; + /* + The type of the member is initially set in the Type_SerEnum preorder visitor. + Here we check additional constraints and we may correct the member. + if (done()) return member; + */ auto serEnum = findContext(); CHECK_NULL(serEnum); auto type = getTypeType(serEnum->type); @@ -1442,9 +1441,9 @@ const IR::Node* TypeInference::postorder(IR::SerEnumMember* member) { return member; } auto exprType = getType(member->value); - auto tvs = unify(member, type, exprType, - "Enum member '%1%' has type '%2%' and not the expected type '%2%'", - { member, exprType, type }); + auto tvs = unifyCast(member, type, exprType, + "Enum member '%1%' has type '%2%' and not the expected type '%3%'", + { member, exprType, type }); if (tvs == nullptr) // error already signalled return member; @@ -1453,6 +1452,8 @@ const IR::Node* TypeInference::postorder(IR::SerEnumMember* member) { ConstantTypeSubstitution cts(tvs, refMap, typeMap, this); member->value = cts.convert(member->value); // sets type + if (!typeMap->getType(member)) + setType(member, getTypeType(serEnum)); return member; } diff --git a/frontends/p4/typeChecking/typeChecker.h b/frontends/p4/typeChecking/typeChecker.h index 5acd48da8fc..651acd668c2 100644 --- a/frontends/p4/typeChecking/typeChecker.h +++ b/frontends/p4/typeChecking/typeChecker.h @@ -222,6 +222,7 @@ class TypeInference : public Transform { const IR::Node* preorder(IR::Declaration_Instance* decl) override; // check invariants for entire list before checking the entries const IR::Node* preorder(IR::EntriesList* el) override; + const IR::Node* preorder(IR::Type_SerEnum* type) override; const IR::Node* postorder(IR::Declaration_MatchKind* decl) override; const IR::Node* postorder(IR::Declaration_Variable* decl) override; @@ -239,7 +240,6 @@ class TypeInference : public Transform { const IR::Node* postorder(IR::Type_Base* type) override; const IR::Node* postorder(IR::Type_Var* type) override; const IR::Node* postorder(IR::Type_Enum* type) override; - const IR::Node* postorder(IR::Type_SerEnum* type) override; const IR::Node* postorder(IR::Type_Extern* type) override; const IR::Node* postorder(IR::StructField* field) override; const IR::Node* postorder(IR::Type_Header* type) override; diff --git a/testdata/p4_16_errors_outputs/serenum-type.p4-stderr b/testdata/p4_16_errors_outputs/serenum-type.p4-stderr index 15870555060..8192d0b9913 100644 --- a/testdata/p4_16_errors_outputs/serenum-type.p4-stderr +++ b/testdata/p4_16_errors_outputs/serenum-type.p4-stderr @@ -1,6 +1,14 @@ serenum-type.p4(8): [--Werror=type-error] error: EthT: Illegal type for enum; only bit<> and int<> are allowed enum EthT EthTypes { ^^^^ -serenum-type.p4(57): [--Werror=type-error] error: prs: cannot evaluate to a compile-time constant -top(prs(), c()) main; - ^^^^^ +serenum-type.p4(49): [--Werror=type-error] error: cast + h.eth.type = (EthTypes)(bit<16>)0; + ^^^^^^^^^^^^^^^^^^^^ + ---- Actual error: +serenum-type.p4(8): Cannot unify type 'bit<16>' with type 'EthTypes' + enum EthT EthTypes { + ^^^^^^^^ + ---- Originating from: +serenum-type.p4(8): Cannot cast from 'bit<16>' to 'EthTypes' + enum EthT EthTypes { + ^^^^^^^^ diff --git a/testdata/p4_16_errors_outputs/serenum-typedef.p4-stderr b/testdata/p4_16_errors_outputs/serenum-typedef.p4-stderr index bd1f14b8190..95b56d924d7 100644 --- a/testdata/p4_16_errors_outputs/serenum-typedef.p4-stderr +++ b/testdata/p4_16_errors_outputs/serenum-typedef.p4-stderr @@ -1,6 +1,14 @@ serenum-typedef.p4(8): [--Werror=type-error] error: EthT: Illegal type for enum; only bit<> and int<> are allowed enum EthT EthTypes { ^^^^ -serenum-typedef.p4(57): [--Werror=type-error] error: prs: cannot evaluate to a compile-time constant -top(prs(), c()) main; - ^^^^^ +serenum-typedef.p4(49): [--Werror=type-error] error: cast + h.eth.type = (EthTypes)(bit<16>)0; + ^^^^^^^^^^^^^^^^^^^^ + ---- Actual error: +serenum-typedef.p4(8): Cannot unify type 'bit<16>' with type 'EthTypes' + enum EthT EthTypes { + ^^^^^^^^ + ---- Originating from: +serenum-typedef.p4(8): Cannot cast from 'bit<16>' to 'EthTypes' + enum EthT EthTypes { + ^^^^^^^^ diff --git a/testdata/p4_16_samples/issue3616.p4 b/testdata/p4_16_samples/issue3616.p4 new file mode 100644 index 00000000000..7b58593dae3 --- /dev/null +++ b/testdata/p4_16_samples/issue3616.p4 @@ -0,0 +1,6 @@ +enum bit<4> e { + a = 0, + b = 0, + c = (bit<4>)a, + d = a +} \ No newline at end of file diff --git a/testdata/p4_16_samples_outputs/issue3616-first.p4 b/testdata/p4_16_samples_outputs/issue3616-first.p4 new file mode 100644 index 00000000000..2da634812e2 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue3616-first.p4 @@ -0,0 +1,7 @@ +enum bit<4> e { + a = 4w0, + b = 4w0, + c = (bit<4>)a, + d = a +} + diff --git a/testdata/p4_16_samples_outputs/issue3616-frontend.p4 b/testdata/p4_16_samples_outputs/issue3616-frontend.p4 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/testdata/p4_16_samples_outputs/issue3616.p4 b/testdata/p4_16_samples_outputs/issue3616.p4 new file mode 100644 index 00000000000..55077bdd761 --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue3616.p4 @@ -0,0 +1,7 @@ +enum bit<4> e { + a = 0, + b = 0, + c = (bit<4>)a, + d = a +} + diff --git a/testdata/p4_16_samples_outputs/issue3616.p4-stderr b/testdata/p4_16_samples_outputs/issue3616.p4-stderr new file mode 100644 index 00000000000..7e57a518ffd --- /dev/null +++ b/testdata/p4_16_samples_outputs/issue3616.p4-stderr @@ -0,0 +1 @@ +[--Wwarn=missing] warning: Program does not contain a `main' module