Skip to content

Commit

Permalink
Allow serenum members initializers refer to other serenum members (#3617
Browse files Browse the repository at this point in the history
)

Signed-off-by: Mihai Budiu <[email protected]>
  • Loading branch information
Mihai Budiu authored Oct 25, 2022
1 parent be4120d commit ecea88c
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 17 deletions.
21 changes: 11 additions & 10 deletions frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<IR::Type_SerEnum>();
CHECK_NULL(serEnum);
auto type = getTypeType(serEnum->type);
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion frontends/p4/typeChecking/typeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
14 changes: 11 additions & 3 deletions testdata/p4_16_errors_outputs/serenum-type.p4-stderr
Original file line number Diff line number Diff line change
@@ -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 {
^^^^^^^^
14 changes: 11 additions & 3 deletions testdata/p4_16_errors_outputs/serenum-typedef.p4-stderr
Original file line number Diff line number Diff line change
@@ -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 {
^^^^^^^^
6 changes: 6 additions & 0 deletions testdata/p4_16_samples/issue3616.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
enum bit<4> e {
a = 0,
b = 0,
c = (bit<4>)a,
d = a
}
7 changes: 7 additions & 0 deletions testdata/p4_16_samples_outputs/issue3616-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enum bit<4> e {
a = 4w0,
b = 4w0,
c = (bit<4>)a,
d = a
}

Empty file.
7 changes: 7 additions & 0 deletions testdata/p4_16_samples_outputs/issue3616.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
enum bit<4> e {
a = 0,
b = 0,
c = (bit<4>)a,
d = a
}

1 change: 1 addition & 0 deletions testdata/p4_16_samples_outputs/issue3616.p4-stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[--Wwarn=missing] warning: Program does not contain a `main' module

0 comments on commit ecea88c

Please sign in to comment.