diff --git a/frontends/p4/typeChecking/typeChecker.cpp b/frontends/p4/typeChecking/typeChecker.cpp index ffb746c70a0..975aff0ca6a 100644 --- a/frontends/p4/typeChecking/typeChecker.cpp +++ b/frontends/p4/typeChecking/typeChecker.cpp @@ -3782,9 +3782,17 @@ const IR::Node* TypeInference::postorder(IR::SwitchStatement* stat) { if (isCompileTimeConstant(stat->expression)) warn(ErrorType::WARN_MISMATCH, "%1%: constant expression in switch", stat->expression); + std::map caselabels; for (auto& c : stat->cases) { if (!isCompileTimeConstant(c->label)) typeError("%1%: must be a compile-time constant", c->label); + if (auto cst = c->label->to()) { + auto it = caselabels.find(cst->value); + if (it != caselabels.end()) { + typeError("%1%: 'switch' label duplicates %2%", c->label, it->second); + } + caselabels.emplace(cst->value, c->label); + } auto lt = getType(c->label); if (lt == nullptr) continue; if (lt->is() && type->is()) { diff --git a/testdata/p4_16_errors/duplicate-switch-case.p4 b/testdata/p4_16_errors/duplicate-switch-case.p4 new file mode 100644 index 00000000000..fcab9e84d4a --- /dev/null +++ b/testdata/p4_16_errors/duplicate-switch-case.p4 @@ -0,0 +1,17 @@ +// https://github.com/p4lang/p4c/issues/3612 +#include + +control c(in bit<4> a) +{ + apply { + switch (a) { + 4w0: {} + 4w1: {} // { dg-note "" } + 4w1: {} // { dg-error "" } + } + } +} + +control ct(in bit<4> a); +package pt(ct t); +pt(c()) main; diff --git a/testdata/p4_16_errors_outputs/duplicate-switch-case.p4 b/testdata/p4_16_errors_outputs/duplicate-switch-case.p4 new file mode 100644 index 00000000000..e22e17813e0 --- /dev/null +++ b/testdata/p4_16_errors_outputs/duplicate-switch-case.p4 @@ -0,0 +1,18 @@ +#include + +control c(in bit<4> a) { + apply { + switch (a) { + 4w0: { + } + 4w1: { + } + 4w1: { + } + } + } +} + +control ct(in bit<4> a); +package pt(ct t); +pt(c()) main; diff --git a/testdata/p4_16_errors_outputs/duplicate-switch-case.p4-stderr b/testdata/p4_16_errors_outputs/duplicate-switch-case.p4-stderr new file mode 100644 index 00000000000..c5ab9771ea3 --- /dev/null +++ b/testdata/p4_16_errors_outputs/duplicate-switch-case.p4-stderr @@ -0,0 +1,6 @@ +duplicate-switch-case.p4(10): [--Werror=type-error] error: 4w1: 'switch' label duplicates 4w1 + 4w1: {} // { dg-error "" } + ^^^ +duplicate-switch-case.p4(9) + 4w1: {} // { dg-note "" } + ^^^