aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc71
-rw-r--r--gcc/go/gofrontend/runtime.def31
3 files changed, 61 insertions, 43 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e22f79e..c987dc9 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-f3658aea2493c7f1c4a72502f9e7da562c7764c4
+ecf9b645cefc5c3b4e6339adeb452b2d8642cf3e
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 36000ea..4f8a519 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -7018,6 +7018,26 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function,
}
}
break;
+
+ case BUILTIN_PRINT:
+ case BUILTIN_PRINTLN:
+ // Force all the arguments into temporary variables, so that we
+ // don't try to evaluate something while holding the print lock.
+ if (this->args() == NULL)
+ break;
+ for (Expression_list::iterator pa = this->args()->begin();
+ pa != this->args()->end();
+ ++pa)
+ {
+ if (!(*pa)->is_variable())
+ {
+ Temporary_statement* temp =
+ Statement::make_temporary(NULL, *pa, loc);
+ inserter->insert(temp);
+ *pa = Expression::make_temporary_reference(temp, loc);
+ }
+ }
+ break;
}
return this;
@@ -8336,7 +8356,9 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
case BUILTIN_PRINTLN:
{
const bool is_ln = this->code_ == BUILTIN_PRINTLN;
- Expression* print_stmts = NULL;
+
+ Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK,
+ location, 0);
const Expression_list* call_args = this->args();
if (call_args != NULL)
@@ -8348,8 +8370,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
if (is_ln && p != call_args->begin())
{
Expression* print_space =
- Runtime::make_call(Runtime::PRINT_SPACE,
- this->location(), 0);
+ Runtime::make_call(Runtime::PRINTSP, location, 0);
print_stmts =
Expression::make_compound(print_stmts, print_space,
@@ -8360,51 +8381,51 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
Type* type = arg->type();
Runtime::Function code;
if (type->is_string_type())
- code = Runtime::PRINT_STRING;
+ code = Runtime::PRINTSTRING;
else if (type->integer_type() != NULL
&& type->integer_type()->is_unsigned())
{
Type* itype = Type::lookup_integer_type("uint64");
arg = Expression::make_cast(itype, arg, location);
- code = Runtime::PRINT_UINT64;
+ code = Runtime::PRINTUINT;
}
else if (type->integer_type() != NULL)
{
Type* itype = Type::lookup_integer_type("int64");
arg = Expression::make_cast(itype, arg, location);
- code = Runtime::PRINT_INT64;
+ code = Runtime::PRINTINT;
}
else if (type->float_type() != NULL)
{
Type* dtype = Type::lookup_float_type("float64");
arg = Expression::make_cast(dtype, arg, location);
- code = Runtime::PRINT_DOUBLE;
+ code = Runtime::PRINTFLOAT;
}
else if (type->complex_type() != NULL)
{
Type* ctype = Type::lookup_complex_type("complex128");
arg = Expression::make_cast(ctype, arg, location);
- code = Runtime::PRINT_COMPLEX;
+ code = Runtime::PRINTCOMPLEX;
}
else if (type->is_boolean_type())
- code = Runtime::PRINT_BOOL;
+ code = Runtime::PRINTBOOL;
else if (type->points_to() != NULL
|| type->channel_type() != NULL
|| type->map_type() != NULL
|| type->function_type() != NULL)
{
arg = Expression::make_cast(type, arg, location);
- code = Runtime::PRINT_POINTER;
+ code = Runtime::PRINTPOINTER;
}
else if (type->interface_type() != NULL)
{
if (type->interface_type()->is_empty())
- code = Runtime::PRINT_EMPTY_INTERFACE;
+ code = Runtime::PRINTEFACE;
else
- code = Runtime::PRINT_INTERFACE;
+ code = Runtime::PRINTIFACE;
}
else if (type->is_slice_type())
- code = Runtime::PRINT_SLICE;
+ code = Runtime::PRINTSLICE;
else
{
go_assert(saw_errors());
@@ -8412,30 +8433,22 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
}
Expression* call = Runtime::make_call(code, location, 1, arg);
- if (print_stmts == NULL)
- print_stmts = call;
- else
- print_stmts = Expression::make_compound(print_stmts, call,
- location);
+ print_stmts = Expression::make_compound(print_stmts, call,
+ location);
}
}
if (is_ln)
{
Expression* print_nl =
- Runtime::make_call(Runtime::PRINT_NL, location, 0);
- if (print_stmts == NULL)
- print_stmts = print_nl;
- else
- print_stmts = Expression::make_compound(print_stmts, print_nl,
- location);
+ Runtime::make_call(Runtime::PRINTNL, location, 0);
+ print_stmts = Expression::make_compound(print_stmts, print_nl,
+ location);
}
- // There aren't any arguments to the print builtin. The compiler
- // issues a warning for this so we should avoid getting the backend
- // representation for this call. Instead, perform a no-op.
- if (print_stmts == NULL)
- return context->backend()->boolean_constant_expression(false);
+ Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK,
+ location, 0);
+ print_stmts = Expression::make_compound(print_stmts, unlock, location);
return print_stmts->get_backend(context);
}
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index 168f473..e7edfa6 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -299,42 +299,47 @@ DEF_GO_RUNTIME(INTERFACE_EMPTY_COMPARE, "__go_interface_empty_compare",
P2(IFACE, EFACE), R1(INT))
+// Lock the printer (for print/println).
+DEF_GO_RUNTIME(PRINTLOCK, "runtime.printlock", P0(), R0())
+
+// Unlock the printer (for print/println).
+DEF_GO_RUNTIME(PRINTUNLOCK, "runtime.printunlock", P0(), R0())
+
// Print a string (for print/println).
-DEF_GO_RUNTIME(PRINT_STRING, "__go_print_string", P1(STRING), R0())
+DEF_GO_RUNTIME(PRINTSTRING, "runtime.printstring", P1(STRING), R0())
// Print a uint64 (for print/println).
-DEF_GO_RUNTIME(PRINT_UINT64, "__go_print_uint64", P1(UINT64), R0())
+DEF_GO_RUNTIME(PRINTUINT, "runtime.printuint", P1(UINT64), R0())
// Print a int64 (for print/println).
-DEF_GO_RUNTIME(PRINT_INT64, "__go_print_int64", P1(INT64), R0())
+DEF_GO_RUNTIME(PRINTINT, "runtime.printint", P1(INT64), R0())
// Print a float64 (for print/println).
-DEF_GO_RUNTIME(PRINT_DOUBLE, "__go_print_double", P1(FLOAT64), R0())
+DEF_GO_RUNTIME(PRINTFLOAT, "runtime.printfloat", P1(FLOAT64), R0())
// Print a complex128 (for print/println).
-DEF_GO_RUNTIME(PRINT_COMPLEX, "__go_print_complex", P1(COMPLEX128), R0())
+DEF_GO_RUNTIME(PRINTCOMPLEX, "runtime.printcomplex", P1(COMPLEX128), R0())
// Print a bool (for print/println).
-DEF_GO_RUNTIME(PRINT_BOOL, "__go_print_bool", P1(BOOL), R0())
+DEF_GO_RUNTIME(PRINTBOOL, "runtime.printbool", P1(BOOL), R0())
// Print a pointer/map/channel/function (for print/println).
-DEF_GO_RUNTIME(PRINT_POINTER, "__go_print_pointer", P1(POINTER), R0())
+DEF_GO_RUNTIME(PRINTPOINTER, "runtime.printpointer", P1(POINTER), R0())
// Print an empty interface (for print/println).
-DEF_GO_RUNTIME(PRINT_EMPTY_INTERFACE, "__go_print_empty_interface",
- P1(EFACE), R0())
+DEF_GO_RUNTIME(PRINTEFACE, "runtime.printeface", P1(EFACE), R0())
// Print a non-empty interface (for print/println).
-DEF_GO_RUNTIME(PRINT_INTERFACE, "__go_print_interface", P1(IFACE), R0())
+DEF_GO_RUNTIME(PRINTIFACE, "runtime.printiface", P1(IFACE), R0())
// Print a slice (for print/println).
-DEF_GO_RUNTIME(PRINT_SLICE, "__go_print_slice", P1(SLICE), R0())
+DEF_GO_RUNTIME(PRINTSLICE, "runtime.printslice", P1(SLICE), R0())
// Print a space (for println).
-DEF_GO_RUNTIME(PRINT_SPACE, "__go_print_space", P0(), R0())
+DEF_GO_RUNTIME(PRINTSP, "runtime.printsp", P0(), R0())
// Print a newline (for println).
-DEF_GO_RUNTIME(PRINT_NL, "__go_print_nl", P0(), R0())
+DEF_GO_RUNTIME(PRINTNL, "runtime.printnl", P0(), R0())
// Used for field tracking for data analysis.