Hi Guys,
I ran a x86 hosted bootstrap of the mainline gcc and binutils
sources over the weekend and it failed with this error report:
bfd/elflink.c: In function 'elf_fixup_link_order':
bfd/elflink.c:9893: error: type mismatch in unary expression
long unsigned int
int
D.16764 = -D.16763
Not exactly the most helpful error report in the world, but with a
set of tree dumps and a bit of guesswork I tracked the problem down
to this line:
offset &= ~(bfd_vma)((1 << s->alignment_power) - 1);
Gcc has worked out that "~ foo - 1" is the same as "- foo" but it
has failed to appreciate that the (bfd_vma) cast should apply to the
constant 1 as well as the expression (1 << s->alignment_power). So
it thinks that the expression above is equivalent to (paraphrasing
slightly):
unsigned long int D.16764;
signed int D.16763;
D.16763 = 1 << s->alignment_power;
D.16764 = - D.16763;
offset = offset & D.16764;
Hence it is complaining about the unary conversion of D.16763 into
D.16764. I think that this is probably a gimplification bug but
that is beyond me, so I have Cc'ed this email to the gcc bugs list.
In the meantime however I have hit on a simple workaround:
offset &= (bfd_vma)~((1 << s->alignment_power) - 1);
(ie moving the cast to a (bfd_vma) to before the inversion
operator). This works in the bootstrap although it would fail if
the alignment power is sufficiently large to cause the left shift to
overflow an integer. So I am going to check in a variant of this
change:
offset &= (bfd_vma)~((1L << s->alignment_power) - 1L);
which I think should satisfy everyone. I will also check the patch
into the 2.18 branch.
Cheers
Nick
PS. The bootstrap still does not succeed with this patch
installed. It fails later on with this error report:
i386-dis.c:4213: error: type mismatch in pointer plus expression
struct dis386 *
struct dis386[8] *
unsigned int
dp = &float_reg + D.7721
I am looking into this now.
bfd/ChangeLog
2007-08-20 Nick Clifton <[EMAIL PROTECTED]>
* elflink.c (elf_fixup_link_order): Rewrite conversion of
s->alignment_power into an offset mask in order to avoid a gcc
error message.
Index: bfd/elflink.c
===
RCS file: /cvs/cvsfiles/devo/bfd/elflink.c,v
retrieving revision 1.95
diff -c -3 -p -r1.95 elflink.c
*** bfd/elflink.c 19 Aug 2007 17:49:44 - 1.95
--- bfd/elflink.c 20 Aug 2007 07:39:30 -
*** elf_fixup_link_order (bfd *abfd, asectio
*** 9965,9971
for (n = 0; n < seen_linkorder; n++)
{
s = sections[n]->u.indirect.section;
! offset &= ~(bfd_vma)((1 << s->alignment_power) - 1);
s->output_offset = offset;
sections[n]->offset = offset;
offset += sections[n]->size;
--- 9965,9971
for (n = 0; n < seen_linkorder; n++)
{
s = sections[n]->u.indirect.section;
! offset &= (bfd_vma)~((1L << s->alignment_power) - 1L);
s->output_offset = offset;
sections[n]->offset = offset;
offset += sections[n]->size;