diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 9f825daa5fe..fbba6626cc4 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -86d223eaccecff72b44cd23a014bc028b658055e +6fa9657df508ff4d7760cf1abfad3611ba808561 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 c228905eb5e..af09138e7ab 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -5270,13 +5270,13 @@ Unary_expression::do_get_backend(Translate_context* context) Bexpression* compare = gogo->backend()->binary_expression(OPERATOR_EQEQ, tbexpr, nil, loc); - Bexpression* crash = - gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, - loc)->get_backend(context); + Expression* crash = Runtime::make_call(Runtime::PANIC_MEM, + loc, 0); + Bexpression* bcrash = crash->get_backend(context); Bfunction* bfn = context->function()->func_value()->get_decl(); bexpr = gogo->backend()->conditional_expression(bfn, btype, compare, - crash, ubexpr, + bcrash, ubexpr, loc); known_valid = true; break; @@ -7060,12 +7060,12 @@ Binary_expression::do_get_backend(Translate_context* context) 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); + Expression* crash = Runtime::make_call(Runtime::PANIC_SHIFT, + loc, 0); + Bexpression* bcrash = crash->get_backend(context); Bfunction* bfn = context->function()->func_value()->get_decl(); ret = gogo->backend()->conditional_expression(bfn, btype, compare, - crash, ret, loc); + bcrash, ret, loc); } } @@ -7081,15 +7081,14 @@ Binary_expression::do_get_backend(Translate_context* context) gogo->backend()->binary_expression(OPERATOR_EQEQ, right, zero_expr, loc); - // __go_runtime_error(RUNTIME_ERROR_DIVISION_BY_ZERO) - int errcode = RUNTIME_ERROR_DIVISION_BY_ZERO; - Bexpression* crash = gogo->runtime_error(errcode, - loc)->get_backend(context); + Expression* crash = Runtime::make_call(Runtime::PANIC_DIVIDE, + loc, 0); + Bexpression* bcrash = crash->get_backend(context); - // right == 0 ? (__go_runtime_error(...), 0) : ret + // right == 0 ? (panicdivide(), 0) : ret Bfunction* bfn = context->function()->func_value()->get_decl(); ret = gogo->backend()->conditional_expression(bfn, btype, - check, crash, + check, bcrash, ret, loc); } @@ -8071,8 +8070,7 @@ Bound_method_expression::do_flatten(Gogo* gogo, Named_object*, if (nil_check != NULL) { - Expression* crash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, - loc); + Expression* crash = Runtime::make_call(Runtime::PANIC_MEM, loc, 0); // Fix the type of the conditional expression by pretending to // evaluate to RET either way through the conditional. crash = Expression::make_compound(crash, ret, loc); @@ -8886,11 +8884,8 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function, Expression* zero = Expression::make_integer_ul(0, int_type, loc); Expression* cond = Expression::make_binary(OPERATOR_LT, len2, zero, loc); - Expression* arg = - Expression::make_integer_ul(RUNTIME_ERROR_MAKE_SLICE_LEN_OUT_OF_BOUNDS, - NULL, loc); - Expression* call = Runtime::make_call(Runtime::RUNTIME_ERROR, - loc, 1, arg); + Expression* call = Runtime::make_call(Runtime::PANIC_MAKE_SLICE_LEN, + loc, 0); cond = Expression::make_conditional(cond, call, zero->copy(), loc); gogo->lower_expression(function, inserter, &cond); gogo->flatten_expression(function, inserter, &cond); @@ -8901,9 +8896,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function, Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc); cond = Expression::make_binary(OPERATOR_LT, cap2, zero->copy(), loc); - arg = Expression::make_integer_ul(RUNTIME_ERROR_MAKE_SLICE_CAP_OUT_OF_BOUNDS, - NULL, loc); - call = Runtime::make_call(Runtime::RUNTIME_ERROR, loc, 1, arg); + call = Runtime::make_call(Runtime::PANIC_MAKE_SLICE_CAP, loc, 0); cond = Expression::make_conditional(cond, call, zero->copy(), loc); gogo->lower_expression(function, inserter, &cond); gogo->flatten_expression(function, inserter, &cond); @@ -14416,8 +14409,8 @@ Interface_field_reference_expression::do_get_backend(Translate_context* context) Expression::make_nil(loc), loc); Bexpression* bnil_check = nil_check->get_backend(context); - Bexpression* bcrash = gogo->runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE, - loc)->get_backend(context); + Expression* crash = Runtime::make_call(Runtime::PANIC_MEM, loc, 0); + Bexpression* bcrash = crash->get_backend(context); Bfunction* bfn = context->function()->func_value()->get_decl(); Bexpression* bcond = diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index b50d8a26f2d..212ef45a29c 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -4887,17 +4887,6 @@ Gogo::build_recover_thunks() this->traverse(&build_recover_thunks); } -// Build a call to the runtime error function. - -Expression* -Gogo::runtime_error(int code, Location location) -{ - Type* int32_type = Type::lookup_integer_type("int32"); - Expression* code_expr = Expression::make_integer_ul(code, int32_type, - location); - return Runtime::make_call(Runtime::RUNTIME_ERROR, location, 1, code_expr); -} - // Look for named types to see whether we need to create an interface // method table. @@ -6346,9 +6335,8 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no) } if (this->asm_name_ == "runtime.gopanic" + || this->asm_name_.compare(0, 13, "runtime.panic") == 0 || this->asm_name_.compare(0, 15, "runtime.goPanic") == 0 - || this->asm_name_ == "__go_runtime_error" - || this->asm_name_ == "runtime.panicdottype" || this->asm_name_ == "runtime.block") flags |= Backend::function_does_not_return; } diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 27d7b4cf2f8..7d83119b698 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -850,10 +850,6 @@ class Gogo void write_globals(); - // Build a call to the runtime error function. - Expression* - runtime_error(int code, Location); - // Build required interface method tables. void build_interface_method_tables(); @@ -3727,57 +3723,6 @@ class Translate_context bool is_const_; }; -// Runtime error codes. These must match the values in -// libgo/runtime/go-runtime-error.c. - -// Slice index out of bounds: negative or larger than the length of -// the slice. -static const int RUNTIME_ERROR_SLICE_INDEX_OUT_OF_BOUNDS = 0; - -// Array index out of bounds. -static const int RUNTIME_ERROR_ARRAY_INDEX_OUT_OF_BOUNDS = 1; - -// String index out of bounds. -static const int RUNTIME_ERROR_STRING_INDEX_OUT_OF_BOUNDS = 2; - -// Slice slice out of bounds: negative or larger than the length of -// the slice or high bound less than low bound. -static const int RUNTIME_ERROR_SLICE_SLICE_OUT_OF_BOUNDS = 3; - -// Array slice out of bounds. -static const int RUNTIME_ERROR_ARRAY_SLICE_OUT_OF_BOUNDS = 4; - -// String slice out of bounds. -static const int RUNTIME_ERROR_STRING_SLICE_OUT_OF_BOUNDS = 5; - -// Dereference of nil pointer. This is used when there is a -// dereference of a pointer to a very large struct or array, to ensure -// that a gigantic array is not used a proxy to access random memory -// locations. -static const int RUNTIME_ERROR_NIL_DEREFERENCE = 6; - -// Slice length out of bounds in make: negative or overflow -// or length greater than capacity. -static const int RUNTIME_ERROR_MAKE_SLICE_LEN_OUT_OF_BOUNDS = 7; - -// Slice capacity out of bounds in make: negative. -static const int RUNTIME_ERROR_MAKE_SLICE_CAP_OUT_OF_BOUNDS = 8; - -// Map capacity out of bounds in make: negative or overflow. -static const int RUNTIME_ERROR_MAKE_MAP_OUT_OF_BOUNDS = 9; - -// Channel capacity out of bounds in make: negative or overflow. -static const int RUNTIME_ERROR_MAKE_CHAN_OUT_OF_BOUNDS = 10; - -// Division by zero. -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/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index d7f5ee2140c..2ef0f94133d 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -243,9 +243,6 @@ DEF_GO_RUNTIME(CHECKDEFER, "runtime.checkdefer", P1(BOOLPTR), R0()) // Run deferred functions. DEF_GO_RUNTIME(DEFERRETURN, "runtime.deferreturn", P1(BOOLPTR), R0()) -// Panic with a runtime error. -DEF_GO_RUNTIME(RUNTIME_ERROR, "__go_runtime_error", P1(INT32), R0()) - // Close. DEF_GO_RUNTIME(CLOSE, "runtime.closechan", P1(CHAN), R0()) @@ -499,6 +496,24 @@ DEF_GO_RUNTIME(ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", P3(POINTER, UINT8, INT32), R1(UINT8)) +// Panic reporting a division by zero. +DEF_GO_RUNTIME(PANIC_DIVIDE, "runtime.panicdivide", P0(), R0()) + +// Panic reporting a shift by negative count. +DEF_GO_RUNTIME(PANIC_SHIFT, "runtime.panicshift", P0(), R0()) + +// Panic reporting a nil dereference. +DEF_GO_RUNTIME(PANIC_MEM, "runtime.panicmem", P0(), R0()) + +// Panic reporting that make's slice len argument is out of range. +DEF_GO_RUNTIME(PANIC_MAKE_SLICE_LEN, "runtime.panicmakeslicelen", P0(), R0()) + +// Panic reporting that make's slice cap argument is out of range. +DEF_GO_RUNTIME(PANIC_MAKE_SLICE_CAP, "runtime.panicmakeslicecap", P0(), R0()) + +// Panic reporting using go with a nil function. +DEF_GO_RUNTIME(PANIC_GO_NIL, "runtime.panicgonil", P0(), R0()) + // Panics reporting an index or slice out of bounds error. DEF_GO_RUNTIME(PANIC_INDEX, "runtime.goPanicIndex", P2(INT, INT), R0()) diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index f52b33d665c..a059ee4d0d9 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -2597,13 +2597,14 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function, // nil` we get a backtrace from the go statement, rather than a // useless backtrace from the brand new goroutine. Expression* param = constructor; - if (!is_constant_function) + if (!is_constant_function && this->classification() == STATEMENT_GO) { fn = Expression::make_temporary_reference(fn_temp, location); Expression* nil = Expression::make_nil(location); Expression* isnil = Expression::make_binary(OPERATOR_EQEQ, fn, nil, location); - Expression* crash = gogo->runtime_error(RUNTIME_ERROR_GO_NIL, location); + Expression* crash = Runtime::make_call(Runtime::PANIC_GO_NIL, + location, 0); crash = Expression::make_conditional(isnil, crash, Expression::make_nil(location), location); diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 1700941d93c..4b2dd58d40a 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -438,7 +438,6 @@ runtime_files = \ runtime/go-now.c \ runtime/go-nosys.c \ runtime/go-reflect-call.c \ - runtime/go-runtime-error.c \ runtime/go-setenv.c \ runtime/go-signal.c \ runtime/go-unsafe-pointer.c \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 0596b5428ef..72c6f9c8886 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -242,13 +242,13 @@ am__objects_4 = runtime/aeshash.lo runtime/go-assert.lo \ runtime/go-matherr.lo runtime/go-memclr.lo \ runtime/go-memequal.lo runtime/go-nanotime.lo \ runtime/go-now.lo runtime/go-nosys.lo \ - runtime/go-reflect-call.lo runtime/go-runtime-error.lo \ - runtime/go-setenv.lo runtime/go-signal.lo \ - runtime/go-unsafe-pointer.lo runtime/go-unsetenv.lo \ - runtime/go-unwind.lo runtime/go-varargs.lo \ - runtime/env_posix.lo runtime/panic.lo runtime/print.lo \ - runtime/proc.lo runtime/runtime_c.lo runtime/stack.lo \ - runtime/yield.lo $(am__objects_2) $(am__objects_3) + runtime/go-reflect-call.lo runtime/go-setenv.lo \ + runtime/go-signal.lo runtime/go-unsafe-pointer.lo \ + runtime/go-unsetenv.lo runtime/go-unwind.lo \ + runtime/go-varargs.lo runtime/env_posix.lo runtime/panic.lo \ + runtime/print.lo runtime/proc.lo runtime/runtime_c.lo \ + runtime/stack.lo runtime/yield.lo $(am__objects_2) \ + $(am__objects_3) am_libgo_llgo_la_OBJECTS = $(am__objects_4) libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -884,7 +884,6 @@ runtime_files = \ runtime/go-now.c \ runtime/go-nosys.c \ runtime/go-reflect-call.c \ - runtime/go-runtime-error.c \ runtime/go-setenv.c \ runtime/go-signal.c \ runtime/go-unsafe-pointer.c \ @@ -1333,8 +1332,6 @@ runtime/go-nosys.lo: runtime/$(am__dirstamp) \ runtime/$(DEPDIR)/$(am__dirstamp) runtime/go-reflect-call.lo: runtime/$(am__dirstamp) \ runtime/$(DEPDIR)/$(am__dirstamp) -runtime/go-runtime-error.lo: runtime/$(am__dirstamp) \ - runtime/$(DEPDIR)/$(am__dirstamp) runtime/go-setenv.lo: runtime/$(am__dirstamp) \ runtime/$(DEPDIR)/$(am__dirstamp) runtime/go-signal.lo: runtime/$(am__dirstamp) \ @@ -1398,7 +1395,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-nosys.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-now.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-reflect-call.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-runtime-error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-setenv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-signal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@runtime/$(DEPDIR)/go-unsafe-pointer.Plo@am__quote@ diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go index 2a11f9329bc..9667181c99f 100644 --- a/libgo/go/runtime/panic.go +++ b/libgo/go/runtime/panic.go @@ -38,6 +38,8 @@ import ( //go:linkname goPanicSlice3BU //go:linkname goPanicSlice3C //go:linkname goPanicSlice3CU +//go:linkname panicshift +//go:linkname panicdivide //go:linkname panicmem // Temporary for C code to call: //go:linkname throw diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index a0147cf954d..a025137f367 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -3157,6 +3157,14 @@ func syscall_runtime_AfterExec() { execLock.unlock() } +// panicgonil is used for gccgo as we need to use a compiler check for +// a nil func, in case we have to build a thunk. +//go:linkname panicgonil +func panicgonil() { + getg().m.throwing = -1 // do not dump full stacks + throw("go of nil func value") +} + // Create a new g running fn passing arg as the single argument. // Put it on the queue of g's waiting to run. // The compiler turns a go statement into a call to this. diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go index c258ebd2bd0..49d5a861054 100644 --- a/libgo/go/runtime/slice.go +++ b/libgo/go/runtime/slice.go @@ -12,6 +12,8 @@ import ( // For gccgo, use go:linkname to export compiler-called functions. // +//go:linkname panicmakeslicelen +//go:linkname panicmakeslicecap //go:linkname makeslice //go:linkname makeslice64 //go:linkname growslice diff --git a/libgo/runtime/go-runtime-error.c b/libgo/runtime/go-runtime-error.c deleted file mode 100644 index 8179e685ef7..00000000000 --- a/libgo/runtime/go-runtime-error.c +++ /dev/null @@ -1,124 +0,0 @@ -/* go-runtime-error.c -- Go runtime error. - - Copyright 2010 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. */ - -#include "runtime.h" - -/* The compiler generates calls to this function. This enum values - are known to the compiler and used by compiled code. Any change - here must be reflected in the compiler. */ - -enum -{ - /* Slice index out of bounds: negative or larger than the length of - the slice. */ - SLICE_INDEX_OUT_OF_BOUNDS = 0, - - /* Array index out of bounds. */ - ARRAY_INDEX_OUT_OF_BOUNDS = 1, - - /* String index out of bounds. */ - STRING_INDEX_OUT_OF_BOUNDS = 2, - - /* Slice slice out of bounds: negative or larger than the length of - the slice or high bound less than low bound. */ - SLICE_SLICE_OUT_OF_BOUNDS = 3, - - /* Array slice out of bounds. */ - ARRAY_SLICE_OUT_OF_BOUNDS = 4, - - /* String slice out of bounds. */ - STRING_SLICE_OUT_OF_BOUNDS = 5, - - /* Dereference of nil pointer. This is used when there is a - dereference of a pointer to a very large struct or array, to - ensure that a gigantic array is not used a proxy to access random - memory locations. */ - NIL_DEREFERENCE = 6, - - /* Slice length out of bounds in make: negative or overflow or length - greater than capacity. */ - MAKE_SLICE_LEN_OUT_OF_BOUNDS = 7, - - /* Slice capacity out of bounds in make: negative. */ - MAKE_SLICE_CAP_OUT_OF_BOUNDS = 8, - - /* Map capacity out of bounds in make: negative or overflow. */ - MAKE_MAP_OUT_OF_BOUNDS = 9, - - /* Channel capacity out of bounds in make: negative or overflow. */ - MAKE_CHAN_OUT_OF_BOUNDS = 10, - - /* Integer division by zero. */ - DIVISION_BY_ZERO = 11, - - /* Go statement with nil function. */ - GO_NIL = 12, - - /* Shift by negative value. */ - SHIFT_BY_NEGATIVE = 13 -}; - -extern void __go_runtime_error (int32) __attribute__ ((noreturn)); - -void -__go_runtime_error (int32 i) -{ - struct funcfileline_return fileline; - bool in_runtime; - - fileline = runtime_funcfileline ((uintptr) runtime_getcallerpc()-1, 0); - in_runtime = (fileline.retfn.len > 0 - && (__builtin_strncmp ((const char *) fileline.retfn.str, - "runtime.", 8) - == 0)); - - switch (i) - { - case SLICE_INDEX_OUT_OF_BOUNDS: - case ARRAY_INDEX_OUT_OF_BOUNDS: - case STRING_INDEX_OUT_OF_BOUNDS: - if (in_runtime) - runtime_throw ("index out of range"); - runtime_panicstring ("index out of range"); - - case SLICE_SLICE_OUT_OF_BOUNDS: - case ARRAY_SLICE_OUT_OF_BOUNDS: - case STRING_SLICE_OUT_OF_BOUNDS: - if (in_runtime) - runtime_throw ("slice bounds out of range"); - runtime_panicstring ("slice bounds out of range"); - - case NIL_DEREFERENCE: - runtime_panicstring ("nil pointer dereference"); - - case MAKE_SLICE_LEN_OUT_OF_BOUNDS: - runtime_panicstring ("make slice len out of range"); - - case MAKE_SLICE_CAP_OUT_OF_BOUNDS: - runtime_panicstring ("make slice cap out of range"); - - case MAKE_MAP_OUT_OF_BOUNDS: - runtime_panicstring ("make map len out of range"); - - case MAKE_CHAN_OUT_OF_BOUNDS: - runtime_panicstring ("make chan len out of range"); - - case DIVISION_BY_ZERO: - runtime_panicstring ("integer divide by zero"); - - case GO_NIL: - /* This one is a throw, rather than a panic. Set throwing to - not dump full stacks. */ - 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"); - } -}