From 1fb80d6d50f3c0adc46ff584af26583b980be834 Mon Sep 17 00:00:00 2001 From: Simon Dardis Date: Thu, 15 Oct 2015 13:28:27 +0100 Subject: [PATCH] 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. --- ld/ChangeLog | 6 ++++++ ld/ldexp.c | 44 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 61a21beb1a..fcae5a0d6e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2015-10-15 Simon Dardis + + * 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. + 2015-10-14 Nick Clifton * po/zh_TW.po: Updated Chinese translation. diff --git a/ld/ldexp.c b/ld/ldexp.c index b7b6e6c57c..7694f7b0ec 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; + 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); - 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); + 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)