aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/ChangeLog8
-rw-r--r--gcc/go/go-gcc.cc29
-rw-r--r--gcc/go/gofrontend/MERGE2
3 files changed, 38 insertions, 1 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 20d5e9d..fef5c44 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,11 @@
+2016-08-08 Ian Lance Taylor <iant@google.com>
+
+ PR go/72814
+ * go-gcc.cc (Gcc_backend::function_type): If the return type is
+ zero bytes, treat the function as returning void.
+ (return_statement): If the return type is zero bytes, don't
+ actually return any values.
+
2016-08-05 Ian Lance Taylor <iant@google.com>
PR go/72812
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 07d9b69..13407ea 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -953,6 +953,14 @@ Gcc_backend::function_type(const Btyped_identifier& receiver,
if (result == error_mark_node)
return this->error_type();
+ // The libffi library can not represent a zero-sized object. To
+ // avoid causing confusion on 32-bit SPARC, we treat a function that
+ // returns a zero-sized value as returning void. That should do no
+ // harm since there is no actual value to be returned. See
+ // https://gcc.gnu.org/PR72814 for details.
+ if (result != void_type_node && int_size_in_bytes(result) == 0)
+ result = void_type_node;
+
tree fntype = build_function_type(result, args);
if (fntype == error_mark_node)
return this->error_type();
@@ -2127,6 +2135,27 @@ Gcc_backend::return_statement(Bfunction* bfunction,
if (result == error_mark_node)
return this->error_statement();
+ // If the result size is zero bytes, we have set the function type
+ // to have a result type of void, so don't return anything.
+ // See the function_type method.
+ if (int_size_in_bytes(TREE_TYPE(result)) == 0)
+ {
+ tree stmt_list = NULL_TREE;
+ for (std::vector<Bexpression*>::const_iterator p = vals.begin();
+ p != vals.end();
+ p++)
+ {
+ tree val = (*p)->get_tree();
+ if (val == error_mark_node)
+ return this->error_statement();
+ append_to_statement_list(val, &stmt_list);
+ }
+ tree ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR,
+ void_type_node, NULL_TREE);
+ append_to_statement_list(ret, &stmt_list);
+ return this->make_statement(stmt_list);
+ }
+
tree ret;
if (vals.empty())
ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index a5d7f51..6ec9f7b 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-eeeeff3e3dd6c09aaefdf13cce99a5beff47a095
+5e4c16d4fea39835e16f17c3d2b2e85f5c81d815
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.