From 79513dc0b2d980bfd1b109d0d502de487c02b894 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 20 Aug 2021 11:33:29 -0700 Subject: [PATCH] compiler: don't pad zero-sized trailing field in results struct Nothing can take the address of that field anyhow. Fixes PR go/101994 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/343873 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/types.cc | 3 ++- gcc/go/gofrontend/types.h | 17 ++++++++++++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index ff41af7..f481681 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -21b30eddc59d92a07264c3b21eb032d6c303d16f +c11d9f8275f2bbe9b05cdd815c79ac331f78e15c 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/types.cc b/gcc/go/gofrontend/types.cc index e76600d..cd69250 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -5050,6 +5050,7 @@ Function_type::get_backend_fntype(Gogo* gogo) Struct_type* st = Type::make_struct_type(sfl, this->location()); st->set_is_struct_incomparable(); + st->set_is_results_struct(); ins.first->second = st->get_backend(gogo); } bresult_struct = ins.first->second; @@ -6458,7 +6459,7 @@ get_backend_struct_fields(Gogo* gogo, Struct_type* type, bool use_placeholder, saw_nonzero = true; } go_assert(i == fields->size()); - if (saw_nonzero && lastsize == 0) + if (saw_nonzero && lastsize == 0 && !type->is_results_struct()) { // For nonzero-sized structs which end in a zero-sized thing, we add // an extra byte of padding to the type. This padding ensures that diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h index ca1ab49..0c51806 100644 --- a/gcc/go/gofrontend/types.h +++ b/gcc/go/gofrontend/types.h @@ -2501,7 +2501,8 @@ class Struct_type : public Type Struct_type(Struct_field_list* fields, Location location) : Type(TYPE_STRUCT), fields_(fields), location_(location), all_methods_(NULL), - is_struct_incomparable_(false), has_padding_(false) + is_struct_incomparable_(false), has_padding_(false), + is_results_struct_(false) { } // Return the field NAME. This only looks at local fields, not at @@ -2632,6 +2633,17 @@ class Struct_type : public Type set_has_padding() { this->has_padding_ = true; } + // Return whether this is a results struct created to hold the + // results of a function that returns multiple results. + bool + is_results_struct() const + { return this->is_results_struct_; } + + // Record that this is a results struct. + void + set_is_results_struct() + { this->is_results_struct_ = true; } + // Write the hash function for this type. void write_hash_function(Gogo*, Function_type*); @@ -2742,6 +2754,9 @@ class Struct_type : public Type // True if this struct's backend type has padding, due to trailing // zero-sized field. bool has_padding_; + // True if this is a results struct created to hold the results of a + // function that returns multiple results. + bool is_results_struct_; }; // The type of an array. -- 2.7.4