Ensures that deeply nested structs that have the underlying shape
of a pointer get unwrapped properly.
Update #77536
Change-Id: I004f424d2c62ec7026281daded9b3d96c021e2e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/747760
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit
1aa534dbb8970b86b0f4059b7665e3505d145e25)
Reviewed-on: https://go-review.googlesource.com/c/go/+/749460
// interface ops
(ITab (IMake itab _)) => itab
-(IData (IMake _ data)) => data
+(IData (IMake _ data)) && data.Op != OpStructMake && data.Op != OpArrayMake1 => data
+// Note: the conditional on data.Op ensures that StructMake/ArrayMake1 ops are
+// unwrapped before the IMake is thrown away. See issue 77534.
(Load <t> ptr mem) && t.IsInterface() =>
(IMake
config := b.Func.Config
typ := &b.Func.Config.Types
// match: (IData (IMake _ data))
+ // cond: data.Op != OpStructMake && data.Op != OpArrayMake1
// result: data
for {
if v_0.Op != OpIMake {
break
}
data := v_0.Args[1]
+ if !(data.Op != OpStructMake && data.Op != OpArrayMake1) {
+ break
+ }
v.copyOf(data)
return true
}
func f4(i any) T {
return i.(T)
}
+
+type Inner struct {
+ a struct{}
+ p *byte
+}
+
+type Outer struct {
+ inner Inner
+}
+
+func f5(o1, o2 Outer, c bool) Outer {
+ var i any
+ if c {
+ i = o1
+ } else {
+ i = o2
+ }
+ return i.(Outer)
+}