From b950bcf0a99a9ad36b222ccb47f06f39d1c9ddca Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 8 Jul 2025 18:59:40 +0200 Subject: [PATCH] pkg/proc: fix type cast between slices (#4048) Type casts between slice types with the same element type should be allowed. In theory this should be allowed by the check on the real type (which already gets rid of typedefs) but the compiler here actually creates a distinct type for Message instead of having it as a typedef for []uint8. Fixes #4042 --- _fixtures/testvariables2.go | 6 +++++- pkg/proc/eval.go | 4 ++++ pkg/proc/variables_test.go | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index a20d9fb7..f8907166 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -169,6 +169,8 @@ type ThreeInts struct { a, b, c int } +type Message []byte + var _ I = (*W2)(nil) type pptr *pptr @@ -423,6 +425,8 @@ func main() { enum6 := FloatConst var zeropoint4 float64 = 0.4 + var messageVar Message = Message{1, 2, 3, 4, 5} + var amb1 = 1 runtime.Breakpoint() for amb1 := 0; amb1 < 10; amb1++ { @@ -433,5 +437,5 @@ func main() { longslice := make([]int, 100, 100) runtime.Breakpoint() - fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerReceiverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan, longbyteslice, enum1, enum2, enum3, enum4, enum5, enum6, zeropoint4, mlarge) + fmt.Println(i1, i2, i3, p1, pp1, amb1, s1, s3, a0, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, m4, m5, upnil, up1, i4, i5, i6, err1, err2, errnil, iface1, iface2, ifacenil, arr1, parr, cpx1, const1, iface3, iface4, recursive1, recursive1.x, iface5, iface2fn1, iface2fn2, bencharr, benchparr, mapinf, mainMenu, b, b2, sd, anonstruct1, anonstruct2, anoniface1, anonfunc, mapanonstruct1, ifacearr, efacearr, ni8, ni16, ni32, ni64, pinf, ninf, nan, zsvmap, zsslice, zsvar, tm, rettm, errtypednil, emptyslice, emptymap, byteslice, bytestypeslice, runeslice, bytearray, bytetypearray, runearray, longstr, nilstruct, as2, as2.NonPointerReceiverMethod, s4, iface2map, issue1578, ll, unread, w2, w3, w4, w5, longarr, longslice, val, m6, m7, cl, tim1, tim2, typedstringvar, namedA1, namedA2, astructName1(namedA2), badslice, tim3, int3chan, longbyteslice, enum1, enum2, enum3, enum4, enum5, enum6, zeropoint4, mlarge, messageVar) } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index 8f7337e2..346741fe 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -1820,6 +1820,10 @@ func typeCastCompatibleTypes(typ1, typ2 godwarf.Type) bool { } return true } + case *godwarf.SliceType: + if ttyp2, ok := typ2.(*godwarf.SliceType); ok { + return ttyp1.ElemType.String() == ttyp2.ElemType.String() + } case *godwarf.ComplexType: if _, ok := typ2.(*godwarf.ComplexType); ok { // size and alignment already checked above diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index ab83ac3b..513047d5 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -836,6 +836,7 @@ func getEvalExpressionTestCases() []varTest { {"int8(i6)", false, "12", "12", "int8", nil}, {"string(byteslice[0])", false, `"t"`, `"t"`, "string", nil}, {"string(runeslice[0])", false, `"t"`, `"t"`, "string", nil}, + {"[]uint8(messageVar)", false, `[]uint8 len: 5, cap: 5, [1,2,3,4,5]`, `[]uint8 len: 5, cap: 5, [...]`, "[]uint8", nil}, // misc {"i1", true, "1", "1", "int", nil},