This is the mail archive of the
`gcc-patches@gcc.gnu.org`
mailing list for the GCC project.

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |

Other format: | [Raw text] |

*From*: Tobias Schlüter <tobias dot schlueter at physik dot uni-muenchen dot de>*To*: GCC Fortran mailing list <fortran at gcc dot gnu dot org>,patch <gcc-patches at gcc dot gnu dot org>*Date*: Wed, 06 Oct 2004 19:28:40 +0200*Subject*: [gfortran] PATCH: Allow wide boz constants

Currently, we always parse boz-literal-constants as INTEGER*4. This was a problem for me when I wanted to write testcases for our bit intrinsics, as I couldn't enter numbers in hexadecimal, which of course makes it much easier to see what should happen in bit handling. The fundamental issue with this is that we don't know which type variable a data constant will be assigned to. I briefly contemplated adding kind suffixes to boz-literal-constants, like z'44444'_4, but not only is this ugly, it is also superfluous, as the kind information is certainly redundant, as the boz constant will always be the initial value of a variable of a fixed type. Instead I developed this patch, which determines the smallest integer kind that a given boz-literal-constant of a certain length (measured in characters of source code) will fit in, and then sets the constant to that kind. Of course leading zeros will set off this scheme, and we will give the initialization a bigger kind than required, but as the value will be converted to the type of the corresponding variable, this works as well. Another special case is where there are more digits than supported by any integer kind. In this case this patch sets the value to the largest available integer kind, and then we will get an error if the value actually overflows that kind. Built, and verified. When trying to run the testsuite I found out that something in my tree broke during the last build, so I couldn't yet test this. Along with this patch I will add new testcases for the bit functions which will exercise this code. Ok if the testsuite passes? - Tobi 2004-10-06 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de> * primary.c (match_boz_constant): Determine required bit width from constant.

Index: primary.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/fortran/primary.c,v retrieving revision 1.12 diff -u -p -r1.12 primary.c --- primary.c 31 Aug 2004 13:35:01 -0000 1.12 +++ primary.c 6 Oct 2004 17:06:23 -0000 @@ -230,12 +230,15 @@ match_integer_constant (gfc_expr ** resu /* Match a binary, octal or hexadecimal constant that can be found in - a DATA statement. */ + a DATA statement. Since we don't know which variable we're going + to initialize, we determine the kind of the initialization from the + width of the boz constant. For instance, z'12' will be INTEGER*1, + o'01234567' will be INTEGER*2, etc. */ static match match_boz_constant (gfc_expr ** result) { - int radix, delim, length, x_hex; + int radix, delim, length, x_hex, kind, i, num_bits; locus old_loc; char *buffer; gfc_expr *e; @@ -295,12 +298,38 @@ match_boz_constant (gfc_expr ** result) match_digits (0, radix, buffer); gfc_next_char (); - e = gfc_convert_integer (buffer, gfc_default_integer_kind, radix, - &gfc_current_locus); + switch (radix) + { + case 2: + num_bits = length; + break; + case 8: + num_bits = length*3; + break; + case 16: + num_bits = length*4; + break; + default: + gcc_unreachable (); + } + + for (i = 0; gfc_integer_kinds[i].kind != 0; i++) + if (gfc_integer_kinds[i].bit_size > num_bits) + break; + + kind = gfc_integer_kinds[i].kind; + if (kind == 0) + /* Set kind to the largest available kind. If the boz constant + has leading zeros it might still fit in the target variable. + Otherwise, it will be an error anyway, as the initialization + would have overflowed the target variable. */ + kind = gfc_integer_kinds[i-1].kind; + + e = gfc_convert_integer (buffer, kind, radix, &gfc_current_locus); if (gfc_range_check (e) != ARITH_OK) { - gfc_error ("Integer too big for default integer kind at %C"); + gfc_error ("Integer too big for all integer kinds at %C"); gfc_free_expr (e); return MATCH_ERROR;

**Follow-Ups**:**Re: [gfortran] PATCH: Allow wide boz constants***From:*Tobias Schlüter

**Re: [gfortran] PATCH: Allow wide boz constants***From:*Paul Brook

Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|

Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |