Commit 343b7fa6 authored by Keith Randall's avatar Keith Randall Committed by Keith Randall

cmd/compile: don't mark argument array as noalg

It ends up making two similar types, [N]uint8 of both
alg and noalg varieties. Comparsions between the two then
don't come out equal when they should.
In particular, the type *[N]uint8 has an Elem pointer which
must point to one of the above two types; it can't point to both.
Thus allocating a *[N]uint8 and dereferencing it might be a
different type than a [N]uint8.

The fix is easy. Making a small test for this is really hard. It
requires that both a argless defer and the test be imported by a
common parent package. This is why a main binary doesn't see this
issue, but a test does (as Agniva noticed), because there's a wrapper
package that imports both the test and the defer.

Types like [N]uint8 don't really need to be marked noalg anyway,
as the generated code (if any) will be shared among all
vanilla memory types of the same size.

Fixes #32595

Change-Id: If7b77fa6ed56cd4495601c3f90170682d853b82f
Reviewed-on: https://go-review.googlesource.com/c/go/+/182357
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 8382ccb0
...@@ -330,7 +330,6 @@ func deferstruct(stksize int64) *types.Type { ...@@ -330,7 +330,6 @@ func deferstruct(stksize int64) *types.Type {
return f return f
} }
argtype := types.NewArray(types.Types[TUINT8], stksize) argtype := types.NewArray(types.Types[TUINT8], stksize)
argtype.SetNoalg(true)
argtype.Width = stksize argtype.Width = stksize
argtype.Align = 1 argtype.Align = 1
// These fields must match the ones in runtime/runtime2.go:_defer and // These fields must match the ones in runtime/runtime2.go:_defer and
......
// Copyright 2019 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.
package a
func A() {
defer func() {}()
}
// Copyright 2019 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.
package b
import "reflect"
func B() {
t1 := reflect.TypeOf([0]byte{})
t2 := reflect.TypeOf(new([0]byte)).Elem()
if t1 != t2 {
panic("[0]byte types do not match")
}
}
// Copyright 2019 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.
package main
import (
"a"
"b"
)
func main() {
a.A()
b.B()
}
// rundir
// Copyright 2019 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.
package ignored
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment