Skip to content

Commit

Permalink
Implict cast fix
Browse files Browse the repository at this point in the history
- Allow implicit casts from serializable enums to their underlying
  type in action calls
  • Loading branch information
ChrisDodd committed Feb 8, 2024
1 parent 12dafee commit 934a6e8
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 2 deletions.
2 changes: 1 addition & 1 deletion bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,4 @@ make_relative_link ()
make_relative_link "${mydir}/.gdbinit" "backends/bmv2/p4c-bm2-psa-gdb.gdb"
make_relative_link "${mydir}/.gdbinit" "backends/bmv2/p4c-bm2-ss-gdb.gdb"
make_relative_link "${mydir}/.gdbinit" "backends/dpdk/p4c-dpdk-gdb.gdb"
make_relative_link "${mydir}/.gdbinit" "backends/dpdk/p4test-gdb.gdb"
make_relative_link "${mydir}/.gdbinit" "backends/p4test/p4test-gdb.gdb"
4 changes: 3 additions & 1 deletion frontends/p4/typeChecking/typeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3496,7 +3496,7 @@ const IR::Expression *TypeInference::actionCall(bool inActionList,
if (paramType == nullptr || argType == nullptr)
// type checking failed before
return actionCall;
constraints.addEqualityConstraint(actionCall, paramType, argType);
constraints.addImplicitCastConstraint(actionCall, paramType, argType);
if (param->direction == IR::Direction::None) {
if (inActionList) {
typeError("%1%: parameter %2% cannot be bound: it is set by the control plane", arg,
Expand All @@ -3512,6 +3512,8 @@ const IR::Expression *TypeInference::actionCall(bool inActionList,
typeError("%1%: action argument must be a compile-time constant",
arg->expression);
}
// This is like an assignment; may make additional conversions.
newExpr = assignment(arg, param->type, arg->expression);
} else if (param->direction == IR::Direction::Out ||
param->direction == IR::Direction::InOut) {
if (!isLeftValue(arg->expression))
Expand Down
6 changes: 6 additions & 0 deletions frontends/p4/typeChecking/typeConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ void TypeConstraints::addEqualityConstraint(const IR::Node *source, const IR::Ty
add(c);
}

void TypeConstraints::addImplicitCastConstraint(const IR::Node *source, const IR::Type *left,
const IR::Type *right) {
auto c = new CanBeImplicitlyCastConstraint(left, right, source);
add(c);
}

TypeVariableSubstitution *TypeConstraints::solve() {
LOG3("Solving constraints:\n" << *this);
currentSubstitution = new TypeVariableSubstitution();
Expand Down
2 changes: 2 additions & 0 deletions frontends/p4/typeChecking/typeConstraints.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,8 @@ class TypeConstraints final : public IHasDbPrint {
constraints.push_back(constraint);
}
void addEqualityConstraint(const IR::Node *source, const IR::Type *left, const IR::Type *right);
void addImplicitCastConstraint(const IR::Node *source, const IR::Type *left,
const IR::Type *right);
/*
* Solve the specified constraint.
* @param subst Variable substitution which is updated with new constraints.
Expand Down
2 changes: 2 additions & 0 deletions frontends/p4/typeChecking/typeUnification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,10 +444,12 @@ bool TypeUnification::unify(const BinaryConstraint *constraint) {
if (!success) return constraint->reportError(constraints->getCurrentSubstitution());
return true;
} else if (auto se = dest->to<IR::Type_SerEnum>()) {
#if 1
if (constraint->is<P4::CanBeImplicitlyCastConstraint>()) {
constraints->add(constraint->create(se->type, src));
return true;
}
#endif
return constraint->reportError(constraints->getCurrentSubstitution());
} else if (dest->is<IR::Type_Declaration>() && src->is<IR::Type_Declaration>()) {
if (dest->to<IR::Type_Declaration>()->name != src->to<IR::Type_Declaration>()->name)
Expand Down
22 changes: 22 additions & 0 deletions testdata/p4_16_errors/serEnumImplCast.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <core.p4>

enum bit<2> foo_t { A = 0, B = 1, C = 2, D = 3 }

struct meta_t {
bit<2> x;
bit<6> y;
}

control c(inout meta_t m) {
action set_x(foo_t v) { m.x = v; }

table t {
key = { m.y : exact; }
actions = { set_x; }
default_action = set_x(2w0); // not allowed to implicitly cast to serenum
}

apply {
t.apply();
}
}
32 changes: 32 additions & 0 deletions testdata/p4_16_errors_outputs/serEnumImplCast.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <core.p4>

enum bit<2> foo_t {
A = 0,
B = 1,
C = 2,
D = 3
}

struct meta_t {
bit<2> x;
bit<6> y;
}

control c(inout meta_t m) {
action set_x(foo_t v) {
m.x = v;
}
table t {
key = {
m.y: exact;
}
actions = {
set_x;
}
default_action = set_x(2w0);
}
apply {
t.apply();
}
}

6 changes: 6 additions & 0 deletions testdata/p4_16_errors_outputs/serEnumImplCast.p4-stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
serEnumImplCast.p4(16): [--Werror=type-error] error: '2w0': values of type 'bit<2>' cannot be implicitly cast to type 'foo_t'
default_action = set_x(2w0); // not allowed to implicitly cast to serenum
^^^
serEnumImplCast.p4(3)
enum bit<2> foo_t { A = 0, B = 1, C = 2, D = 3 }
^^^^^
22 changes: 22 additions & 0 deletions testdata/p4_16_samples/serEnumImplCast.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include <core.p4>

enum bit<2> foo_t { A = 0, B = 1, C = 2, D = 3 }

struct meta_t {
bit<2> x;
bit<6> y;
}

control c(inout meta_t m) {
action set_x(bit<2> v) { m.x = v; }

table t {
key = { m.y : exact; }
actions = { set_x; }
default_action = set_x(foo_t.A);
}

apply {
t.apply();
}
}
32 changes: 32 additions & 0 deletions testdata/p4_16_samples_outputs/serEnumImplCast-first.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <core.p4>

enum bit<2> foo_t {
A = 2w0,
B = 2w1,
C = 2w2,
D = 2w3
}

struct meta_t {
bit<2> x;
bit<6> y;
}

control c(inout meta_t m) {
action set_x(bit<2> v) {
m.x = v;
}
table t {
key = {
m.y: exact @name("m.y");
}
actions = {
set_x();
}
default_action = set_x(foo_t.A);
}
apply {
t.apply();
}
}

7 changes: 7 additions & 0 deletions testdata/p4_16_samples_outputs/serEnumImplCast-frontend.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <core.p4>

struct meta_t {
bit<2> x;
bit<6> y;
}

32 changes: 32 additions & 0 deletions testdata/p4_16_samples_outputs/serEnumImplCast.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <core.p4>

enum bit<2> foo_t {
A = 0,
B = 1,
C = 2,
D = 3
}

struct meta_t {
bit<2> x;
bit<6> y;
}

control c(inout meta_t m) {
action set_x(bit<2> v) {
m.x = v;
}
table t {
key = {
m.y: exact;
}
actions = {
set_x;
}
default_action = set_x(foo_t.A);
}
apply {
t.apply();
}
}

1 change: 1 addition & 0 deletions testdata/p4_16_samples_outputs/serEnumImplCast.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 934a6e8

Please sign in to comment.