diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 29 | ||||
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 |
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. |