-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/compile: diagnose constant division by complex zero
When casting an ideal to complex{64,128}, for example during the evaluation of var a = complex64(0) / 1e-50 we want the compiler to report a division-by-zero error if a divisor would be zero after the cast. We already do this for floats; for example var b = float32(0) / 1e-50 generates a 'division by zero' error at compile time (because float32(1e-50) is zero, and the cast is done before performing the division). There's no such check in the path for complex{64,128} expressions, and no cast is performed before the division in the evaluation of var a = complex64(0) / 1e-50 which compiles just fine. This patch changes the convlit1 function so that complex ideals components (real and imag) are correctly truncated to float{32,64} when doing an ideal -> complex{64, 128} cast. Fixes golang#11674 Change-Id: Ic5f8ee3c8cfe4c3bb0621481792c96511723d151 Reviewed-on: https://go-review.googlesource.com/37891 Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
- Loading branch information
Showing
4 changed files
with
149 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright 2017 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package gc | ||
|
||
import "testing" | ||
|
||
var f52want float64 = 1.0 / (1 << 52) | ||
var f53want float64 = 1.0 / (1 << 53) | ||
|
||
func TestTruncFlt(t *testing.T) { | ||
const f52 = 1 + 1.0/(1<<52) | ||
const f53 = 1 + 1.0/(1<<53) | ||
|
||
if got := f52 - 1; got != f52want { | ||
t.Errorf("f52-1 = %g, want %g", got, f52want) | ||
} | ||
if got := float64(f52) - 1; got != f52want { | ||
t.Errorf("float64(f52)-1 = %g, want %g", got, f52want) | ||
} | ||
if got := f53 - 1; got != f53want { | ||
t.Errorf("f53-1 = %g, want %g", got, f53want) | ||
} | ||
if got := float64(f53) - 1; got != 0 { | ||
t.Errorf("float64(f53)-1 = %g, want 0", got) | ||
} | ||
} | ||
|
||
func TestTruncCmplx(t *testing.T) { | ||
const r52 = complex(1+1.0/(1<<52), 0) | ||
const r53 = complex(1+1.0/(1<<53), 0) | ||
|
||
if got := real(r52 - 1); got != f52want { | ||
t.Errorf("real(r52-1) = %g, want %g", got, f52want) | ||
} | ||
if got := real(complex128(r52) - 1); got != f52want { | ||
t.Errorf("real(complex128(r52)-1) = %g, want %g", got, f52want) | ||
} | ||
if got := real(r53 - 1); got != f53want { | ||
t.Errorf("real(r53-1) = %g, want %g", got, f53want) | ||
} | ||
if got := real(complex128(r53) - 1); got != 0 { | ||
t.Errorf("real(complex128(r53)-1) = %g, want 0", got) | ||
} | ||
|
||
const i52 = complex(0, 1+1.0/(1<<52)) | ||
const i53 = complex(0, 1+1.0/(1<<53)) | ||
|
||
if got := imag(i52 - 1i); got != f52want { | ||
t.Errorf("imag(i52-1i) = %g, want %g", got, f52want) | ||
} | ||
if got := imag(complex128(i52) - 1i); got != f52want { | ||
t.Errorf("imag(complex128(i52)-1i) = %g, want %g", got, f52want) | ||
} | ||
if got := imag(i53 - 1i); got != f53want { | ||
t.Errorf("imag(i53-1i) = %g, want %g", got, f53want) | ||
} | ||
if got := imag(complex128(i53) - 1i); got != 0 { | ||
t.Errorf("imag(complex128(i53)-1i) = %g, want 0", got) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// errorcheck | ||
|
||
// Copyright 2017 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Issue 11674: cmd/compile: does not diagnose constant division by | ||
// zero | ||
|
||
package p | ||
|
||
const x complex64 = 0 | ||
const y complex128 = 0 | ||
|
||
var _ = x / 1e-20 | ||
var _ = x / 1e-50 // ERROR "complex division by zero" | ||
var _ = x / 1e-1000 // ERROR "complex division by zero" | ||
var _ = x / 1e-20i | ||
var _ = x / 1e-50i // ERROR "complex division by zero" | ||
var _ = x / 1e-1000i // ERROR "complex division by zero" | ||
|
||
var _ = x / 1e-45 // smallest positive float32 | ||
|
||
var _ = x / (1e-20 + 1e-20i) | ||
var _ = x / (1e-50 + 1e-20i) | ||
var _ = x / (1e-20 + 1e-50i) | ||
var _ = x / (1e-50 + 1e-50i) // ERROR "complex division by zero" | ||
var _ = x / (1e-1000 + 1e-1000i) // ERROR "complex division by zero" | ||
|
||
var _ = y / 1e-50 | ||
var _ = y / 1e-1000 // ERROR "complex division by zero" | ||
var _ = y / 1e-50i | ||
var _ = y / 1e-1000i // ERROR "complex division by zero" | ||
|
||
var _ = y / 5e-324 // smallest positive float64 | ||
|
||
var _ = y / (1e-50 + 1e-50) | ||
var _ = y / (1e-1000 + 1e-50i) | ||
var _ = y / (1e-50 + 1e-1000i) | ||
var _ = y / (1e-1000 + 1e-1000i) // ERROR "complex division by zero" |