-
Notifications
You must be signed in to change notification settings - Fork 466
Check for out/inout bindings aliased with uses #5318
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
base: main
Are you sure you want to change the base?
Conversation
@ChrisDodd Is this going to support also aliasing cases at the caller side? E.g. struct S {
bit<16> field
}
action foo(inout S, out bit<16>) { ... }
S s;
foo(S, s.field) |
I think that should already be an error -- using the same object for two different out or inout args in the same call. |
I might be missing something, but the following code compiles fine for me on struct S {
bit<16> field;
}
action foo(inout S s, inout bit<16> f) {
s.field = 42;
f = f + s.field;
}
action bar() {
S s = { 10 };
foo(s, s.field);
} Is this an error with this PR? |
Iirc this was allowed because the spec has precise description of the expected behavior. There was a similar issue with #2176 |
I really don't like allowing multiple writes to the same object in a single call, even though the spec has been worded to allow it. IMO that's s spec flaw we should discuss in the WG. I'm of a mind to add the check here (even though the spec says it should be ok), but it could also be "fixed" by inserting copies around the call (which, if desirable, should be done in a later, midend pass). In any case this needs more discussion. |
c3f1710
to
53f4bbc
Compare
- pass that finds captured expressions in callable (symbols defined outside the callable) - modify some failing tests to not have the error Signed-off-by: Chris Dodd <[email protected]>
Can this be solved in a way done with |
The main thing we're trying to avoid in P4 is "undefined behavior" -- where the spec doesn't say what happens, but an error diagnostic at compile time is not required. The existing spec currently avoids undefined behavior by specifying a strict behavior (copying argument left-to-right), while IMO it would be better to specify it as a compile time error. |
I know quite well what strict aliasing rules are, thanks :) As I mentioned, my idea is to optionally enforce no-alias rules. Certainly, the name of the option would be different, but essentially this might relax copy-in / copy-out semantics giving stronger guarantees to the compiler (in C terms everything would be |
This is compiler support for p4lang/p4-spec#1370.
Basically, the idea is that we want to forbid "aliasing" between out/inout arguments and things that are accessed directly in the called thing. This simplifies backends in that the don't have to detect such cases and special case them to avoid problematic behavior. The fact that there have been a number of issues in the past related to this aliasing suggests that alllowing it is problematic both from implementation complexity and user understanding. Having a clear compile-time error message (rather than confusing runtime behavior) is much better for all involved.
The implementation here is fairly straight-forward. There are two passes here
Currently it only looks at things on a per-field basis. Accesses to arrays are assumed to access any element of the array, and slices of fields are not tracked per-bit to see if they are disjoint or overlap. The code could be extended to track constant array indexes (so two different constant indexes would not overlap) and bit slices.
As can be seen there are a number of existing test cases that trigger this (new) error. Two of them have been moved to P4_16_errors, as what they were doing was highly questionable. The others have been modified to not have this error as they seem to be testing unrelated things.