Commit 43055d23 by Ian Lance Taylor Committed by Ian Lance Taylor

compiler, runtime: implement shifts by signed amounts

    
    Shifting by signed types is a new language feature in Go 1.13.
    
    This requires a patch to the testsuite.
    
    Updates golang/go#19113
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/190977

	* go.test/test/fixedbugs/bug073.go: Update for language changes.

From-SVN: r274755
parent 5ba5ad30
a453eebae76296a39a1ded5bd2bffa78bedf40bd 1846b07fec2b91facc02ea269f7ab250b30f90b4
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -6734,11 +6734,10 @@ Binary_expression::do_check_types(Gogo*) ...@@ -6734,11 +6734,10 @@ Binary_expression::do_check_types(Gogo*)
this->report_error(_("shift of non-integer operand")); this->report_error(_("shift of non-integer operand"));
if (right_type->is_string_type()) if (right_type->is_string_type())
this->report_error(_("shift count not unsigned integer")); this->report_error(_("shift count not integer"));
else if (!right_type->is_abstract() else if (!right_type->is_abstract()
&& (right_type->integer_type() == NULL && right_type->integer_type() == NULL)
|| !right_type->integer_type()->is_unsigned())) this->report_error(_("shift count not integer"));
this->report_error(_("shift count not unsigned integer"));
else else
{ {
Numeric_constant nc; Numeric_constant nc;
...@@ -6746,7 +6745,7 @@ Binary_expression::do_check_types(Gogo*) ...@@ -6746,7 +6745,7 @@ Binary_expression::do_check_types(Gogo*)
{ {
mpz_t val; mpz_t val;
if (!nc.to_int(&val)) if (!nc.to_int(&val))
this->report_error(_("shift count not unsigned integer")); this->report_error(_("shift count not integer"));
else else
{ {
if (mpz_sgn(val) < 0) if (mpz_sgn(val) < 0)
...@@ -6865,9 +6864,11 @@ Binary_expression::do_get_backend(Translate_context* context) ...@@ -6865,9 +6864,11 @@ Binary_expression::do_get_backend(Translate_context* context)
// In Go, a shift larger than the size of the type is well-defined. // In Go, a shift larger than the size of the type is well-defined.
// This is not true in C, so we need to insert a conditional. // This is not true in C, so we need to insert a conditional.
// We also need to check for a negative shift count.
if (is_shift_op) if (is_shift_op)
{ {
go_assert(left_type->integer_type() != NULL); go_assert(left_type->integer_type() != NULL);
go_assert(right_type->integer_type() != NULL);
int bits = left_type->integer_type()->bits(); int bits = left_type->integer_type()->bits();
...@@ -6909,6 +6910,23 @@ Binary_expression::do_get_backend(Translate_context* context) ...@@ -6909,6 +6910,23 @@ Binary_expression::do_get_backend(Translate_context* context)
ret, overflow, loc); ret, overflow, loc);
mpz_clear(bitsval); mpz_clear(bitsval);
} }
if (!right_type->integer_type()->is_unsigned()
&& (!this->right_->numeric_constant_value(&nc)
|| nc.to_unsigned_long(&ul) != Numeric_constant::NC_UL_VALID))
{
Bexpression* zero_expr =
gogo->backend()->integer_constant_expression(right_btype, zero);
Bexpression* compare =
gogo->backend()->binary_expression(OPERATOR_LT, right, zero_expr,
loc);
const int errcode = RUNTIME_ERROR_SHIFT_BY_NEGATIVE;
Bexpression* crash =
gogo->runtime_error(errcode, loc)->get_backend(context);
Bfunction* bfn = context->function()->func_value()->get_decl();
ret = gogo->backend()->conditional_expression(bfn, btype, compare,
crash, ret, loc);
}
} }
// Add checks for division by zero and division overflow as needed. // Add checks for division by zero and division overflow as needed.
......
...@@ -3745,6 +3745,9 @@ static const int RUNTIME_ERROR_DIVISION_BY_ZERO = 11; ...@@ -3745,6 +3745,9 @@ static const int RUNTIME_ERROR_DIVISION_BY_ZERO = 11;
// Go statement with nil function. // Go statement with nil function.
static const int RUNTIME_ERROR_GO_NIL = 12; static const int RUNTIME_ERROR_GO_NIL = 12;
// Shift by negative value.
static const int RUNTIME_ERROR_SHIFT_BY_NEGATIVE = 13;
// This is used by some of the langhooks. // This is used by some of the langhooks.
extern Gogo* go_get_gogo(); extern Gogo* go_get_gogo();
......
2019-08-20 Ian Lance Taylor <iant@golang.org>
* go.test/test/fixedbugs/bug073.go: Update for language changes.
2019-08-20 Matthew Beliveau <mbelivea@redhat.com> 2019-08-20 Matthew Beliveau <mbelivea@redhat.com>
* gcc.dg/tree-ssa/redundant-assign-zero-1.c: New test. * gcc.dg/tree-ssa/redundant-assign-zero-1.c: New test.
......
// errorcheck // compile
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
package main package main
func main() { func main() {
var s int = 0; var s int = 0
var x int = 0; var x int = 0
x = x << s; // ERROR "illegal|inval|shift" x = x << s // as of 1.13, these are ok
x = x >> s; // ERROR "illegal|inval|shift" x = x >> s // as of 1.13, these are ok
} }
...@@ -55,7 +55,10 @@ enum ...@@ -55,7 +55,10 @@ enum
DIVISION_BY_ZERO = 11, DIVISION_BY_ZERO = 11,
/* Go statement with nil function. */ /* Go statement with nil function. */
GO_NIL = 12 GO_NIL = 12,
/* Shift by negative value. */
SHIFT_BY_NEGATIVE = 13
}; };
extern void __go_runtime_error (int32) __attribute__ ((noreturn)); extern void __go_runtime_error (int32) __attribute__ ((noreturn));
...@@ -112,6 +115,9 @@ __go_runtime_error (int32 i) ...@@ -112,6 +115,9 @@ __go_runtime_error (int32 i)
runtime_g()->m->throwing = -1; runtime_g()->m->throwing = -1;
runtime_throw ("go of nil func value"); runtime_throw ("go of nil func value");
case SHIFT_BY_NEGATIVE:
runtime_panicstring ("negative shift amount");
default: default:
runtime_panicstring ("unknown runtime error"); runtime_panicstring ("unknown runtime error");
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment