diff options
Diffstat (limited to 'contrib/gcc/cppexp.c')
-rw-r--r-- | contrib/gcc/cppexp.c | 593 |
1 files changed, 312 insertions, 281 deletions
diff --git a/contrib/gcc/cppexp.c b/contrib/gcc/cppexp.c index 44f8a66..aef6d19 100644 --- a/contrib/gcc/cppexp.c +++ b/contrib/gcc/cppexp.c @@ -1,5 +1,5 @@ /* Parse C expressions for CCCP. - Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998 Free Software Foundation. + Copyright (C) 1987, 92, 94, 95, 97, 98, 1999 Free Software Foundation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -26,24 +26,12 @@ Written by Per Bothner 1994. */ #include "config.h" #include "system.h" -#include "gansidecl.h" #include "cpplib.h" -extern char *xmalloc PARAMS ((unsigned)); -extern char *xrealloc PARAMS ((void *, unsigned)); - #ifdef MULTIBYTE_CHARS #include <locale.h> #endif -/* This is used for communicating lists of keywords with cccp.c. */ -struct arglist { - struct arglist *next; - U_CHAR *name; - int length; - int argno; -}; - #ifndef CHAR_TYPE_SIZE #define CHAR_TYPE_SIZE BITS_PER_UNIT #endif @@ -76,13 +64,21 @@ struct arglist { #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE #endif +#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ + ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \ + : ~ (HOST_WIDEST_INT) 0) + +#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ + ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \ + : ~ (HOST_WIDEST_INT) 0) + /* Yield nonzero if adding two numbers with A's and B's signs can yield a number with SUM's sign, where A, B, and SUM are all C integers. */ #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0) static void integer_overflow PARAMS ((cpp_reader *)); -static long left_shift PARAMS ((cpp_reader *, long, int, unsigned long)); -static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long)); +static HOST_WIDEST_INT left_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, int, unsigned HOST_WIDEST_INT)); +static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, int, unsigned HOST_WIDEST_INT)); #define ERROR 299 #define OROR 300 @@ -105,135 +101,117 @@ static long right_shift PARAMS ((cpp_reader *, long, int, unsigned long)); #define SKIP_OPERAND 8 /*#define UNSIGNEDP 16*/ -/* Find the largest host integer type and set its size and type. - Watch out: on some crazy hosts `long' is shorter than `int'. */ - -#ifndef HOST_WIDE_INT -# if HAVE_INTTYPES_H -# include <inttypes.h> -# define HOST_WIDE_INT intmax_t -# else -# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT \ - && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT) -# define HOST_WIDE_INT int -# else -# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG \ - || ! (defined LONG_LONG_MAX || defined LLONG_MAX)) -# define HOST_WIDE_INT long -# else -# define HOST_WIDE_INT long long -# endif -# endif -# endif -#endif - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#ifndef HOST_BITS_PER_WIDE_INT -#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT)) -#endif - struct operation { short op; char rprio; /* Priority of op (relative to it right operand). */ char flags; char unsignedp; /* true if value should be treated as unsigned */ - HOST_WIDE_INT value; /* The value logically "right" of op. */ + HOST_WIDEST_INT value; /* The value logically "right" of op. */ }; - -/* Take care of parsing a number (anything that starts with a digit). - LEN is the number of characters in it. */ -/* maybe needs to actually deal with floating point numbers */ +/* Parse and convert an integer for #if. Accepts decimal, hex, or octal + with or without size suffixes. */ -struct operation -parse_number (pfile, start, olen) +static struct operation +parse_number (pfile, start, end) cpp_reader *pfile; - char *start; - int olen; + U_CHAR *start; + U_CHAR *end; { struct operation op; - register char *p = start; - register int c; - register unsigned long n = 0, nd, ULONG_MAX_over_base; - register int base = 10; - register int len = olen; - register int overflow = 0; - register int digit, largest_digit = 0; + U_CHAR *p = start; + int c; + unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base; + int base = 10; + int overflow = 0; + int digit, largest_digit = 0; int spec_long = 0; op.unsignedp = 0; - for (c = 0; c < len; c++) - if (p[c] == '.') { - /* It's a float since it contains a point. */ - cpp_error (pfile, - "floating point numbers not allowed in #if expressions"); - op.op = ERROR; - return op; + if (p[0] == '0') + { + if (end - start >= 3 && (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + base = 16; + } + else + { + p += 1; + base = 8; + } } - if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) { - p += 2; - base = 16; - len -= 2; - } - else if (*p == '0') - base = 8; - /* Some buggy compilers (e.g. MPW C) seem to need both casts. */ - ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base); - - for (; len > 0; len--) { - c = *p++; - - if (c >= '0' && c <= '9') - digit = c - '0'; - else if (base == 16 && c >= 'a' && c <= 'f') - digit = c - 'a' + 10; - else if (base == 16 && c >= 'A' && c <= 'F') - digit = c - 'A' + 10; - else { - /* `l' means long, and `u' means unsigned. */ - while (1) { - if (c == 'l' || c == 'L') - { - if (spec_long) - cpp_error (pfile, "two `l's in integer constant"); - spec_long = 1; - } - else if (c == 'u' || c == 'U') - { - if (op.unsignedp) - cpp_error (pfile, "two `u's in integer constant"); - op.unsignedp = 1; - } - else - break; + MAX_over_base = (((unsigned HOST_WIDEST_INT) -1) + / ((unsigned HOST_WIDEST_INT) base)); - if (--len == 0) + while (p < end) + { + c = *p++; + + if (c >= '0' && c <= '9') + digit = c - '0'; + else if (base == 16 && c >= 'a' && c <= 'f') /* FIXME: assumes ASCII */ + digit = c - 'a' + 10; + else if (base == 16 && c >= 'A' && c <= 'F') + digit = c - 'A' + 10; + else if (c == '.') + { + /* It's a float since it contains a point. */ + cpp_error (pfile, + "floating point numbers are not allowed in #if expressions"); + goto error; + } + else + { + /* `l' means long, and `u' means unsigned. */ + for (;;) + { + if (c == 'l' || c == 'L') + spec_long++; + else if (c == 'u' || c == 'U') + op.unsignedp++; + else + { + /* Decrement p here so that the error for an invalid number + will be generated below in the case where this is the + last character in the buffer. */ + p--; + break; + } + if (p == end) + break; + c = *p++; + } + /* Don't look for any more digits after the suffixes. */ break; - c = *p++; - } - /* Don't look for any more digits after the suffixes. */ - break; + } + + if (largest_digit < digit) + largest_digit = digit; + nd = n * base + digit; + overflow |= MAX_over_base < n || nd < n; + n = nd; } - if (largest_digit < digit) - largest_digit = digit; - nd = n * base + digit; - overflow |= ULONG_MAX_over_base < n || nd < n; - n = nd; - } - if (len != 0) + if (p != end) { - cpp_error (pfile, "Invalid number in #if expression"); - op.op = ERROR; - return op; + cpp_error (pfile, "invalid number in #if expression"); + goto error; } - + else if (spec_long > (CPP_OPTIONS (pfile)->c89 ? 1 : 2)) + { + cpp_error (pfile, "too many `l' suffixes in integer constant"); + goto error; + } + else if (op.unsignedp > 1) + { + cpp_error (pfile, "too many `u' suffixes in integer constant"); + goto error; + } + if (base <= largest_digit) cpp_pedwarn (pfile, "integer constant contains digits beyond the radix"); @@ -241,18 +219,132 @@ parse_number (pfile, start, olen) cpp_pedwarn (pfile, "integer constant out of range"); /* If too big to be signed, consider it unsigned. */ - if ((long) n < 0 && ! op.unsignedp) + else if ((HOST_WIDEST_INT) n < 0 && ! op.unsignedp) { if (base == 10) - cpp_warning (pfile, "integer constant is so large that it is unsigned"); + cpp_warning (pfile, + "integer constant is so large that it is unsigned"); op.unsignedp = 1; } op.value = n; op.op = INT; return op; + + error: + op.op = ERROR; + return op; +} + +/* Parse and convert a character constant for #if. Understands backslash + escapes (\n, \031) and multibyte characters (if so configured). */ +static struct operation +parse_charconst (pfile, start, end) + cpp_reader *pfile; + U_CHAR *start; + U_CHAR *end; +{ + struct operation op; + HOST_WIDEST_INT result = 0; + int num_chars = 0; + int num_bits; + unsigned int width = MAX_CHAR_TYPE_SIZE, mask = MAX_CHAR_TYPE_MASK; + int max_chars; + U_CHAR *ptr = start; + + /* FIXME: Should use reentrant multibyte functions. */ +#ifdef MULTIBYTE_CHARS + wchar_t c = (wchar_t)-1; + (void) mbtowc (NULL_PTR, NULL_PTR, 0); +#else + int c = -1; +#endif + + if (*ptr == 'L') + { + ++ptr; + width = MAX_WCHAR_TYPE_SIZE, mask = MAX_WCHAR_TYPE_MASK; + } + max_chars = MAX_LONG_TYPE_SIZE / width; + + ++ptr; /* skip initial quote */ + + while (ptr < end) + { +#ifndef MULTIBYTE_CHARS + c = *ptr++; +#else + ptr += mbtowc (&c, ptr, end - ptr); +#endif + if (c == '\'' || c == '\0') + break; + else if (c == '\\') + { + /* Hopefully valid assumption: if mbtowc returns a backslash, + we are in initial shift state. No valid escape-sequence + character can take us out of initial shift state or begin + an unshifted multibyte char, so cpp_parse_escape doesn't + need to know about multibyte chars. */ + + c = cpp_parse_escape (pfile, (char **) &ptr, mask); + if (width < HOST_BITS_PER_INT + && (unsigned int) c >= (unsigned int)(1 << width)) + cpp_pedwarn (pfile, "escape sequence out of range for character"); + } + + /* Merge character into result; ignore excess chars. */ + if (++num_chars <= max_chars) + { + if (width < HOST_BITS_PER_INT) + result = (result << width) | (c & ((1 << width) - 1)); + else + result = c; + } + } + + if (num_chars == 0) + { + cpp_error (pfile, "empty character constant"); + goto error; + } + else if (c != '\'') + { + /* cpp_get_token has already emitted an error if !traditional. */ + if (! CPP_TRADITIONAL (pfile)) + cpp_error (pfile, "malformatted character constant"); + goto error; + } + else if (num_chars > max_chars) + { + cpp_error (pfile, "character constant too long"); + goto error; + } + else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile)) + cpp_warning (pfile, "multi-character character constant"); + + /* If char type is signed, sign-extend the constant. */ + num_bits = num_chars * width; + + if (cpp_lookup (pfile, (U_CHAR *)"__CHAR_UNSIGNED__", + sizeof ("__CHAR_UNSIGNED__")-1, -1) + || ((result >> (num_bits - 1)) & 1) == 0) + op.value = result & ((unsigned HOST_WIDEST_INT) ~0 + >> (HOST_BITS_PER_WIDEST_INT - num_bits)); + else + op.value = result | ~((unsigned HOST_WIDEST_INT) ~0 + >> (HOST_BITS_PER_WIDEST_INT - num_bits)); + + /* This is always a signed type. */ + op.unsignedp = 0; + op.op = CHAR; + return op; + + error: + op.op = ERROR; + return op; } + struct token { char *operator; int token; @@ -274,13 +366,13 @@ static struct token tokentab2[] = { /* Read one token. */ -struct operation +static struct operation cpp_lex (pfile, skip_evaluation) cpp_reader *pfile; int skip_evaluation; { - register int c; - register struct token *toktab; + U_CHAR c; + struct token *toktab; enum cpp_token token; struct operation op; U_CHAR *tok_start, *tok_end; @@ -292,8 +384,11 @@ cpp_lex (pfile, skip_evaluation) cpp_skip_hspace (pfile); c = CPP_BUF_PEEK (CPP_BUFFER (pfile)); if (c == '#') - return parse_number (pfile, - cpp_read_check_assertion (pfile) ? "1" : "0", 1); + { + op.op = INT; + op.value = cpp_read_check_assertion (pfile); + return op; + } if (c == '\n') { @@ -319,131 +414,66 @@ cpp_lex (pfile, skip_evaluation) } cpp_pop_buffer (pfile); goto retry; - case CPP_HSPACE: case CPP_COMMENT: + case CPP_HSPACE: + case CPP_COMMENT: goto retry; case CPP_NUMBER: - return parse_number (pfile, tok_start, tok_end - tok_start); + return parse_number (pfile, tok_start, tok_end); case CPP_STRING: cpp_error (pfile, "string constants not allowed in #if expressions"); op.op = ERROR; return op; case CPP_CHAR: - /* This code for reading a character constant - handles multicharacter constants and wide characters. - It is mostly copied from c-lex.c. */ - { - register int result = 0; - register int num_chars = 0; - unsigned width = MAX_CHAR_TYPE_SIZE; - int wide_flag = 0; - int max_chars; - U_CHAR *ptr = tok_start; -#ifdef MULTIBYTE_CHARS - char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + MB_CUR_MAX]; -#else - char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1]; -#endif - - if (*ptr == 'L') - { - ptr++; - wide_flag = 1; - width = MAX_WCHAR_TYPE_SIZE; -#ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; -#endif - } - else - max_chars = MAX_LONG_TYPE_SIZE / width; + return parse_charconst (pfile, tok_start, tok_end); - ++ptr; - while (ptr < tok_end && ((c = *ptr++) != '\'')) - { - if (c == '\\') - { - c = cpp_parse_escape (pfile, (char **) &ptr); - if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1 << width)) - cpp_pedwarn (pfile, - "escape sequence out of range for character"); - } - - num_chars++; - - /* Merge character into result; ignore excess chars. */ - if (num_chars < max_chars + 1) - { - if (width < HOST_BITS_PER_INT) - result = (result << width) | (c & ((1 << width) - 1)); - else - result = c; - token_buffer[num_chars - 1] = c; - } - } - - token_buffer[num_chars] = 0; - - if (c != '\'') - cpp_error (pfile, "malformatted character constant"); - else if (num_chars == 0) - cpp_error (pfile, "empty character constant"); - else if (num_chars > max_chars) - { - num_chars = max_chars; - cpp_error (pfile, "character constant too long"); - } - else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile)) - cpp_warning (pfile, "multi-character character constant"); + case CPP_NAME: + op.op = INT; + op.unsignedp = 0; + op.value = 0; + if (strcmp (tok_start, "defined")) + { + if (CPP_WARN_UNDEF (pfile) && !skip_evaluation) + cpp_warning (pfile, "`%.*s' is not defined", + (int) (tok_end - tok_start), tok_start); + } + else + { + int paren = 0, len; + cpp_buffer *ip = CPP_BUFFER (pfile); + U_CHAR *tok; - /* If char type is signed, sign-extend the constant. */ - if (! wide_flag) - { - int num_bits = num_chars * width; + cpp_skip_hspace (pfile); + if (*ip->cur == '(') + { + paren++; + ip->cur++; /* Skip over the paren */ + cpp_skip_hspace (pfile); + } - if (cpp_lookup (pfile, (U_CHAR *)"__CHAR_UNSIGNED__", - sizeof ("__CHAR_UNSIGNED__")-1, -1) - || ((result >> (num_bits - 1)) & 1) == 0) - op.value - = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits)); - else - op.value - = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits)); - } - else - { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[0] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer, num_chars) == num_chars) - result = wc; - else - cpp_pedwarn (pfile,"Ignoring invalid multibyte character"); - } -#endif - op.value = result; + if (!is_idstart[*ip->cur]) + goto oops; + if (ip->cur[0] == 'L' && (ip->cur[1] == '\'' || ip->cur[1] == '"')) + goto oops; + tok = ip->cur; + while (is_idchar[*ip->cur]) + ++ip->cur; + len = ip->cur - tok; + cpp_skip_hspace (pfile); + if (paren) + { + if (*ip->cur != ')') + goto oops; + ++ip->cur; } - } + if (cpp_lookup (pfile, tok, len, -1)) + op.value = 1; - /* This is always a signed type. */ - op.unsignedp = 0; - op.op = CHAR; - + } return op; - case CPP_NAME: - if (CPP_WARN_UNDEF (pfile) && !skip_evaluation) - cpp_warning (pfile, "`%.*s' is not defined", - (int) (tok_end - tok_start), tok_start); - return parse_number (pfile, "0", 0); + oops: + cpp_error (pfile, "`defined' without an identifier"); + return op; case CPP_OTHER: /* See if it is a special token of length 2. */ @@ -454,11 +484,8 @@ cpp_lex (pfile, skip_evaluation) && tok_start[1] == toktab->operator[1]) break; if (toktab->token == ERROR) - { - char *buf = (char *) alloca (40); - sprintf (buf, "`%s' not allowed in operand of `#if'", tok_start); - cpp_error (pfile, buf); - } + cpp_error (pfile, "`%s' not allowed in operand of `#if'", + tok_start); op.op = toktab->token; return op; } @@ -484,10 +511,11 @@ cpp_lex (pfile, skip_evaluation) If \ is followed by 000, we return 0 and leave the string pointer after the zeros. A value of 0 does not mean end of string. */ -int -cpp_parse_escape (pfile, string_ptr) +HOST_WIDEST_INT +cpp_parse_escape (pfile, string_ptr, result_mask) cpp_reader *pfile; char **string_ptr; + HOST_WIDEST_INT result_mask; { register int c = *(*string_ptr)++; switch (c) @@ -498,7 +526,7 @@ cpp_parse_escape (pfile, string_ptr) return TARGET_BS; case 'e': case 'E': - if (CPP_PEDANTIC (pfile)) + if (CPP_OPTIONS (pfile)->pedantic) cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c); return 033; case 'f': @@ -526,7 +554,7 @@ cpp_parse_escape (pfile, string_ptr) case '6': case '7': { - register int i = c - '0'; + register HOST_WIDEST_INT i = c - '0'; register int count = 0; while (++count < 3) { @@ -539,17 +567,17 @@ cpp_parse_escape (pfile, string_ptr) break; } } - if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0) + if (i != (i & result_mask)) { - i &= (1 << MAX_CHAR_TYPE_SIZE) - 1; - cpp_pedwarn (pfile, - "octal character constant does not fit in a byte"); + i &= result_mask; + cpp_pedwarn (pfile, "octal escape sequence out of range"); } return i; } case 'x': { - register unsigned i = 0, overflow = 0, digits_found = 0, digit; + register unsigned HOST_WIDEST_INT i = 0, overflow = 0; + register int digits_found = 0, digit; for (;;) { c = *(*string_ptr)++; @@ -570,11 +598,10 @@ cpp_parse_escape (pfile, string_ptr) } if (!digits_found) cpp_error (pfile, "\\x used with no following hex digits"); - if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1))) + if (overflow | (i != (i & result_mask))) { - i &= (1 << BITS_PER_UNIT) - 1; - cpp_pedwarn (pfile, - "hex character constant does not fit in a byte"); + i &= result_mask; + cpp_pedwarn (pfile, "hex escape sequence out of range"); } return i; } @@ -591,41 +618,41 @@ integer_overflow (pfile) cpp_pedwarn (pfile, "integer overflow in preprocessor expression"); } -static long +static HOST_WIDEST_INT left_shift (pfile, a, unsignedp, b) cpp_reader *pfile; - long a; + HOST_WIDEST_INT a; int unsignedp; - unsigned long b; + unsigned HOST_WIDEST_INT b; { - if (b >= HOST_BITS_PER_LONG) + if (b >= HOST_BITS_PER_WIDEST_INT) { if (! unsignedp && a != 0) integer_overflow (pfile); return 0; } else if (unsignedp) - return (unsigned long) a << b; + return (unsigned HOST_WIDEST_INT) a << b; else { - long l = a << b; + HOST_WIDEST_INT l = a << b; if (l >> b != a) integer_overflow (pfile); return l; } } -static long +static HOST_WIDEST_INT right_shift (pfile, a, unsignedp, b) cpp_reader *pfile ATTRIBUTE_UNUSED; - long a; + HOST_WIDEST_INT a; int unsignedp; - unsigned long b; + unsigned HOST_WIDEST_INT b; { - if (b >= HOST_BITS_PER_LONG) - return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1); + if (b >= HOST_BITS_PER_WIDEST_INT) + return unsignedp ? 0 : a >> (HOST_BITS_PER_WIDEST_INT - 1); else if (unsignedp) - return (unsigned long) a >> b; + return (unsigned HOST_WIDEST_INT) a >> b; else return a >> b; } @@ -649,12 +676,13 @@ right_shift (pfile, a, unsignedp, b) #define COMPARE(OP) \ top->unsignedp = 0;\ - top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP v2 : (v1 OP v2) + top->value = (unsigned1 || unsigned2) \ + ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2) /* Parse and evaluate a C expression, reading from PFILE. Returns the value of the expression. */ -HOST_WIDE_INT +HOST_WIDEST_INT cpp_parse_expr (pfile) cpp_reader *pfile; { @@ -673,7 +701,7 @@ cpp_parse_expr (pfile) struct operation *stack = init_stack; struct operation *limit = stack + INIT_STACK_SIZE; register struct operation *top = stack; - int lprio, rprio; + int lprio, rprio = 0; int skip_evaluation = 0; top->rprio = 0; @@ -693,7 +721,8 @@ cpp_parse_expr (pfile) switch (op.op) { case NAME: - abort (); + cpp_fatal (pfile, "internal error: cpp_lex returns a NAME"); + goto syntax_error; case INT: case CHAR: top->value = op.value; top->unsignedp = op.unsignedp; @@ -734,6 +763,8 @@ cpp_parse_expr (pfile) case '?': lprio = COND_PRIO + 1; rprio = COND_PRIO; goto maybe_reduce; + case ERROR: + goto syntax_error; binop: flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED; rprio = lprio + 1; @@ -757,7 +788,7 @@ cpp_parse_expr (pfile) /* Push an operator, and check if we can reduce now. */ while (top->rprio > lprio) { - long v1 = top[-1].value, v2 = top[0].value; + HOST_WIDEST_INT v1 = top[-1].value, v2 = top[0].value; int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp; top--; if ((top[1].flags & LEFT_OPERAND_REQUIRED) @@ -812,7 +843,7 @@ cpp_parse_expr (pfile) case '*': top->unsignedp = unsigned1 || unsigned2; if (top->unsignedp) - top->value = (unsigned long) v1 * v2; + top->value = (unsigned HOST_WIDEST_INT) v1 * v2; else if (!skip_evaluation) { top->value = v1 * v2; @@ -832,7 +863,7 @@ cpp_parse_expr (pfile) } top->unsignedp = unsigned1 || unsigned2; if (top->unsignedp) - top->value = (unsigned long) v1 / v2; + top->value = (unsigned HOST_WIDEST_INT) v1 / v2; else { top->value = v1 / v2; @@ -850,7 +881,7 @@ cpp_parse_expr (pfile) } top->unsignedp = unsigned1 || unsigned2; if (top->unsignedp) - top->value = (unsigned long) v1 % v2; + top->value = (unsigned HOST_WIDEST_INT) v1 % v2; else top->value = v1 % v2; break; @@ -967,11 +998,11 @@ cpp_parse_expr (pfile) } break; default: - fprintf (stderr, - top[1].op >= ' ' && top[1].op <= '~' - ? "unimplemented operator '%c'\n" - : "unimplemented operator '\\%03o'\n", - top[1].op); + cpp_error (pfile, + (top[1].op >= ' ' && top[1].op <= '~' + ? "unimplemented operator '%c'\n" + : "unimplemented operator '\\%03o'\n"), + top[1].op); } } if (op.op == 0) |