p4c icon indicating copy to clipboard operation
p4c copied to clipboard

decls and state names, are they in the same namespaces?

Open apinski-cavium opened this issue 2 years ago • 5 comments

Take:

parser p()
{
  bit<4> t;
  state start {
    t = 1;
    transition t;
  }
  state t {
    transition accept;
  }
}

Currently p4c rejects this with saying t is declared as a different type. The spec just mentions that 2 states need to be not named the same but it does not say anything about naming the same as the a local decl. I found this on accident when I was writing up a testcase for value_set.

apinski-cavium avatar Oct 14 '22 04:10 apinski-cavium

This is what the spec says:

At least one state, named start, must be present in any parser. A parser may not define two states with the same name. It is also illegal for a parser to give explicit definitions for the accept and reject states—those states are logically distinct from the states defined by the programmer.

apinski-cavium avatar Oct 14 '22 04:10 apinski-cavium

FWIW, Petr4 accepts this. I think p4c is overly conservative here.

jnfoster avatar Oct 14 '22 11:10 jnfoster

At least p4c is catching the error that the transition statement needs a state, not a bit field to transition to. Now, should p4c detect invalid type first or detect name clash with decl first or test for both and then emit both errors?

hesingh avatar Oct 14 '22 13:10 hesingh

@hesingh I don't think it has to be an error. Parser starts can be declared in any order. So the transition may legally be to the state t.

jnfoster avatar Oct 14 '22 13:10 jnfoster

I know parser states can be in any order, but p4c should at least give an error that the Parser never reaches accept or reject state. With changes to P4 code as shown below, latest p4c-bm2-ss does give the error for not reaching accept or reject state. The p4c frontend emits the error.

-- a/testdata/p4_16_samples/basic_routing-bmv2.p4
+++ b/testdata/p4_16_samples/basic_routing-bmv2.p4
@@ -38,6 +38,7 @@ struct headers {
 }
 
 parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
+    bit<8> j;
     state parse_ethernet {
         packet.extract(hdr = hdr.ethernet);
         transition select(hdr.ethernet.etherType) {
@@ -50,7 +51,8 @@ parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout
         transition accept;
     }
     state start {
-        transition parse_ethernet;
+        j = 1;
+        transition j; //parse_ethernet;
     }
 }

hesingh avatar Oct 14 '22 15:10 hesingh

The LDWG has established that the compiler implements the correct behavior: https://github.com/p4lang/p4-spec/pull/1217

mihaibudiu avatar Jan 10 '23 19:01 mihaibudiu