-
Notifications
You must be signed in to change notification settings - Fork 449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shadowing a control parameter within an apply block is disallowed #5092
Comments
By normal (C/C++) scoping rules, one would expect |
Hmm, to clarify if I understood correctly, does it mean that control ingress(inout Headers h /* A */) {
apply {
Headers h /* B */ = h /* C */;
}
} C is referring to B, not A? I thought that C refers to A. |
Yes, I think C unambiguously refers to B here, not A. More problematic is something like:
here, does C refer to A or B? Yes, it is clearly before B is defined, but the spec doesn't say that B is ignored for name lookup, just that referring to it in this way is an error. Note the spec's statement " all uses of a symbol must follow the symbol’s declaration. (This is a departure from P4_14, which allows declarations in any order. This requirement significantly simplifies the implementation of compilers for P4_16)" which is patently false due to this sort of problem -- it adds a whole bunch of implementation difficulty to name resolution lookup and doesn't really help parsing. |
Assignments like Note that in C++ (at least from my testing) shadowing a function argument is disallowed, but only when the shadowing happens in the top-level block -- if it happens in a sub-block, it is allowed, but the RHS already refers to the new name. In the case of use-before-define, C++ does not take the "to be declared" variable into account, which is consistent with the wannabe-single-pass parsing relict from C. C++ does have a case where name resolution works as you suggested though -- in the class constructor's initialization section, |
control ingress(inout Headers h /* A */) {
/* control-local layer */
apply {
Headers h /* B */ = h /* C */;
}
} It does make sense to reject this program if A and B live in the same scoping level. But I thought A and B live in different levels because they are separated by a block (curly braces One piece of evidence is that, below program is accepted by the p4c frontend, yet with shadow warnings. control ingress(inout Headers h) {
Headers h = h;
apply {
Headers h = h;
}
}
So, it seems like control parameters and local variables in an apply block are not in the same scoping level, because there is a control-local layer in between. If we were to write the program as below (with abuse of P4 syntax), then A and B indeed lies in the same scope. However, I believe that the presence of a control-local layer differentiates the two. control ingress {
apply(inout Headers h /* A */) {
Headers h /* B */ = h /* C */;
}
} |
issue2544_shadowing1.p4 defines a local variable
h
, of the same name with the control parameterh
, but this is disallowed by the frontend.inout Headers h
andHeaders h = h
reside in different blocks, so there should be no problem in disambiguating the right-hand side of the assignmenth
(coming from the control parameter) from the localh
.I suppose #2589 was a fix for this issue, but is there a reason for the p4c frontend to reject this program?
The text was updated successfully, but these errors were encountered: