aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-08-20 21:15:46 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-08-20 21:15:46 +0000
commit43055d2379cfb1b5b1b09e243a9829e52e12b60a (patch)
tree25ee7c396a4bc315d93ef63cd8092a66275cd5a1
parent5ba5ad304a16644614c3ea143181682a94cb999e (diff)
downloadgcc-43055d2379cfb1b5b1b09e243a9829e52e12b60a.zip
gcc-43055d2379cfb1b5b1b09e243a9829e52e12b60a.tar.gz
gcc-43055d2379cfb1b5b1b09e243a9829e52e12b60a.tar.bz2
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
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc28
-rw-r--r--gcc/go/gofrontend/gogo.h3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug073.go10
-rw-r--r--libgo/runtime/go-runtime-error.c8
6 files changed, 43 insertions, 12 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 94bc2f7..2776fb8 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-a453eebae76296a39a1ded5bd2bffa78bedf40bd
+1846b07fec2b91facc02ea269f7ab250b30f90b4
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 995a18c..aa0fda0 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -6734,11 +6734,10 @@ Binary_expression::do_check_types(Gogo*)
this->report_error(_("shift of non-integer operand"));
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()
- && (right_type->integer_type() == NULL
- || !right_type->integer_type()->is_unsigned()))
- this->report_error(_("shift count not unsigned integer"));
+ && right_type->integer_type() == NULL)
+ this->report_error(_("shift count not integer"));
else
{
Numeric_constant nc;
@@ -6746,7 +6745,7 @@ Binary_expression::do_check_types(Gogo*)
{
mpz_t val;
if (!nc.to_int(&val))
- this->report_error(_("shift count not unsigned integer"));
+ this->report_error(_("shift count not integer"));
else
{
if (mpz_sgn(val) < 0)
@@ -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.
// 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)
{
go_assert(left_type->integer_type() != NULL);
+ go_assert(right_type->integer_type() != NULL);
int bits = left_type->integer_type()->bits();
@@ -6909,6 +6910,23 @@ Binary_expression::do_get_backend(Translate_context* context)
ret, overflow, loc);
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.
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index b3ec629..0abd4b4 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -3745,6 +3745,9 @@ static const int RUNTIME_ERROR_DIVISION_BY_ZERO = 11;
// Go statement with nil function.
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.
extern Gogo* go_get_gogo();
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0512a60..2e361d3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+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>
* gcc.dg/tree-ssa/redundant-assign-zero-1.c: New test.
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug073.go b/gcc/testsuite/go.test/test/fixedbugs/bug073.go
index 49b47ae..f3605b3 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug073.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug073.go
@@ -1,4 +1,4 @@
-// errorcheck
+// compile
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -7,8 +7,8 @@
package main
func main() {
- var s int = 0;
- var x int = 0;
- x = x << s; // ERROR "illegal|inval|shift"
- x = x >> s; // ERROR "illegal|inval|shift"
+ var s int = 0
+ var x int = 0
+ x = x << s // as of 1.13, these are ok
+ x = x >> s // as of 1.13, these are ok
}
diff --git a/libgo/runtime/go-runtime-error.c b/libgo/runtime/go-runtime-error.c
index c9ccf98..8179e68 100644
--- a/libgo/runtime/go-runtime-error.c
+++ b/libgo/runtime/go-runtime-error.c
@@ -55,7 +55,10 @@ enum
DIVISION_BY_ZERO = 11,
/* 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));
@@ -112,6 +115,9 @@ __go_runtime_error (int32 i)
runtime_g()->m->throwing = -1;
runtime_throw ("go of nil func value");
+ case SHIFT_BY_NEGATIVE:
+ runtime_panicstring ("negative shift amount");
+
default:
runtime_panicstring ("unknown runtime error");
}