summaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2012-12-17 00:16:47 +0000
committerAlan Modra <amodra@bigpond.net.au>2012-12-17 00:16:47 +0000
commitf32ceb79186bcdce4ebec1d23f93a07a4aab6757 (patch)
treea31da0f0dda6e571ed226d607bc988a8c23bb700 /ld/ldlang.c
parent096928d1633f9604751d0b6ae0cfc9d3474cbe41 (diff)
downloadbinutils-redhat-f32ceb79186bcdce4ebec1d23f93a07a4aab6757.tar.gz
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/ldlang.c')
-rw-r--r--ld/ldlang.c59
1 files changed, 5 insertions, 54 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 750711ceb3..01c12df2c5 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3951,63 +3951,12 @@ print_output_section_statement
output_section_statement);
}
-/* Scan for the use of the destination in the right hand side
- of an expression. In such cases we will not compute the
- correct expression, since the value of DST that is used on
- the right hand side will be its final value, not its value
- just before this expression is evaluated. */
-
-static bfd_boolean
-scan_for_self_assignment (const char * dst, etree_type * rhs)
-{
- if (rhs == NULL || dst == NULL)
- return FALSE;
-
- switch (rhs->type.node_class)
- {
- case etree_binary:
- return (scan_for_self_assignment (dst, rhs->binary.lhs)
- || scan_for_self_assignment (dst, rhs->binary.rhs));
-
- case etree_trinary:
- return (scan_for_self_assignment (dst, rhs->trinary.lhs)
- || scan_for_self_assignment (dst, rhs->trinary.rhs));
-
- case etree_assign:
- case etree_provided:
- case etree_provide:
- if (strcmp (dst, rhs->assign.dst) == 0)
- return TRUE;
- return scan_for_self_assignment (dst, rhs->assign.src);
-
- case etree_unary:
- return scan_for_self_assignment (dst, rhs->unary.child);
-
- case etree_value:
- if (rhs->value.str)
- return strcmp (dst, rhs->value.str) == 0;
- return FALSE;
-
- case etree_name:
- if (rhs->name.name)
- return strcmp (dst, rhs->name.name) == 0;
- return FALSE;
-
- default:
- break;
- }
-
- return FALSE;
-}
-
-
static void
print_assignment (lang_assignment_statement_type *assignment,
lang_output_section_statement_type *output_section)
{
unsigned int i;
bfd_boolean is_dot;
- bfd_boolean computation_is_valid = TRUE;
etree_type *tree;
asection *osec;
@@ -4018,15 +3967,14 @@ print_assignment (lang_assignment_statement_type *assignment,
{
is_dot = FALSE;
tree = assignment->exp->assert_s.child;
- computation_is_valid = TRUE;
}
else
{
const char *dst = assignment->exp->assign.dst;
is_dot = (dst[0] == '.' && dst[1] == 0);
+ expld.assign_name = dst;
tree = assignment->exp->assign.src;
- computation_is_valid = is_dot || !scan_for_self_assignment (dst, tree);
}
osec = output_section->bfd_section;
@@ -4037,7 +3985,9 @@ print_assignment (lang_assignment_statement_type *assignment,
{
bfd_vma value;
- if (computation_is_valid)
+ if (assignment->exp->type.node_class == etree_assert
+ || is_dot
+ || expld.assign_name != NULL)
{
value = expld.result.value;
@@ -4073,6 +4023,7 @@ print_assignment (lang_assignment_statement_type *assignment,
minfo (" ");
#endif
}
+ expld.assign_name = NULL;
minfo (" ");
exp_print_tree (assignment->exp);