diff options
author | Richard Stallman <rms@gnu.org> | 1993-09-28 01:02:31 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-09-28 01:02:31 +0000 |
commit | e26ceb284367fff654268a31fcaa5546d42b5fb0 (patch) | |
tree | c319633d9356c927ffd28ed1e6575c8757cdd3be | |
parent | 2da63e2ae05e4cf70bc307c4eb741d5865bf3aa2 (diff) | |
download | gcc-e26ceb284367fff654268a31fcaa5546d42b5fb0.zip gcc-e26ceb284367fff654268a31fcaa5546d42b5fb0.tar.gz gcc-e26ceb284367fff654268a31fcaa5546d42b5fb0.tar.bz2 |
(yylex): Handle i together with f or l in float constant.
From-SVN: r5501
-rw-r--r-- | gcc/c-lex.c | 117 |
1 files changed, 78 insertions, 39 deletions
diff --git a/gcc/c-lex.c b/gcc/c-lex.c index f5f8872..fe59c1c 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -1477,47 +1477,86 @@ yylex () } else { + int fflag = 0, lflag = 0; + /* Copy token_buffer now, while it has just the number + and not the suffixes; once we add `f' or `i', + REAL_VALUE_ATOF may not work any more. */ + char *copy = (char *) alloca (p - token_buffer + 1); + bcopy (token_buffer, copy, p - token_buffer + 1); + set_float_handler (handler); -/* The second argument, machine_mode, of REAL_VALUE_ATOF tells the - desired precision of the binary result of decimal-to-binary conversion. */ + while (1) + { + int lose = 0; - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - type = float_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `float'"); - garbage_chars = -1; - break; - - case 'l': case 'L': - type = long_double_type_node; - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ( - "floating point number exceeds range of `long double'"); - garbage_chars = -1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - imag = 1; - garbage_chars = -1; - break; - - default: - value = REAL_VALUE_ATOF (token_buffer, TYPE_MODE (type)); - if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT - && REAL_VALUE_ISINF (value) && pedantic) - pedwarn ("floating point number exceeds range of `double'"); - } - set_float_handler (NULL_PTR); + /* Read the suffixes to choose a data type. */ + switch (c) + { + case 'f': case 'F': + if (fflag) + error ("more than one `f' in numeric constant"); + fflag = 1; + break; + + case 'l': case 'L': + if (lflag) + error ("more than one `l' in numeric constant"); + lflag = 1; + break; + + case 'i': case 'I': + if (imag) + error ("more than one `i' or `j' in numeric constant"); + imag = 1; + break; + + default: + lose = 1; + } + + if (lose) + break; + + if (p >= token_buffer + maxtoken - 3) + p = extend_token_buffer (p); + *p++ = c; + *p = 0; + c = getc (finput); + } + + /* The second argument, machine_mode, of REAL_VALUE_ATOF + tells the desired precision of the binary result + of decimal-to-binary conversion. */ + + if (fflag) + { + if (lflag) + error ("both `f' and `l' in floating constant"); + + type = float_type_node; + value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); + if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT + && REAL_VALUE_ISINF (value) && pedantic) + pedwarn ("floating point number exceeds range of `float'"); + } + else if (lflag) + { + type = long_double_type_node; + value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); + if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT + && REAL_VALUE_ISINF (value) && pedantic) + pedwarn ("floating point number exceeds range of `long double'"); + } + else + { + value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); + if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT + && REAL_VALUE_ISINF (value) && pedantic) + pedwarn ("floating point number exceeds range of `double'"); + } + + set_float_handler (NULL_PTR); } #ifdef ERANGE if (errno == ERANGE && !flag_traditional && pedantic) @@ -1533,7 +1572,7 @@ yylex () } } #endif - /* Note: garbage_chars is -1 if first char is *not* garbage. */ + garbage_chars = 0; while (isalnum (c) || c == '.' || c == '_' || (!flag_traditional && (c == '+' || c == '-') && (p[-1] == 'e' || p[-1] == 'E'))) |