summaryrefslogtreecommitdiff
path: root/ld/ldexp.c
diff options
context:
space:
mode:
authorSimon Dardis <Simon.Dardis@imgtec.com>2015-10-15 13:28:27 +0100
committerNick Clifton <nickc@redhat.com>2015-10-15 13:28:27 +0100
commit1fb80d6d50f3c0adc46ff584af26583b980be834 (patch)
treee513862b31448dfec69fd84aa2afd6c38196e7f5 /ld/ldexp.c
parentb32a5c16f100c53fd9c0c22464f863eeeec6087a (diff)
downloadbinutils-gdb-1fb80d6d50f3c0adc46ff584af26583b980be834.tar.gz
When evaluating a ternary operator in a linker script, copy the symbol flags.
* ld/ldexp.c: (try_copy_symbol_flags): New. Factored out from... (exp_fold_tree_1): Here. Cope with ternary operator in assignments. Use new helper.
Diffstat (limited to 'ld/ldexp.c')
-rw-r--r--ld/ldexp.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/ld/ldexp.c b/ld/ldexp.c
index b7b6e6c57c9..7694f7b0ec0 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -973,7 +973,24 @@ is_align_conditional (const etree_type *tree)
&& is_dot_ne_0 (tree->trinary.cond)
&& is_value (tree->trinary.rhs, 1));
}
- return 0;
+ return FALSE;
+}
+
+/* Subroutine of exp_fold_tree_1 for copying a symbol type. */
+
+static void
+try_copy_symbol_type (struct bfd_link_hash_entry * h, etree_type *src)
+{
+ if (src->type.node_class == etree_name)
+ {
+ struct bfd_link_hash_entry *hsrc;
+
+ hsrc = bfd_link_hash_lookup (link_info.hash, src->name.name,
+ FALSE, FALSE, TRUE);
+ if (hsrc)
+ bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
+ hsrc);
+ }
}
static void
@@ -1166,18 +1183,25 @@ exp_fold_tree_1 (etree_type *tree)
tree->type.node_class = etree_provided;
/* Copy the symbol type if this is a simple assignment of
- one symbol to another. This could be more general
- (e.g. a ?: operator with NAMEs in each branch). */
+ one symbol to another. Also, handle the case of a foldable
+ ternary conditional with names on either side. */
if (tree->assign.src->type.node_class == etree_name)
+ try_copy_symbol_type (h, tree->assign.src);
+ else if (tree->assign.src->type.node_class == etree_trinary)
{
- struct bfd_link_hash_entry *hsrc;
-
- hsrc = bfd_link_hash_lookup (link_info.hash,
- tree->assign.src->name.name,
- FALSE, FALSE, TRUE);
- if (hsrc)
- bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
- hsrc);
+ exp_fold_tree_1 (tree->assign.src->trinary.cond);
+ if (expld.result.valid_p)
+ {
+ if (expld.result.value
+ && tree->assign.src->trinary.lhs->type.node_class
+ == etree_name)
+ try_copy_symbol_type (h, tree->assign.src->trinary.lhs);
+
+ if (!expld.result.value
+ && tree->assign.src->trinary.rhs->type.node_class
+ == etree_name)
+ try_copy_symbol_type (h, tree->assign.src->trinary.rhs);
+ }
}
}
else if (expld.phase == lang_final_phase_enum)