Plan for bug-fixing g77-3.1.
Toon Moene
toon@moene.indiv.nluug.nl
Fri Jan 25 18:08:00 GMT 2002
I wrote:
> I'm planning to do the following to fix extant bugs in g77 for the 3.1
> release:
>
> 1. PR 3743 Reference to intrinsic `ISHFT' invalid
>
> This is due to the subtle bug in the intrinsics table that David
> Edelsohn showed. I'll probably follow his advice in
>
> http://gcc.gnu.org/ml/gcc-patches/2002-01/msg00000.html
>
> (use strcasecmp in libiberty) to fix this problem.
The proposed patch is attached - it passes make bootstrap (C and
Fortran), make check (Fortran only) and make install (C and Fortran) on
i686-pc-linux-gnu. I send it to the list now, so that other people
might try it on their systems. I'll certainly _not_ commit it before it
passes on SPARC, MIPS, Alpha and PowerPC.
Now for the proof that this is correct.
As David Edelsohn showed, the intrinsics table of g77 (in f/intrin.def)
is sorted _on the upper case names only_.
This means that, in order to fix the deficiency, we have to rely on
comparing to the the upper case entry only as long as this defines the
search direction for `bsearch'.
The attached patch does that.
It first compares the would-be-intrinsic-name case-insensitively to the
upper case entry of the table.
In case the g77 options indicate that intrinsics have no case
sensitivity or are upper case only, the result of this comparison is
used directly.
In case the g77 options indicate that intrinsics should have been
written in lower case, the next comparison is against the exact lower
case name.
In case the g77 options indicate that intrinsics should have been
written to a predefined "initial caps" convention, the next comparison
is against the string according to that convention.
If the case-insensitive comparison to the upper case entry didn't match,
the comparison is returned, which will direct `bsearch' in choosing the
right half of the table for further search.
The interesting part is what happens if the case insensitive comparison
succeeds, but the case sensitive one doesn't. Due to the fact that
`bsearch' will always either choose or cut a half, this search must
terminate in case there's no match. Because the comparison that's
returned is always the same for each entry of the 380-entry table for
invariant "intrinsic capitalisation mode", this will always be the case.
End-of-proof.
Note that I do not have to prove anything about alias analysis in
Fortran - that's dead simple by comparison:
If you don't indicate to the compiler that two items can overlap (by
using EQUIVALENCE) they better don't - or else [1].
--
Toon Moene - mailto:toon@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)
[1] According to the comp.lang.fortran FAQ, "or else" means: "could
start
WW III, if the right - optional - hardware is installed."
Obviously, the comp.lang.fortran FAQ was written during the Cold
War.
-------------- next part --------------
*** intrin.c.orig Mon Jan 14 21:57:55 2002
--- intrin.c Fri Jan 25 22:15:28 2002
*************** ffeintrin_check_any_ (ffebld arglist)
*** 1154,1158 ****
}
! /* Compare name to intrinsic's name. Uses strcmp on arguments' names. */
static int
--- 1154,1161 ----
}
! /* Compare name to intrinsic's name. Uses strcmp on arguments' names.
! The intrinsics table is sorted on the upper case entries; so first
! compare irrespective of case on the `uc' entry. If it matches,
! compare according to the setting of intrinsics case comparison mode. */
static int
*************** ffeintrin_cmp_name_ (const void *name, c
*** 1162,1167 ****
const char *const lc = ((const struct _ffeintrin_name_ *) intrinsic)->name_lc;
const char *const ic = ((const struct _ffeintrin_name_ *) intrinsic)->name_ic;
! return ffesrc_strcmp_2c (ffe_case_intrin (), name, uc, lc, ic);
}
--- 1165,1184 ----
const char *const lc = ((const struct _ffeintrin_name_ *) intrinsic)->name_lc;
const char *const ic = ((const struct _ffeintrin_name_ *) intrinsic)->name_ic;
+ int i;
! if ((i = strcasecmp (name, uc)) == 0)
! {
! switch (ffe_case_intrin ())
! {
! case FFE_caseLOWER:
! return strcmp(name, lc);
! case FFE_caseINITCAP:
! return strcmp(name, ic);
! default:
! return 0;
! }
! }
!
! return i;
}
More information about the Gcc
mailing list