-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
x/tools/go/ssa: mistakenly converts slice index to int on 32 bit systems #50949
Comments
Thank you for the report. SSA is not faithfully translating the original program. Here are possible options for resolving this:
My thoughts:
Thoughts on the preferred resolution? In the meantime, I'll try to get some thoughts from the compiler folks for how to faithfully lower the check. |
Relevant part of cmd/compile: go/src/cmd/compile/internal/ssagen/ssa.go Line 7378 in a42bbf4
This solutions requires knowing the sizes of the target architecture. |
FWIW, this is the solution cmd/compile uses in its IR representation, where bounds checks are still implicit as part of the index operation. It's only once we lower to SSA where bounds checks are explicit that we constrain the size of the index value, because it needs to be register-sized for instruction selection / register allocation. |
I'm in favour of option 2. Adding explicit bounds checks with branches seems out of place. go/ssa doesn't explicitly encode panics in the CFG. Interface assertions, slice indexing, map writes, pointer dereferences, all are assumed to panic dynamically, without these edges being part of the CFG. Adding a new instruction that checks the bounds before the conversion seems unnecessarily detailed, and somewhat redundant with IndexAddr also doing bounds checking on the The only faithful representation of the language semantics is IndexAddr accepting any integer type. There is no conversion to int, and doing additional bounds checking and conversions outside the IndexAddr instruction creates new behavior that doesn't exist¹.
They don't have to change much. The type of the index is no longer guaranteed to be ¹: this is all considering that go/ssa is a high-level IR that represents the language as specified. It doesn't encode the actual, lowered to real instructions, behavior. |
I also lean towards option 2. Adding explicit checks with branches also might increase the size of SSA unnecessarily. |
The plan is to implement the fix based on option 2, which will happen after #48525 is done. |
Change https://go.dev/cl/387996 mentions this issue: |
Consider this program:
go/ssa compiles it to
both times converting the index to
int
before using it. But on systems whereint
is 32 bits wide, this is not correct. Compare with the runtime behavior on GOARCH=386: The first indexing operation panics withpanic: runtime error: index out of range [4294967302] with length 16
while the second one succeeds, accessing x[6], thanks to wrap-around.https://go.dev/ref/spec#Index_expressions is the relevant section of the specification.
/cc @timothy-king
The text was updated successfully, but these errors were encountered: