diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-08-31 03:07:48 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-08-31 03:07:48 +0000 |
commit | 3ba155dd1921b55f04866b35a2e054e092670cd6 (patch) | |
tree | d363ebe768fa8e1493850b82f82b2d9f857a1e2a /gcc | |
parent | c70ff9f9be0c7360a37519ec68ac4dd41e8d0a3c (diff) | |
download | gcc-3ba155dd1921b55f04866b35a2e054e092670cd6.zip gcc-3ba155dd1921b55f04866b35a2e054e092670cd6.tar.gz gcc-3ba155dd1921b55f04866b35a2e054e092670cd6.tar.bz2 |
compiler: check for notinheap struct at each struct field
When generating write barriers, we were only checking for a notinheap
struct at the outermost struct. That mishandled the case of setting a
pointer to a notinheap struct as a field of another struct that is not
notinheap. This caused an invalid write barrier error when building
the 1.13 version of the runtime.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/192279
From-SVN: r275240
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/wb.cc | 50 |
2 files changed, 26 insertions, 26 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 025e66e..0add2f0 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -289d94b9e6303ec74649d1f08d418300f2b4d0fd +3b8a505824abb2a69f4c04c555a4ba29ab8b102b 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/wb.cc b/gcc/go/gofrontend/wb.cc index 41d8f94..1eadb3e 100644 --- a/gcc/go/gofrontend/wb.cc +++ b/gcc/go/gofrontend/wb.cc @@ -733,6 +733,31 @@ Gogo::assign_needs_write_barrier( && !lhs->type()->points_to()->in_heap()) return false; + // For a struct assignment, we don't need a write barrier if all + // the field types can not be in the heap. + Struct_type* st = lhs->type()->struct_type(); + if (st != NULL) + { + bool in_heap = false; + const Struct_field_list* fields = st->fields(); + for (Struct_field_list::const_iterator p = fields->begin(); + p != fields->end(); + p++) + { + Type* ft = p->type(); + if (!ft->has_pointer()) + continue; + if (!ft->in_heap()) + continue; + if (ft->points_to() != NULL && !ft->points_to()->in_heap()) + continue; + in_heap = true; + break; + } + if (!in_heap) + return false; + } + Field_reference_expression* fre = lhs->field_reference_expression(); if (fre != NULL) { @@ -788,31 +813,6 @@ Gogo::assign_needs_write_barrier( && this->is_nonwb_pointer(ue->operand(), nonwb_pointers)) return false; - // For a struct assignment, we don't need a write barrier if all the - // pointer types can not be in the heap. - Struct_type* st = lhs->type()->struct_type(); - if (st != NULL) - { - bool in_heap = false; - const Struct_field_list* fields = st->fields(); - for (Struct_field_list::const_iterator p = fields->begin(); - p != fields->end(); - p++) - { - Type* ft = p->type(); - if (!ft->has_pointer()) - continue; - if (!ft->in_heap()) - continue; - if (ft->points_to() != NULL && !ft->points_to()->in_heap()) - continue; - in_heap = true; - break; - } - if (!in_heap) - return false; - } - // Write barrier needed in other cases. return true; } |