diff --git a/_fixtures/testvariables2.go b/_fixtures/testvariables2.go index 255eee021..6fb3bccc7 100644 --- a/_fixtures/testvariables2.go +++ b/_fixtures/testvariables2.go @@ -415,6 +415,7 @@ func main() { enum4 := IntConst enum5 := BoolConst enum6 := FloatConst + var zeropoint4 float64 = 0.4 var amb1 = 1 runtime.Breakpoint() @@ -426,5 +427,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) + 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) } diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go index cd72e2bb3..d146123c3 100644 --- a/pkg/proc/eval.go +++ b/pkg/proc/eval.go @@ -2295,12 +2295,27 @@ func (scope *EvalScope) evalBinary(binop *evalop.Binary, stack *evalStack) { } op := node.Op - if typ != nil && (op == token.QUO) { - _, isint := typ.(*godwarf.IntType) - _, isuint := typ.(*godwarf.UintType) - if isint || isuint { - // forces integer division if the result type is integer - op = token.QUO_ASSIGN + if op == token.QUO { + if typ != nil { + _, isint := typ.(*godwarf.IntType) + _, isuint := typ.(*godwarf.UintType) + if isint || isuint { + // forces integer division if the result type is integer + op = token.QUO_ASSIGN + } + } else { + if xv.Value != nil && yv.Value != nil && xv.Value.Kind() == constant.Int && yv.Value.Kind() == constant.Int { + // See issue #3793 and the specification at https://go.dev/ref/spec#Constant_expressions + // in particular: + // + // "If the untyped operands of a binary operation (other than a shift) + // are of different kinds, the result is of the operand's kind that + // appears later in this list: integer, rune, floating-point, complex" + // + // However the go/constant package says that to get an integer result + // from a division token.QUO_ASSIGN must be used. + op = token.QUO_ASSIGN + } } } diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go index 7f7a58f21..02c3e628a 100644 --- a/pkg/proc/variables_test.go +++ b/pkg/proc/variables_test.go @@ -718,6 +718,8 @@ func getEvalExpressionTestCases() []varTest { {"1 + 2i", false, "(1 + 2i)", "(1 + 2i)", "", nil}, {"true", false, "true", "true", "", nil}, {"\"test\"", false, "\"test\"", "\"test\"", "", nil}, + {"1/2", false, "0", "0", "", nil}, + {"zeropoint4 > 1/2", false, "true", "true", "", nil}, // binary operators {"i2 + i3", false, "5", "5", "int", nil},