diff options
Diffstat (limited to 'gcc/expr-rewriter.c')
-rw-r--r-- | gcc/expr-rewriter.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/gcc/expr-rewriter.c b/gcc/expr-rewriter.c index ef8f93244e6..da4a7fa8320 100644 --- a/gcc/expr-rewriter.c +++ b/gcc/expr-rewriter.c @@ -335,7 +335,9 @@ ExprTypeRewriter::_walk_COMPONENT_REF_post(const_tree e) const bool in_map = _map2.find(f) != _map2.end(); if (!in_map) return; - tree n_f = _map2[f]; + auto p = _map2[f]; + tree n_f = p.first; + bool is_deleted = p.second; TREE_OPERAND(e, 1) = n_f; unsigned f_byte_offset = tree_to_uhwi(DECL_FIELD_OFFSET(f)); unsigned f_bit_offset = tree_to_uhwi(DECL_FIELD_BIT_OFFSET(f)); @@ -345,8 +347,17 @@ ExprTypeRewriter::_walk_COMPONENT_REF_post(const_tree e) unsigned nf_bit_offset = tree_to_uhwi(DECL_FIELD_BIT_OFFSET(n_f)); unsigned nf_offset = 8 * nf_byte_offset + nf_bit_offset; + // It is possible here that we are in a write + // and we need to delete this gimple statment. + // So, how do we know if it is a write? + // Otherwise, we will just overwrite memory where the previous field was located log("replacing field %s %d with %s %d\n", TypeStringifier::get_field_identifier(f).c_str(), f_offset, TypeStringifier::get_field_identifier(n_f).c_str(), nf_offset); + if (!is_deleted) return; + + log("deleting field %s %d\n", TypeStringifier::get_field_identifier(f).c_str(), f_offset); + _delete = true; + } |