diff options
author | Alan Modra <amodra@gmail.com> | 2012-12-17 00:16:49 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2012-12-17 00:16:49 +0000 |
commit | 4194268f43623a5f893b9a92b0456d3cb43ab915 (patch) | |
tree | d3c470f3494ea65b44f5ca7d69aa1640c93ace2e /ld/ldexp.c | |
parent | faa7371af5014736b1c67cc7bd0cbcca3353a953 (diff) | |
download | gdb-4194268f43623a5f893b9a92b0456d3cb43ab915.zip gdb-4194268f43623a5f893b9a92b0456d3cb43ab915.tar.gz gdb-4194268f43623a5f893b9a92b0456d3cb43ab915.tar.bz2 |
PR ld/14962
* ldexp.h (struct ldexp_control): Add "assign_name".
* ldexp.c (fold_name <NAME>): Compare and clear assign_name on match.
(exp_fold_tree_1): Remove existing code testing for self assignment.
Instead set and test expld.assign_name.
* ldlang.c (scan_for_self_assignment): Delete.
(print_assignment): Instead set and test expld.assign_name.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r-- | ld/ldexp.c | 37 |
1 files changed, 17 insertions, 20 deletions
@@ -572,6 +572,9 @@ fold_name (etree_type *tree) break; case NAME: + if (expld.assign_name != NULL + && strcmp (expld.assign_name, tree->name.name) == 0) + expld.assign_name = NULL; if (expld.phase == lang_first_phase_enum) ; else if (tree->name.name[0] == '.' && tree->name.name[1] == 0) @@ -852,8 +855,6 @@ exp_fold_tree_1 (etree_type *tree) } else { - etree_type *name; - struct bfd_link_hash_entry *h = NULL; if (tree->type.node_class == etree_provide) @@ -871,25 +872,20 @@ exp_fold_tree_1 (etree_type *tree) } } - name = tree->assign.src; - if (name->type.node_class == etree_trinary) - { - exp_fold_tree_1 (name->trinary.cond); - if (expld.result.valid_p) - name = (expld.result.value - ? name->trinary.lhs : name->trinary.rhs); - } - - if (name->type.node_class == etree_name - && name->type.node_code == NAME - && strcmp (tree->assign.dst, name->name.name) == 0) - /* Leave it alone. Do not replace a symbol with its own - output address, in case there is another section sizing - pass. Folding does not preserve input sections. */ - break; - + expld.assign_name = tree->assign.dst; exp_fold_tree_1 (tree->assign.src); - if (expld.result.valid_p + /* expld.assign_name remaining equal to tree->assign.dst + below indicates the evaluation of tree->assign.src did + not use the value of tree->assign.dst. We don't allow + self assignment until the final phase for two reasons: + 1) Expressions are evaluated multiple times. With + relaxation, the number of times may vary. + 2) Section relative symbol values cannot be correctly + converted to absolute values, as is required by many + expressions, until final section sizing is complete. */ + if ((expld.result.valid_p + && (expld.phase == lang_final_phase_enum + || expld.assign_name != NULL)) || (expld.phase <= lang_mark_phase_enum && tree->type.node_class == etree_assign && tree->assign.defsym)) @@ -937,6 +933,7 @@ exp_fold_tree_1 (etree_type *tree) && h->type == bfd_link_hash_new) h->type = bfd_link_hash_undefined; } + expld.assign_name = NULL; } break; |