diff --git a/frontends/p4/duplicateActionControlPlaneNameCheck.cpp b/frontends/p4/duplicateActionControlPlaneNameCheck.cpp index 5c921f091f..13dd2b1c1e 100644 --- a/frontends/p4/duplicateActionControlPlaneNameCheck.cpp +++ b/frontends/p4/duplicateActionControlPlaneNameCheck.cpp @@ -24,7 +24,8 @@ cstring DuplicateActionControlPlaneNameCheck::getName(const IR::IDeclaration *de return decl->getName(); } -void DuplicateActionControlPlaneNameCheck::checkForDuplicateName(cstring name, const IR::Node *node) { +void DuplicateActionControlPlaneNameCheck::checkForDuplicateName(cstring name, + const IR::Node *node) { bool foundDuplicate = false; auto *otherNode = node; auto [it, inserted] = actions.insert(std::pair(name, node)); diff --git a/testdata/p4_16_samples/actions-almost-duplicate-names1.p4 b/testdata/p4_16_samples/actions-almost-duplicate-names1.p4 new file mode 100644 index 0000000000..15084de938 --- /dev/null +++ b/testdata/p4_16_samples/actions-almost-duplicate-names1.p4 @@ -0,0 +1,152 @@ +/* +Copyright 2024 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include + +typedef bit<48> EthernetAddress; + +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +struct headers_t { + ethernet_t ethernet; +} + +struct metadata_t { +} + +parser parserImpl( + packet_in pkt, + out headers_t hdr, + inout metadata_t meta, + inout standard_metadata_t stdmeta) +{ + state start { + pkt.extract(hdr.ethernet); + transition accept; + } +} + +control verifyChecksum( + inout headers_t hdr, + inout metadata_t meta) +{ + apply { } +} + +action foo1() { +} + +@name("foo2") +action foo2() { +} + +@name(".baz") +action foo3() { +} + +control ingressImpl( + inout headers_t hdr, + inout metadata_t meta, + inout standard_metadata_t stdmeta) +{ + bit<8> tmp1; + bit<8> tmp2; + + // This is not a name conflict with foo1, because it has a top + // level name ".foo1", but a1 will have hierarchical name + // "ingressImpl.foo1". + @name("foo1") action a1 (bit<8> x, bit<8> y) { tmp1 = x >> 1; tmp2 = y; } + + // This should not be a name conflict with foo2, because it has a + // top level name ".foo2", but a2 will have hierarchical name + // "ingressImpl.foo2". + // TODO: However, it is a @name conflict in the current p4c + // implementation until a PR like #4970 is merged in. + //@name("foo2") action a2 (bit<8> x, bit<8> y) { tmp1 = x >> 2; tmp2 = y; } + + @name(".bar") action a3 (bit<8> x, bit<8> y) { tmp1 = x >> 3; tmp2 = y; } + // This is not a name conflict with a3, because it has a top level + // name ".bar", but a4 will have hierarchical name + // "ingressImpl.bar". + @name("bar") action a4 (bit<8> x, bit<8> y) { tmp1 = x >> 4; tmp2 = y; } + + // This is not a name conflict with foo3, because it has a top + // level name ".baz", but a5 will have hierarchical name + // "ingressImpl.baz". + @name("baz") action a5 (bit<8> x, bit<8> y) { tmp1 = x >> 5; tmp2 = y; } + + table t1 { + actions = { + NoAction; + a1; + //a2; + a3; + a4; + a5; + foo1; + foo2; + foo3; + } + key = { hdr.ethernet.etherType: exact; } + default_action = NoAction(); + size = 512; + } + apply { + tmp1 = hdr.ethernet.srcAddr[7:0]; + tmp2 = hdr.ethernet.dstAddr[7:0]; + t1.apply(); + // This is here simply to ensure that the compiler cannot + // optimize away the effects of t1 and t2, which can only + // assign values to variables tmp1 and tmp2. + hdr.ethernet.etherType = (bit<16>) (tmp1 - tmp2); + } +} + +control egressImpl( + inout headers_t hdr, + inout metadata_t meta, + inout standard_metadata_t stdmeta) +{ + apply { } +} + +control updateChecksum( + inout headers_t hdr, + inout metadata_t meta) +{ + apply { } +} + +control deparserImpl( + packet_out pkt, + in headers_t hdr) +{ + apply { + pkt.emit(hdr.ethernet); + } +} + +V1Switch(parserImpl(), + verifyChecksum(), + ingressImpl(), + egressImpl(), + updateChecksum(), + deparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-first.p4 b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-first.p4 new file mode 100644 index 0000000000..d606f50225 --- /dev/null +++ b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-first.p4 @@ -0,0 +1,97 @@ +#include +#define V1MODEL_VERSION 20180101 +#include + +typedef bit<48> EthernetAddress; +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +struct headers_t { + ethernet_t ethernet; +} + +struct metadata_t { +} + +parser parserImpl(packet_in pkt, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + state start { + pkt.extract(hdr.ethernet); + transition accept; + } +} + +control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +action foo1() { +} +@name("foo2") action foo2() { +} +@name(".baz") action foo3() { +} +control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + bit<8> tmp1; + bit<8> tmp2; + @name("foo1") action a1(bit<8> x, bit<8> y) { + tmp1 = x >> 1; + tmp2 = y; + } + @name(".bar") action a3(bit<8> x, bit<8> y) { + tmp1 = x >> 3; + tmp2 = y; + } + @name("bar") action a4(bit<8> x, bit<8> y) { + tmp1 = x >> 4; + tmp2 = y; + } + @name("baz") action a5(bit<8> x, bit<8> y) { + tmp1 = x >> 5; + tmp2 = y; + } + table t1 { + actions = { + NoAction(); + a1(); + a3(); + a4(); + a5(); + foo1(); + foo2(); + foo3(); + } + key = { + hdr.ethernet.etherType: exact @name("hdr.ethernet.etherType"); + } + default_action = NoAction(); + size = 512; + } + apply { + tmp1 = hdr.ethernet.srcAddr[7:0]; + tmp2 = hdr.ethernet.dstAddr[7:0]; + t1.apply(); + hdr.ethernet.etherType = (bit<16>)(tmp1 - tmp2); + } +} + +control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + apply { + } +} + +control updateChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +control deparserImpl(packet_out pkt, in headers_t hdr) { + apply { + pkt.emit(hdr.ethernet); + } +} + +V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-frontend.p4 b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-frontend.p4 new file mode 100644 index 0000000000..7198191873 --- /dev/null +++ b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-frontend.p4 @@ -0,0 +1,99 @@ +#include +#define V1MODEL_VERSION 20180101 +#include + +typedef bit<48> EthernetAddress; +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +struct headers_t { + ethernet_t ethernet; +} + +struct metadata_t { +} + +parser parserImpl(packet_in pkt, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + state start { + pkt.extract(hdr.ethernet); + transition accept; + } +} + +control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + @name("ingressImpl.tmp1") bit<8> tmp1_0; + @name("ingressImpl.tmp2") bit<8> tmp2_0; + @noWarn("unused") @name(".NoAction") action NoAction_1() { + } + @name(".foo1") action foo1_0() { + } + @name("ingressImpl.foo2") action foo2_0() { + } + @name(".baz") action foo3_0() { + } + @name("ingressImpl.foo1") action a1(@name("x") bit<8> x, @name("y") bit<8> y) { + tmp1_0 = x >> 1; + tmp2_0 = y; + } + @name(".bar") action a3(@name("x") bit<8> x_4, @name("y") bit<8> y_4) { + tmp1_0 = x_4 >> 3; + tmp2_0 = y_4; + } + @name("ingressImpl.bar") action a4(@name("x") bit<8> x_5, @name("y") bit<8> y_5) { + tmp1_0 = x_5 >> 4; + tmp2_0 = y_5; + } + @name("ingressImpl.baz") action a5(@name("x") bit<8> x_6, @name("y") bit<8> y_6) { + tmp1_0 = x_6 >> 5; + tmp2_0 = y_6; + } + @name("ingressImpl.t1") table t1_0 { + actions = { + NoAction_1(); + a1(); + a3(); + a4(); + a5(); + foo1_0(); + foo2_0(); + foo3_0(); + } + key = { + hdr.ethernet.etherType: exact @name("hdr.ethernet.etherType"); + } + default_action = NoAction_1(); + size = 512; + } + apply { + tmp1_0 = hdr.ethernet.srcAddr[7:0]; + tmp2_0 = hdr.ethernet.dstAddr[7:0]; + t1_0.apply(); + hdr.ethernet.etherType = (bit<16>)(tmp1_0 - tmp2_0); + } +} + +control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + apply { + } +} + +control updateChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +control deparserImpl(packet_out pkt, in headers_t hdr) { + apply { + pkt.emit(hdr.ethernet); + } +} + +V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-midend.p4 b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-midend.p4 new file mode 100644 index 0000000000..d1cca333c6 --- /dev/null +++ b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1-midend.p4 @@ -0,0 +1,116 @@ +#include +#define V1MODEL_VERSION 20180101 +#include + +header ethernet_t { + bit<48> dstAddr; + bit<48> srcAddr; + bit<16> etherType; +} + +struct headers_t { + ethernet_t ethernet; +} + +struct metadata_t { +} + +parser parserImpl(packet_in pkt, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + state start { + pkt.extract(hdr.ethernet); + transition accept; + } +} + +control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + @name("ingressImpl.tmp1") bit<8> tmp1_0; + @name("ingressImpl.tmp2") bit<8> tmp2_0; + @noWarn("unused") @name(".NoAction") action NoAction_1() { + } + @name(".foo1") action foo1_0() { + } + @name("ingressImpl.foo2") action foo2_0() { + } + @name(".baz") action foo3_0() { + } + @name("ingressImpl.foo1") action a1(@name("x") bit<8> x, @name("y") bit<8> y) { + tmp1_0 = x >> 1; + tmp2_0 = y; + } + @name(".bar") action a3(@name("x") bit<8> x_4, @name("y") bit<8> y_4) { + tmp1_0 = x_4 >> 3; + tmp2_0 = y_4; + } + @name("ingressImpl.bar") action a4(@name("x") bit<8> x_5, @name("y") bit<8> y_5) { + tmp1_0 = x_5 >> 4; + tmp2_0 = y_5; + } + @name("ingressImpl.baz") action a5(@name("x") bit<8> x_6, @name("y") bit<8> y_6) { + tmp1_0 = x_6 >> 5; + tmp2_0 = y_6; + } + @name("ingressImpl.t1") table t1_0 { + actions = { + NoAction_1(); + a1(); + a3(); + a4(); + a5(); + foo1_0(); + foo2_0(); + foo3_0(); + } + key = { + hdr.ethernet.etherType: exact @name("hdr.ethernet.etherType"); + } + default_action = NoAction_1(); + size = 512; + } + @hidden action actionsalmostduplicatenames1l113() { + tmp1_0 = hdr.ethernet.srcAddr[7:0]; + tmp2_0 = hdr.ethernet.dstAddr[7:0]; + } + @hidden action actionsalmostduplicatenames1l119() { + hdr.ethernet.etherType = (bit<16>)(tmp1_0 - tmp2_0); + } + @hidden table tbl_actionsalmostduplicatenames1l113 { + actions = { + actionsalmostduplicatenames1l113(); + } + const default_action = actionsalmostduplicatenames1l113(); + } + @hidden table tbl_actionsalmostduplicatenames1l119 { + actions = { + actionsalmostduplicatenames1l119(); + } + const default_action = actionsalmostduplicatenames1l119(); + } + apply { + tbl_actionsalmostduplicatenames1l113.apply(); + t1_0.apply(); + tbl_actionsalmostduplicatenames1l119.apply(); + } +} + +control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + apply { + } +} + +control updateChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +control deparserImpl(packet_out pkt, in headers_t hdr) { + apply { + pkt.emit(hdr.ethernet); + } +} + +V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4 b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4 new file mode 100644 index 0000000000..a85e79f001 --- /dev/null +++ b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4 @@ -0,0 +1,97 @@ +#include +#define V1MODEL_VERSION 20180101 +#include + +typedef bit<48> EthernetAddress; +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +struct headers_t { + ethernet_t ethernet; +} + +struct metadata_t { +} + +parser parserImpl(packet_in pkt, out headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + state start { + pkt.extract(hdr.ethernet); + transition accept; + } +} + +control verifyChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +action foo1() { +} +@name("foo2") action foo2() { +} +@name(".baz") action foo3() { +} +control ingressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + bit<8> tmp1; + bit<8> tmp2; + @name("foo1") action a1(bit<8> x, bit<8> y) { + tmp1 = x >> 1; + tmp2 = y; + } + @name(".bar") action a3(bit<8> x, bit<8> y) { + tmp1 = x >> 3; + tmp2 = y; + } + @name("bar") action a4(bit<8> x, bit<8> y) { + tmp1 = x >> 4; + tmp2 = y; + } + @name("baz") action a5(bit<8> x, bit<8> y) { + tmp1 = x >> 5; + tmp2 = y; + } + table t1 { + actions = { + NoAction; + a1; + a3; + a4; + a5; + foo1; + foo2; + foo3; + } + key = { + hdr.ethernet.etherType: exact; + } + default_action = NoAction(); + size = 512; + } + apply { + tmp1 = hdr.ethernet.srcAddr[7:0]; + tmp2 = hdr.ethernet.dstAddr[7:0]; + t1.apply(); + hdr.ethernet.etherType = (bit<16>)(tmp1 - tmp2); + } +} + +control egressImpl(inout headers_t hdr, inout metadata_t meta, inout standard_metadata_t stdmeta) { + apply { + } +} + +control updateChecksum(inout headers_t hdr, inout metadata_t meta) { + apply { + } +} + +control deparserImpl(packet_out pkt, in headers_t hdr) { + apply { + pkt.emit(hdr.ethernet); + } +} + +V1Switch(parserImpl(), verifyChecksum(), ingressImpl(), egressImpl(), updateChecksum(), deparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4-stderr b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4-stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4.entries.txtpb b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4.entries.txtpb new file mode 100644 index 0000000000..5cb9652623 --- /dev/null +++ b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4.entries.txtpb @@ -0,0 +1,3 @@ +# proto-file: p4/v1/p4runtime.proto +# proto-message: p4.v1.WriteRequest + diff --git a/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4.p4info.txtpb b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4.p4info.txtpb new file mode 100644 index 0000000000..76b13ff063 --- /dev/null +++ b/testdata/p4_16_samples_outputs/actions-almost-duplicate-names1.p4.p4info.txtpb @@ -0,0 +1,146 @@ +# proto-file: p4/config/v1/p4info.proto +# proto-message: p4.config.v1.P4Info + +pkg_info { + arch: "v1model" +} +tables { + preamble { + id: 49173205 + name: "ingressImpl.t1" + alias: "t1" + } + match_fields { + id: 1 + name: "hdr.ethernet.etherType" + bitwidth: 16 + match_type: EXACT + } + action_refs { + id: 21257015 + } + action_refs { + id: 30176274 + } + action_refs { + id: 21008649 + } + action_refs { + id: 27458909 + } + action_refs { + id: 24058105 + } + action_refs { + id: 25646030 + } + action_refs { + id: 17174663 + } + action_refs { + id: 28708850 + } + initial_default_action { + action_id: 21257015 + } + size: 512 +} +actions { + preamble { + id: 21257015 + name: "NoAction" + alias: "NoAction" + annotations: "@noWarn(\"unused\")" + } +} +actions { + preamble { + id: 25646030 + name: "foo1" + alias: "foo1" + } +} +actions { + preamble { + id: 17174663 + name: "ingressImpl.foo2" + alias: "foo2" + } +} +actions { + preamble { + id: 28708850 + name: "baz" + alias: "baz" + } +} +actions { + preamble { + id: 30176274 + name: "ingressImpl.foo1" + alias: "ingressImpl.foo1" + } + params { + id: 1 + name: "x" + bitwidth: 8 + } + params { + id: 2 + name: "y" + bitwidth: 8 + } +} +actions { + preamble { + id: 21008649 + name: "bar" + alias: "bar" + } + params { + id: 1 + name: "x" + bitwidth: 8 + } + params { + id: 2 + name: "y" + bitwidth: 8 + } +} +actions { + preamble { + id: 27458909 + name: "ingressImpl.bar" + alias: "ingressImpl.bar" + } + params { + id: 1 + name: "x" + bitwidth: 8 + } + params { + id: 2 + name: "y" + bitwidth: 8 + } +} +actions { + preamble { + id: 24058105 + name: "ingressImpl.baz" + alias: "ingressImpl.baz" + } + params { + id: 1 + name: "x" + bitwidth: 8 + } + params { + id: 2 + name: "y" + bitwidth: 8 + } +} +type_info { +}