aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-08-31 03:07:48 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-08-31 03:07:48 +0000
commit3ba155dd1921b55f04866b35a2e054e092670cd6 (patch)
treed363ebe768fa8e1493850b82f82b2d9f857a1e2a /gcc
parentc70ff9f9be0c7360a37519ec68ac4dd41e8d0a3c (diff)
downloadgcc-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/MERGE2
-rw-r--r--gcc/go/gofrontend/wb.cc50
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;
}