diff --git a/midend/eliminateSwitch.cpp b/midend/eliminateSwitch.cpp index 01be5223a5..ad16bea8ae 100644 --- a/midend/eliminateSwitch.cpp +++ b/midend/eliminateSwitch.cpp @@ -19,6 +19,21 @@ limitations under the License. namespace P4 { +const IR::Node* DoEliminateSwitch::postorder(IR::P4Program* program) { + if (!exactNeeded) + return program; + for (auto *obj : program->objects) { + if (auto *match_kind = obj->to()) { + if (match_kind->getDeclByName(P4CoreLibrary::instance.exactMatch.Id())) + return program; + } + } + ::error(ErrorType::ERR_NOT_FOUND, + "Could not find declaration for 'match_kind.exact', which is needed to implement " + "switch statements; did you include core.p4?"); + return program; +} + const IR::Node* DoEliminateSwitch::postorder(IR::P4Control* control) { for (auto a : toInsert) control->controlLocals.push_back(a); @@ -54,6 +69,7 @@ const IR::Node* DoEliminateSwitch::postorder(IR::SwitchStatement* statement) { auto tableKeyEl = new IR::KeyElement( src, new IR::PathExpression(key), new IR::PathExpression(P4CoreLibrary::instance.exactMatch.Id())); + exactNeeded = true; IR::IndexedVector actionsList; IR::IndexedVector properties; IR::Vector cases; diff --git a/midend/eliminateSwitch.h b/midend/eliminateSwitch.h index 8b1c81663c..b9f373d285 100644 --- a/midend/eliminateSwitch.h +++ b/midend/eliminateSwitch.h @@ -79,11 +79,14 @@ class DoEliminateSwitch final : public Transform { const TypeMap* typeMap; std::vector toInsert; public: - explicit DoEliminateSwitch(ReferenceMap* refMap, const TypeMap* typeMap): + bool exactNeeded = false; + + DoEliminateSwitch(ReferenceMap* refMap, const TypeMap* typeMap): refMap(refMap), typeMap(typeMap) { setName("DoEliminateSwitch"); CHECK_NULL(refMap); CHECK_NULL(typeMap); } const IR::Node* postorder(IR::SwitchStatement* statement) override; const IR::Node* postorder(IR::P4Control* control) override; + const IR::Node* postorder(IR::P4Program* program) override; }; class EliminateSwitch final : public PassManager { diff --git a/testdata/p4_16_errors/issue3613.p4 b/testdata/p4_16_errors/issue3613.p4 new file mode 100644 index 0000000000..79ec7e6937 --- /dev/null +++ b/testdata/p4_16_errors/issue3613.p4 @@ -0,0 +1,11 @@ +control c(in bit<4> a) +{ + apply { + switch (a) { + 4w0: {} + } + } +} +control ct(in bit<4> a); +package pt(ct t); +pt(c()) main; diff --git a/testdata/p4_16_errors_outputs/issue3613-first.p4 b/testdata/p4_16_errors_outputs/issue3613-first.p4 new file mode 100644 index 0000000000..bf16b50296 --- /dev/null +++ b/testdata/p4_16_errors_outputs/issue3613-first.p4 @@ -0,0 +1,12 @@ +control c(in bit<4> a) { + apply { + switch (a) { + 4w0: { + } + } + } +} + +control ct(in bit<4> a); +package pt(ct t); +pt(c()) main; diff --git a/testdata/p4_16_errors_outputs/issue3613-frontend.p4 b/testdata/p4_16_errors_outputs/issue3613-frontend.p4 new file mode 100644 index 0000000000..bf16b50296 --- /dev/null +++ b/testdata/p4_16_errors_outputs/issue3613-frontend.p4 @@ -0,0 +1,12 @@ +control c(in bit<4> a) { + apply { + switch (a) { + 4w0: { + } + } + } +} + +control ct(in bit<4> a); +package pt(ct t); +pt(c()) main; diff --git a/testdata/p4_16_errors_outputs/issue3613.p4 b/testdata/p4_16_errors_outputs/issue3613.p4 new file mode 100644 index 0000000000..bf16b50296 --- /dev/null +++ b/testdata/p4_16_errors_outputs/issue3613.p4 @@ -0,0 +1,12 @@ +control c(in bit<4> a) { + apply { + switch (a) { + 4w0: { + } + } + } +} + +control ct(in bit<4> a); +package pt(ct t); +pt(c()) main; diff --git a/testdata/p4_16_errors_outputs/issue3613.p4-stderr b/testdata/p4_16_errors_outputs/issue3613.p4-stderr new file mode 100644 index 0000000000..d8f3481940 --- /dev/null +++ b/testdata/p4_16_errors_outputs/issue3613.p4-stderr @@ -0,0 +1 @@ +[--Werror=not-found] error: Could not find declaration for 'match_kind.exact', which is needed to implement switch statements; did you include core.p4?