-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
go/types: calling Sizeof(*Struct) twice with different sizes yields incorrect results #16316
Comments
Another, intermediate option: Store the Sizes param that was used to calculate the cached offsets. If it is unchanged (normal case), used the cache. Otherwise recalculate and replace the old cache. Simple, and should maintain performance for normal uses. It loses the concurrency safety of once.Do; does that matter? |
DO NOT SUBMIT [includes temporary workaround for issue golang#16316] The asmdecl check had hand-rolled code that calculated the size and offset of parameters based only on the AST. It included a list of known named types. This CL changes asmdecl to use go/types instead. This allows us to easily handle named types. It also adds support for structs, arrays, and complex parameters. It improves the default names given to unnamed parameters. Previously, all anonymous arguments were called "unnamed", and the first anonymous return argument was called "ret". Anonymous arguments are now called arg, arg1, arg2, etc., depending on the index in the argument list. Return arguments are ret, ret1, ret2. This CL also fixes a bug in the printing of composite data type sizes. Updates golang#11041 Change-Id: I1085116a26fe6199480b680eff659eb9ab31769b
DO NOT SUBMIT [includes temporary workaround for issue golang#16316] The asmdecl check had hand-rolled code that calculated the size and offset of parameters based only on the AST. It included a list of known named types. This CL changes asmdecl to use go/types instead. This allows us to easily handle named types. It also adds support for structs, arrays, and complex parameters. It improves the default names given to unnamed parameters. Previously, all anonymous arguments were called "unnamed", and the first anonymous return argument was called "ret". Anonymous arguments are now called arg, arg1, arg2, etc., depending on the index in the argument list. Return arguments are ret, ret1, ret2. This CL also fixes a bug in the printing of composite data type sizes. Updates golang#11041 Change-Id: I1085116a26fe6199480b680eff659eb9ab31769b
DO NOT SUBMIT [includes temporary workaround for issue golang#16316] The asmdecl check had hand-rolled code that calculated the size and offset of parameters based only on the AST. It included a list of known named types. This CL changes asmdecl to use go/types instead. This allows us to easily handle named types. It also adds support for structs, arrays, and complex parameters. It improves the default names given to unnamed parameters. Previously, all anonymous arguments were called "unnamed", and the first anonymous return argument was called "ret". Anonymous arguments are now called arg, arg1, arg2, etc., depending on the index in the argument list. Return arguments are ret, ret1, ret2. This CL also fixes a bug in the printing of composite data type sizes. Updates golang#11041 Change-Id: I1085116a26fe6199480b680eff659eb9ab31769b
I suspect recomputing the size each time is ok. I doubt this is a speed-critical portion of code. |
DO NOT SUBMIT [includes temporary workaround for issue golang#16316] The asmdecl check had hand-rolled code that calculated the size and offset of parameters based only on the AST. It included a list of known named types. This CL changes asmdecl to use go/types instead. This allows us to easily handle named types. It also adds support for structs, arrays, and complex parameters. It improves the default names given to unnamed parameters. Previously, all anonymous arguments were called "unnamed", and the first anonymous return argument was called "ret". Anonymous arguments are now called arg, arg1, arg2, etc., depending on the index in the argument list. Return arguments are ret, ret1, ret2. This CL also fixes a bug in the printing of composite data type sizes. Updates golang#11041 Change-Id: I1085116a26fe6199480b680eff659eb9ab31769b
I have a CL ready for 1.8 that removes the cache. I'm not sure how best to confirm that the performance impact is ok, though. Is there a standard corpus to measure on? |
@josharian I tend to run the type checker on the std lib and look at the times. But I doubt that will show you much. Calls to Sizeof are exceedingly rare. |
CL https://golang.org/cl/26995 mentions this issue. |
Typecheck a package containing:
Given
t
(of type*types.Struct
) that contains the typeS
, run:Want:
20
, then40
. Got:20
, then20
. It appears that the problem is ingo/types/sizes.go
:Once the offsets for a struct have been calculated once, they are cached forever, even if the
sizes
parameter changes.I encountered this while working on improvements to vet. I'm happy to fix, but I'd like input on what direction the fix should take. It's not obvious to me. The only decent options I see are:
(1) removing the cached offsets entirely
(2) keeping a map from StdSizes to cached offsets and type assert to go from Sizes to StdSizes (because not all Sizes implementations can serve as a map key)
and neither of those is particularly appealing.
My temporary workaround to eliminate the call to
s.offsetsOnce.Do
, to force recalculation each time.cc @griesemer @mdempsky
The text was updated successfully, but these errors were encountered: