aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSteven Kabbes <[email protected]>2022-05-21 04:19:39 -0700
committerRon Evans <[email protected]>2022-05-25 11:01:00 +0200
commit52c61de19f068b8c932c1546fc671ea809e0c899 (patch)
tree17381abbe6d4fdb1834ce68405b1f50a876f4526
parentf308d7d28ca8d1d06a9cdca928f06086dfd4e26c (diff)
downloadtinygo-52c61de19f068b8c932c1546fc671ea809e0c899.tar.gz
tinygo-52c61de19f068b8c932c1546fc671ea809e0c899.zip
compiler: alignof(func) is 1 pointer, not 2
This ensures that an embedded [0]func() never ends up being larger than 1 pointer, which is requried by protobuf processing code.
-rw-r--r--compiler/sizes.go10
-rw-r--r--testdata/reflect.go7
-rw-r--r--testdata/reflect.txt3
3 files changed, 14 insertions, 6 deletions
diff --git a/compiler/sizes.go b/compiler/sizes.go
index 57108323b..5f28f161a 100644
--- a/compiler/sizes.go
+++ b/compiler/sizes.go
@@ -21,12 +21,6 @@ func (s *stdSizes) Alignof(T types.Type) int64 {
// of alignment of the elements and fields, respectively.
switch t := T.Underlying().(type) {
case *types.Array:
- if t.Len() == 0 {
- // 0-sized arrays, always have 0 size.
- // And from the spec, should have an alignment of _at least_ 1
- return 1
- }
-
// spec: "For a variable x of array type: unsafe.Alignof(x)
// is the same as unsafe.Alignof(x[0]), but at least 1."
return s.Alignof(t.Elem())
@@ -51,7 +45,11 @@ func (s *stdSizes) Alignof(T types.Type) int64 {
if t.Info()&types.IsString != 0 {
return s.PtrSize
}
+ case *types.Signature:
+ // Even though functions in tinygo are 2 pointers, they are not 2 pointer aligned
+ return s.PtrSize
}
+
a := s.Sizeof(T) // may be 0
// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
if a < 1 {
diff --git a/testdata/reflect.go b/testdata/reflect.go
index f48683150..f36fcca73 100644
--- a/testdata/reflect.go
+++ b/testdata/reflect.go
@@ -347,6 +347,13 @@ func main() {
println("errorValue.Implements(errorType) was true, expected false")
}
+ println("\nalignment / offset:")
+ v2 := struct {
+ noCompare [0]func()
+ data byte
+ }{}
+ println("struct{[0]func(); byte}:", unsafe.Offsetof(v2.data) == uintptr(unsafe.Pointer(&v2.data))-uintptr(unsafe.Pointer(&v2)))
+
println("\nstruct tags")
TestStructTag()
diff --git a/testdata/reflect.txt b/testdata/reflect.txt
index c07fc01d8..f2b455aa9 100644
--- a/testdata/reflect.txt
+++ b/testdata/reflect.txt
@@ -405,6 +405,9 @@ offset for int64 matches: true
offset for complex128 matches: true
type assertion succeeded for unreferenced type
+alignment / offset:
+struct{[0]func(); byte}: true
+
struct tags
blue gopher