It was not responsive to the sizes param.
Remove it, and unwind the extra layers.
Fixes #16316
Change-Id: I940a57184a1601f52348d4bff8638f3f7462f5cd
Reviewed-on: https://go-review.googlesource.com/26995
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
if n == 0 {
return 0
}
- setOffsets(t, s)
- return t.offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
+ offsets := s.Offsetsof(t.fields)
+ return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
case *Interface:
return s.WordSize * 2
}
if T.NumFields() > 0 {
// compute offsets on demand
if s := conf.Sizes; s != nil {
- calculated := setOffsets(T, s)
- offsets = T.offsets
- if calculated {
- // sanity checks
- if len(offsets) != T.NumFields() {
- panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
- }
- for _, o := range offsets {
- if o < 0 {
- panic("Config.Sizes.Offsetsof returned an offset < 0")
- }
+ offsets := s.Offsetsof(T.fields)
+ // sanity checks
+ if len(offsets) != T.NumFields() {
+ panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
+ }
+ for _, o := range offsets {
+ if o < 0 {
+ panic("Config.Sizes.Offsetsof returned an offset < 0")
}
}
} else {
- setOffsets(T, &stdSizes)
- offsets = T.offsets
+ offsets = stdSizes.Offsetsof(T.fields)
}
}
return offsets
y := x + a - 1
return y - y%a
}
-
-// setOffsets sets the offsets of s for the given sizes if necessary.
-// The result is true if the offsets were not set before; otherwise it
-// is false.
-func setOffsets(s *Struct, sizes Sizes) bool {
- var calculated bool
- s.offsetsOnce.Do(func() {
- calculated = true
- s.offsets = sizes.Offsetsof(s.fields)
- })
- return calculated
-}
--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for sizes.
+
+package types_test
+
+import (
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "go/types"
+ "testing"
+)
+
+// findStructType typechecks src and returns the first struct type encountered.
+func findStructType(t *testing.T, src string) *types.Struct {
+ fset := token.NewFileSet()
+ f, err := parser.ParseFile(fset, "x.go", src, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
+ var conf types.Config
+ _, err = conf.Check("x", fset, []*ast.File{f}, &info)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, tv := range info.Types {
+ if ts, ok := tv.Type.(*types.Struct); ok {
+ return ts
+ }
+ }
+ t.Fatalf("failed to find a struct type in src:\n%s\n", src)
+ return nil
+}
+
+// Issue 16316
+func TestMultipleSizeUse(t *testing.T) {
+ const src = `
+package main
+
+type S struct {
+ i int
+ b bool
+ s string
+ n int
+}
+`
+ ts := findStructType(t, src)
+ sizes := types.StdSizes{WordSize: 4, MaxAlign: 4}
+ if got := sizes.Sizeof(ts); got != 20 {
+ t.Errorf("Sizeof(%v) with WordSize 4 = %d want 20", ts, got)
+ }
+ sizes = types.StdSizes{WordSize: 8, MaxAlign: 8}
+ if got := sizes.Sizeof(ts); got != 40 {
+ t.Errorf("Sizeof(%v) with WordSize 8 = %d want 40", ts, got)
+ }
+}
package types
-import (
- "sort"
- "sync"
-)
+import "sort"
// A Type represents a type of Go.
// All types implement the Type interface.
// A Struct represents a struct type.
type Struct struct {
- fields []*Var
- tags []string // field tags; nil if there are no tags
- offsets []int64 // field offsets in bytes, lazily initialized
- offsetsOnce sync.Once // for threadsafe lazy initialization of offsets
+ fields []*Var
+ tags []string // field tags; nil if there are no tags
}
// NewStruct returns a new struct with the given fields and corresponding field tags.