This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Fix gcc bootstrap problem
- From: Michael Matz <matz at suse dot de>
- To: Nick Clifton <nickc at redhat dot com>
- Cc: binutils at sourceware dot org, Richard Guenther <rguenther at suse dot de>
- Date: Wed, 22 Aug 2007 03:28:54 +0200 (CEST)
- Subject: Re: Fix gcc bootstrap problem
- References: <m31wdywr2y.fsf@redhat.com>
Hi Nick,
[full quote for Richard]
On Mon, 20 Aug 2007, Nick Clifton wrote:
> 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
This and the error below are really compiler bugs (frontend missing to
generate appropriate casts), which the type verifier now catches, i.e.
internal compiler errors. Please create a bug report or provide a
preprocessed file showing the problem.
> 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 <nickc@redhat.com>
>
> * 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 -0000 1.95
> --- bfd/elflink.c 20 Aug 2007 07:39:30 -0000
> *************** 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;
>