Source file src/go/types/sizes_test.go

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file contains tests for sizes.
     6  
     7  package types_test
     8  
     9  import (
    10  	"go/ast"
    11  	"go/importer"
    12  	"go/parser"
    13  	"go/token"
    14  	"go/types"
    15  	"testing"
    16  )
    17  
    18  // findStructType typechecks src and returns the first struct type encountered.
    19  func findStructType(t *testing.T, src string) *types.Struct {
    20  	fset := token.NewFileSet()
    21  	f, err := parser.ParseFile(fset, "x.go", src, 0)
    22  	if err != nil {
    23  		t.Fatal(err)
    24  	}
    25  	info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
    26  	var conf types.Config
    27  	_, err = conf.Check("x", fset, []*ast.File{f}, &info)
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  	for _, tv := range info.Types {
    32  		if ts, ok := tv.Type.(*types.Struct); ok {
    33  			return ts
    34  		}
    35  	}
    36  	t.Fatalf("failed to find a struct type in src:\n%s\n", src)
    37  	return nil
    38  }
    39  
    40  // Issue 16316
    41  func TestMultipleSizeUse(t *testing.T) {
    42  	const src = `
    43  package main
    44  
    45  type S struct {
    46      i int
    47      b bool
    48      s string
    49      n int
    50  }
    51  `
    52  	ts := findStructType(t, src)
    53  	sizes := types.StdSizes{WordSize: 4, MaxAlign: 4}
    54  	if got := sizes.Sizeof(ts); got != 20 {
    55  		t.Errorf("Sizeof(%v) with WordSize 4 = %d want 20", ts, got)
    56  	}
    57  	sizes = types.StdSizes{WordSize: 8, MaxAlign: 8}
    58  	if got := sizes.Sizeof(ts); got != 40 {
    59  		t.Errorf("Sizeof(%v) with WordSize 8 = %d want 40", ts, got)
    60  	}
    61  }
    62  
    63  // Issue 16464
    64  func TestAlignofNaclSlice(t *testing.T) {
    65  	const src = `
    66  package main
    67  
    68  var s struct {
    69  	x *int
    70  	y []byte
    71  }
    72  `
    73  	ts := findStructType(t, src)
    74  	sizes := &types.StdSizes{WordSize: 4, MaxAlign: 8}
    75  	var fields []*types.Var
    76  	// Make a copy manually :(
    77  	for i := 0; i < ts.NumFields(); i++ {
    78  		fields = append(fields, ts.Field(i))
    79  	}
    80  	offsets := sizes.Offsetsof(fields)
    81  	if offsets[0] != 0 || offsets[1] != 4 {
    82  		t.Errorf("OffsetsOf(%v) = %v want %v", ts, offsets, []int{0, 4})
    83  	}
    84  }
    85  
    86  func TestIssue16902(t *testing.T) {
    87  	const src = `
    88  package a
    89  
    90  import "unsafe"
    91  
    92  const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
    93  `
    94  	fset := token.NewFileSet()
    95  	f, err := parser.ParseFile(fset, "x.go", src, 0)
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  	info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
   100  	conf := types.Config{
   101  		Importer: importer.Default(),
   102  		Sizes:    &types.StdSizes{WordSize: 8, MaxAlign: 8},
   103  	}
   104  	_, err = conf.Check("x", fset, []*ast.File{f}, &info)
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  	for _, tv := range info.Types {
   109  		_ = conf.Sizes.Sizeof(tv.Type)
   110  		_ = conf.Sizes.Alignof(tv.Type)
   111  	}
   112  }
   113  

View as plain text