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
7package types2_test
8
9import (
10	"cmd/compile/internal/syntax"
11	"cmd/compile/internal/types2"
12	"testing"
13)
14
15// findStructType typechecks src and returns the first struct type encountered.
16func findStructType(t *testing.T, src string) *types2.Struct {
17	f, err := parseSrc("x.go", src)
18	if err != nil {
19		t.Fatal(err)
20	}
21	info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
22	var conf types2.Config
23	_, err = conf.Check("x", []*syntax.File{f}, &info)
24	if err != nil {
25		t.Fatal(err)
26	}
27	for _, tv := range info.Types {
28		if ts, ok := tv.Type.(*types2.Struct); ok {
29			return ts
30		}
31	}
32	t.Fatalf("failed to find a struct type in src:\n%s\n", src)
33	return nil
34}
35
36// Issue 16316
37func TestMultipleSizeUse(t *testing.T) {
38	const src = `
39package main
40
41type S struct {
42    i int
43    b bool
44    s string
45    n int
46}
47`
48	ts := findStructType(t, src)
49	sizes := types2.StdSizes{WordSize: 4, MaxAlign: 4}
50	if got := sizes.Sizeof(ts); got != 20 {
51		t.Errorf("Sizeof(%v) with WordSize 4 = %d want 20", ts, got)
52	}
53	sizes = types2.StdSizes{WordSize: 8, MaxAlign: 8}
54	if got := sizes.Sizeof(ts); got != 40 {
55		t.Errorf("Sizeof(%v) with WordSize 8 = %d want 40", ts, got)
56	}
57}
58
59// Issue 16464
60func TestAlignofNaclSlice(t *testing.T) {
61	const src = `
62package main
63
64var s struct {
65	x *int
66	y []byte
67}
68`
69	ts := findStructType(t, src)
70	sizes := &types2.StdSizes{WordSize: 4, MaxAlign: 8}
71	var fields []*types2.Var
72	// Make a copy manually :(
73	for i := 0; i < ts.NumFields(); i++ {
74		fields = append(fields, ts.Field(i))
75	}
76	offsets := sizes.Offsetsof(fields)
77	if offsets[0] != 0 || offsets[1] != 4 {
78		t.Errorf("OffsetsOf(%v) = %v want %v", ts, offsets, []int{0, 4})
79	}
80}
81
82func TestIssue16902(t *testing.T) {
83	const src = `
84package a
85
86import "unsafe"
87
88const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
89`
90	f, err := parseSrc("x.go", src)
91	if err != nil {
92		t.Fatal(err)
93	}
94	info := types2.Info{Types: make(map[syntax.Expr]types2.TypeAndValue)}
95	conf := types2.Config{
96		Importer: defaultImporter(),
97		Sizes:    &types2.StdSizes{WordSize: 8, MaxAlign: 8},
98	}
99	_, err = conf.Check("x", []*syntax.File{f}, &info)
100	if err != nil {
101		t.Fatal(err)
102	}
103	for _, tv := range info.Types {
104		_ = conf.Sizes.Sizeof(tv.Type)
105		_ = conf.Sizes.Alignof(tv.Type)
106	}
107}
108