From: Alberto Donizetti Date: Sat, 13 May 2017 17:11:44 +0000 (+0200) Subject: go/types: don't panic in complex division X-Git-Tag: go1.9beta1~110 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=3c745d750e8342b1dd4144a83488b559efb8b271;p=gostls13.git go/types: don't panic in complex division Make sure that in complex division we reject divisors that would underflow to zero when using the textbook complex-division method we currently use. This change does for go/types what golang.org/cl/42650 did for gc. Fixes #20227 Change-Id: Iaa784ac5e60141f51c501eb0e3ce0e9c1c2993d0 Reviewed-on: https://go-review.googlesource.com/44590 Run-TryBot: Alberto Donizetti TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 7de13f5be6..7f54b09071 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -800,10 +800,24 @@ func (check *Checker) binary(x *operand, e *ast.BinaryExpr, lhs, rhs ast.Expr, o return } - if (op == token.QUO || op == token.REM) && (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 { - check.invalidOp(y.pos(), "division by zero") - x.mode = invalid - return + if op == token.QUO || op == token.REM { + // check for zero divisor + if (x.mode == constant_ || isInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 { + check.invalidOp(y.pos(), "division by zero") + x.mode = invalid + return + } + + // check for divisor underflow in complex division (see issue 20227) + if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) { + re, im := constant.Real(y.val), constant.Imag(y.val) + re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im) + if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 { + check.invalidOp(y.pos(), "division by zero") + x.mode = invalid + return + } + } } if x.mode == constant_ && y.mode == constant_ { diff --git a/src/go/types/stdlib_test.go b/src/go/types/stdlib_test.go index b9a6681e66..345c7897f3 100644 --- a/src/go/types/stdlib_test.go +++ b/src/go/types/stdlib_test.go @@ -171,7 +171,6 @@ func TestStdFixed(t *testing.T) { "issue18459.go", // go/types doesn't check validity of //go:xxx directives "issue18882.go", // go/types doesn't check validity of //go:xxx directives "issue20232.go", // go/types handles larger constants than gc - "issue20227.go", // go/types does not handle this yet "issue20529.go", // go/types does not have constraints on stack size ) }