proc: fix result type of division of untyped constants (#3794)
The Go specification says that the result of division of untyped constants should be an untyped integer constant if both constants are untyped integers, the go/constant package however does something different by always producing an untyped floating constant. Fixes #3793
This commit is contained in:
parent
c2dc6edcfc
commit
a63cc8a1a3
@ -415,6 +415,7 @@ func main() {
|
|||||||
enum4 := IntConst
|
enum4 := IntConst
|
||||||
enum5 := BoolConst
|
enum5 := BoolConst
|
||||||
enum6 := FloatConst
|
enum6 := FloatConst
|
||||||
|
var zeropoint4 float64 = 0.4
|
||||||
|
|
||||||
var amb1 = 1
|
var amb1 = 1
|
||||||
runtime.Breakpoint()
|
runtime.Breakpoint()
|
||||||
@ -426,5 +427,5 @@ func main() {
|
|||||||
longslice := make([]int, 100, 100)
|
longslice := make([]int, 100, 100)
|
||||||
|
|
||||||
runtime.Breakpoint()
|
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)
|
||||||
}
|
}
|
||||||
|
@ -2295,12 +2295,27 @@ func (scope *EvalScope) evalBinary(binop *evalop.Binary, stack *evalStack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
op := node.Op
|
op := node.Op
|
||||||
if typ != nil && (op == token.QUO) {
|
if op == token.QUO {
|
||||||
_, isint := typ.(*godwarf.IntType)
|
if typ != nil {
|
||||||
_, isuint := typ.(*godwarf.UintType)
|
_, isint := typ.(*godwarf.IntType)
|
||||||
if isint || isuint {
|
_, isuint := typ.(*godwarf.UintType)
|
||||||
// forces integer division if the result type is integer
|
if isint || isuint {
|
||||||
op = token.QUO_ASSIGN
|
// 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,6 +718,8 @@ func getEvalExpressionTestCases() []varTest {
|
|||||||
{"1 + 2i", false, "(1 + 2i)", "(1 + 2i)", "", nil},
|
{"1 + 2i", false, "(1 + 2i)", "(1 + 2i)", "", nil},
|
||||||
{"true", false, "true", "true", "", nil},
|
{"true", false, "true", "true", "", nil},
|
||||||
{"\"test\"", false, "\"test\"", "\"test\"", "", nil},
|
{"\"test\"", false, "\"test\"", "\"test\"", "", nil},
|
||||||
|
{"1/2", false, "0", "0", "", nil},
|
||||||
|
{"zeropoint4 > 1/2", false, "true", "true", "", nil},
|
||||||
|
|
||||||
// binary operators
|
// binary operators
|
||||||
{"i2 + i3", false, "5", "5", "int", nil},
|
{"i2 + i3", false, "5", "5", "int", nil},
|
||||||
|
Loading…
Reference in New Issue
Block a user