Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions frontends/p4/typeChecking/typeCheckStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ const IR::Node *TypeInferenceBase::postorder(const IR::SwitchStatement *stat) {
}
} else {
// switch (expression)
if (!(type->is<IR::Type_Bits>() || type->is<IR::Type_InfInt>() ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's about typedefs and type aliases? Are they already resolved here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we have any test cases that cover that. Also of potential concern is a Type_Variable (where the type may not have been inferenced yet). Best would be to add test cases to cover all of those.

type->is<IR::Type_Enum>() || type->is<IR::Type_SerEnum>() ||
type->is<IR::Type_Error>())) {
typeError("%1%: switch expression cannot be of type %2%", stat->expression,
type->toString());
return stat;
}

Comparison comp;
comp.left = stat->expression;

Expand Down
43 changes: 43 additions & 0 deletions testdata/p4_16_errors/issue5120.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
@command_line("--preferSwitch")

extern void __e(in bit<28> arg);
extern void __e2(in bit<28> arg);

control C() {
action bar(bool a, bool b) {
bit<28> x; bit<28> y;
switch (a) {
b: {
__e(x);
}
default: {
if (b) {
__e2(y);
}
}
}
}

action baz() {
bar(true, false);
}

action foo() {
baz();

}

table t {
actions = { foo; }
default_action = foo;
}

apply {
t.apply();
}
}

control proto();
package top(proto p);

top(C()) main;
32 changes: 32 additions & 0 deletions testdata/p4_16_errors/issue5313_type_variable.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@command_line("--preferSwitch")

// Generic helper over a type variable T.
// The switch is written in terms of T; T is instantiated later.
void bar_generic<T>(T v, out bit<8> y) {
switch (v) {
0b01: { y = 1; }
0b10: { y = 2; }
default: { y = 0; }
}
}

control C(out bit<8> y) {
action foo() {
// Here T is instantiated as bit<2>, so switch(v) is on bit<2>.
bar_generic<bit<2>>(1, y);
}

table t {
actions = { foo; }
default_action = foo;
}

apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);

top(C()) main;
32 changes: 32 additions & 0 deletions testdata/p4_16_errors/issue5313_typealiass.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@command_line("--preferSwitch")

type bit<2> TwoBitsAlias;

void bar(bit<2> x, out bit<8> y) {
TwoBitsAlias a = (TwoBitsAlias)x;
switch (a) {
0b01: { y = 4; }
0b10: { y = 5; }
default: { y = y; }
}
}

control C(out bit<8> y) {
action foo() {
bar(1, y);
}

table t {
actions = { foo; }
default_action = foo;
}

apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);

top(C()) main;
37 changes: 37 additions & 0 deletions testdata/p4_16_errors_outputs/issue5120.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
@command_line("--preferSwitch") extern void __e(in bit<28> arg);
extern void __e2(in bit<28> arg);
control C() {
action bar(bool a, bool b) {
bit<28> x;
bit<28> y;
switch (a) {
b: {
__e(x);
}
default: {
if (b) {
__e2(y);
}
}
}
}
action baz() {
bar(true, false);
}
action foo() {
baz();
}
table t {
actions = {
foo;
}
default_action = foo;
}
apply {
t.apply();
}
}

control proto();
package top(proto p);
top(C()) main;
3 changes: 3 additions & 0 deletions testdata/p4_16_errors_outputs/issue5120.p4-stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
issue5120.p4(9): [--Werror=type-error] error: a: switch expression cannot be of type bool
switch (a) {
^
31 changes: 31 additions & 0 deletions testdata/p4_16_errors_outputs/issue5313_type_variable.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@command_line("--preferSwitch") void bar_generic<T>(T v, out bit<8> y) {
switch (v) {
0b1: {
y = 1;
}
0b10: {
y = 2;
}
default: {
y = 0;
}
}
}
control C(out bit<8> y) {
action foo() {
bar_generic<bit<2>>(1, y);
}
table t {
actions = {
foo;
}
default_action = foo;
}
apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);
top(C()) main;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
issue5313_type_variable.p4(6): [--Werror=type-error] error: v: switch expression cannot be of type T
switch (v) {
^
33 changes: 33 additions & 0 deletions testdata/p4_16_errors_outputs/issue5313_typealiass.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@command_line("--preferSwitch") type bit<2> TwoBitsAlias;
void bar(bit<2> x, out bit<8> y) {
TwoBitsAlias a = (TwoBitsAlias)x;
switch (a) {
0b1: {
y = 4;
}
0b10: {
y = 5;
}
default: {
y = y;
}
}
}
control C(out bit<8> y) {
action foo() {
bar(1, y);
}
table t {
actions = {
foo;
}
default_action = foo;
}
apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);
top(C()) main;
3 changes: 3 additions & 0 deletions testdata/p4_16_errors_outputs/issue5313_typealiass.p4-stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
issue5313_typealiass.p4(7): [--Werror=type-error] error: a: switch expression cannot be of type TwoBitsAlias
switch (a) {
^
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
stmt-switch-on-unsupported-type.p4(3): [--Wwarn=unused] warning: control 'ctrl' is unused
control ctrl()() {
^^^^
stmt-switch-on-unsupported-type.p4(5): [--Werror=type-error] error: ...: could not find default value
stmt-switch-on-unsupported-type.p4(5): [--Werror=type-error] error: ...: switch expression cannot be of type ANYTYPE
switch (...) { }
^^^
28 changes: 28 additions & 0 deletions testdata/p4_16_samples/issue5313.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@command_line("--preferSwitch")

void bar(bit<2> x, out bit<8> y) {
switch (x) {
0b01: { y = 2; }
0b10: { y = 3; }
}
}

control C(out bit<8> y) {
action foo() {
bar(1, y);
}

table t {
actions = { foo; }
default_action = foo;
}

apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);

top(C()) main;
30 changes: 30 additions & 0 deletions testdata/p4_16_samples/issue5313_aliass.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
@command_line("--preferSwitch")

typedef bit<2> TwoBits;

void bar(TwoBits x, out bit<8> y) {
switch (x) {
0b01: { y = 2; }
0b10: { y = 3; }
}
}

control C(out bit<8> y) {
action foo() {
bar(1, y);
}

table t {
actions = { foo; }
default_action = foo;
}

apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);

top(C()) main;
28 changes: 28 additions & 0 deletions testdata/p4_16_samples_outputs/issue5313-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@command_line("--preferSwitch") void bar(bit<2> x, out bit<8> y) {
switch (x) {
2w0b1: {
y = 8w2;
}
2w0b10: {
y = 8w3;
}
}
}
control C(out bit<8> y) {
action foo() {
bar(2w1, y);
}
table t {
actions = {
foo();
}
default_action = foo();
}
apply {
t.apply();
}
}

control proto(out bit<8> y);
package top(proto p);
top(C()) main;
27 changes: 27 additions & 0 deletions testdata/p4_16_samples_outputs/issue5313-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
control C(out bit<8> y) {
@name("C.y_0") bit<8> y_1;
@name("C.foo") action foo() {
switch (2w1) {
2w0b1: {
y_1 = 8w2;
}
2w0b10: {
y_1 = 8w3;
}
}
y = y_1;
}
@name("C.t") table t_0 {
actions = {
foo();
}
default_action = foo();
}
apply {
t_0.apply();
}
}

control proto(out bit<8> y);
package top(proto p);
top(C()) main;
27 changes: 27 additions & 0 deletions testdata/p4_16_samples_outputs/issue5313-midend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
control C(out bit<8> y) {
@name("C.y_0") bit<8> y_1;
@name("C.foo") action foo() {
switch (2w1) {
2w0b1: {
y_1 = 8w2;
}
2w0b10: {
y_1 = 8w3;
}
}
y = y_1;
}
@name("C.t") table t_0 {
actions = {
foo();
}
default_action = foo();
}
apply {
t_0.apply();
}
}

control proto(out bit<8> y);
package top(proto p);
top(C()) main;
Loading
Loading