OSDN Git Service

(cpp_lex): Correctly parse character constants.
[pf3gnuchains/gcc-fork.git] / gcc / cppexp.c
1 /* Parse C expressions for CCCP.
2    Copyright (C) 1987, 1992, 1994, 1995 Free Software Foundation.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
7 later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
18
19  In other words, you are welcome to use, share and improve this program.
20  You are forbidden to forbid anyone else to use, share and improve
21  what you give them.   Help stamp out software-hoarding!
22
23 Written by Per Bothner 1994. */
24
25 /* Parse a C expression from text in a string  */
26    
27 #include "config.h"
28 #include "cpplib.h"
29
30 extern char *xmalloc PARAMS ((unsigned));
31 extern char *xrealloc PARAMS ((char *, unsigned));
32
33 #ifdef MULTIBYTE_CHARS
34 #include <stdlib.h>
35 #include <locale.h>
36 #endif
37
38 #include <stdio.h>
39
40 /* This is used for communicating lists of keywords with cccp.c.  */
41 struct arglist {
42   struct arglist *next;
43   U_CHAR *name;
44   int length;
45   int argno;
46 };
47
48 /* Define a generic NULL if one hasn't already been defined.  */
49
50 #ifndef NULL
51 #define NULL 0
52 #endif
53
54 #ifndef GENERIC_PTR
55 #if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
56 #define GENERIC_PTR void *
57 #else
58 #define GENERIC_PTR char *
59 #endif
60 #endif
61
62 #ifndef NULL_PTR
63 #define NULL_PTR ((GENERIC_PTR)0)
64 #endif
65
66 extern char *xmalloc ();
67
68 #ifndef CHAR_TYPE_SIZE
69 #define CHAR_TYPE_SIZE BITS_PER_UNIT
70 #endif
71
72 #ifndef INT_TYPE_SIZE
73 #define INT_TYPE_SIZE BITS_PER_WORD
74 #endif
75
76 #ifndef LONG_TYPE_SIZE
77 #define LONG_TYPE_SIZE BITS_PER_WORD
78 #endif
79
80 #ifndef WCHAR_TYPE_SIZE
81 #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
82 #endif
83
84 #ifndef MAX_CHAR_TYPE_SIZE
85 #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
86 #endif
87
88 #ifndef MAX_INT_TYPE_SIZE
89 #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE
90 #endif
91
92 #ifndef MAX_LONG_TYPE_SIZE
93 #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
94 #endif
95
96 #ifndef MAX_WCHAR_TYPE_SIZE
97 #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
98 #endif
99
100 /* Yield nonzero if adding two numbers with A's and B's signs can yield a
101    number with SUM's sign, where A, B, and SUM are all C integers.  */
102 #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
103
104 static void integer_overflow ();
105 static long left_shift ();
106 static long right_shift ();
107
108 #define ERROR 299
109 #define OROR 300
110 #define ANDAND 301
111 #define EQUAL 302
112 #define NOTEQUAL 303
113 #define LEQ 304
114 #define GEQ 305
115 #define LSH 306
116 #define RSH 307
117 #define NAME 308
118 #define INT 309
119 #define CHAR 310
120
121 #define LEFT_OPERAND_REQUIRED 1
122 #define RIGHT_OPERAND_REQUIRED 2
123 #define HAVE_VALUE 4
124 /*#define UNSIGNEDP 8*/
125
126 #ifndef HOST_BITS_PER_WIDE_INT
127
128 #if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
129 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
130 #define HOST_WIDE_INT long
131 #else
132 #define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
133 #define HOST_WIDE_INT int
134 #endif
135
136 #endif
137
138 struct operation {
139     short op;
140     char rprio; /* Priority of op (relative to it right operand). */
141     char flags;
142     char unsignedp;    /* true if value should be treated as unsigned */
143     HOST_WIDE_INT value;        /* The value logically "right" of op. */
144 };
145 \f
146 /* Take care of parsing a number (anything that starts with a digit).
147    LEN is the number of characters in it.  */
148
149 /* maybe needs to actually deal with floating point numbers */
150
151 struct operation
152 parse_number (pfile, start, olen)
153      cpp_reader *pfile;
154      char *start;
155      int olen;
156 {
157   struct operation op;
158   register char *p = start;
159   register int c;
160   register unsigned long n = 0, nd, ULONG_MAX_over_base;
161   register int base = 10;
162   register int len = olen;
163   register int overflow = 0;
164   register int digit, largest_digit = 0;
165   int spec_long = 0;
166
167   op.unsignedp = 0;
168
169   for (c = 0; c < len; c++)
170     if (p[c] == '.') {
171       /* It's a float since it contains a point.  */
172       cpp_error (pfile,
173                  "floating point numbers not allowed in #if expressions");
174       op.op = ERROR;
175       return op;
176     }
177
178   if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) {
179     p += 2;
180     base = 16;
181     len -= 2;
182   }
183   else if (*p == '0')
184     base = 8;
185
186   /* Some buggy compilers (e.g. MPW C) seem to need both casts. */
187   ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base);
188
189   for (; len > 0; len--) {
190     c = *p++;
191
192     if (c >= '0' && c <= '9')
193       digit = c - '0';
194     else if (base == 16 && c >= 'a' && c <= 'f')
195       digit = c - 'a' + 10;
196     else if (base == 16 && c >= 'A' && c <= 'F')
197       digit = c - 'A' + 10;
198     else {
199       /* `l' means long, and `u' means unsigned.  */
200       while (1) {
201         if (c == 'l' || c == 'L')
202           {
203             if (spec_long)
204               cpp_error (pfile, "two `l's in integer constant");
205             spec_long = 1;
206           }
207         else if (c == 'u' || c == 'U')
208           {
209             if (op.unsignedp)
210               cpp_error (pfile, "two `u's in integer constant");
211             op.unsignedp = 1;
212           }
213         else
214           break;
215
216         if (--len == 0)
217           break;
218         c = *p++;
219       }
220       /* Don't look for any more digits after the suffixes.  */
221       break;
222     }
223     if (largest_digit < digit)
224       largest_digit = digit;
225     nd = n * base + digit;
226     overflow |= ULONG_MAX_over_base < n | nd < n;
227     n = nd;
228   }
229
230   if (len != 0)
231     {
232       cpp_error (pfile, "Invalid number in #if expression");
233       op.op = ERROR;
234       return op;
235     }
236
237   if (base <= largest_digit)
238     cpp_warning (pfile, "integer constant contains digits beyond the radix");
239
240   if (overflow)
241     cpp_warning (pfile, "integer constant out of range");
242
243   /* If too big to be signed, consider it unsigned.  */
244   if ((long) n < 0 && ! op.unsignedp)
245     {
246       if (base == 10)
247         cpp_warning (pfile, "integer constant is so large that it is unsigned");
248       op.unsignedp = 1;
249     }
250
251   op.value = n;
252   op.op = INT;
253   return op;
254 }
255
256 struct token {
257   char *operator;
258   int token;
259 };
260
261 static struct token tokentab2[] = {
262   {"&&", ANDAND},
263   {"||", OROR},
264   {"<<", LSH},
265   {">>", RSH},
266   {"==", EQUAL},
267   {"!=", NOTEQUAL},
268   {"<=", LEQ},
269   {">=", GEQ},
270   {"++", ERROR},
271   {"--", ERROR},
272   {NULL, ERROR}
273 };
274
275 /* Read one token. */
276
277 struct operation
278 cpp_lex (pfile)
279 cpp_reader *pfile;
280 {
281   register int c;
282   register int namelen;
283   register struct token *toktab;
284   enum cpp_token token;
285   struct operation op;
286   U_CHAR *tok_start, *tok_end;
287   int old_written;
288
289  retry:
290
291   old_written = CPP_WRITTEN (pfile);
292   cpp_skip_hspace (pfile);
293   c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
294   if (c == '#')
295     return parse_number (pfile,
296                          cpp_read_check_assertion (pfile) ? "1" : "0", 1);
297
298   if (c == '\n')
299     {
300       op.op = 0;
301       return op;
302     }
303
304   token = cpp_get_token (pfile);
305   tok_start = pfile->token_buffer + old_written;
306   tok_end = CPP_PWRITTEN (pfile);
307   pfile->limit = tok_start;
308   switch (token)
309   {
310     case CPP_EOF: /* Should not happen ... */
311       op.op = 0;
312       return op;
313     case CPP_VSPACE:
314     case CPP_POP:
315       if (CPP_BUFFER (pfile)->fname != NULL)
316         {
317           op.op = 0;
318           return op;
319         }
320       goto retry;
321     case CPP_HSPACE:   case CPP_COMMENT: 
322       goto retry;
323     case CPP_NUMBER:
324       return parse_number (pfile, tok_start, tok_end - tok_start);
325     case CPP_STRING:
326       cpp_error (pfile, "string constants not allowed in #if expressions");
327       op.op = ERROR;
328       return op;
329     case CPP_CHAR:
330       /* This code for reading a character constant
331          handles multicharacter constants and wide characters.
332          It is mostly copied from c-lex.c.  */
333       {
334         register int result = 0;
335         register num_chars = 0;
336         unsigned width = MAX_CHAR_TYPE_SIZE;
337         int wide_flag = 0;
338         int max_chars;
339         U_CHAR *ptr = tok_start;
340 #ifdef MULTIBYTE_CHARS
341         char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + MB_CUR_MAX];
342 #else
343         char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1];
344 #endif
345
346         if (*ptr == 'L')
347           {
348             ptr++;
349             wide_flag = 1;
350             width = MAX_WCHAR_TYPE_SIZE;
351 #ifdef MULTIBYTE_CHARS
352             max_chars = MB_CUR_MAX;
353 #else
354             max_chars = 1;
355 #endif
356           }
357         else
358             max_chars = MAX_LONG_TYPE_SIZE / width;
359
360         ++ptr;
361         while (ptr < tok_end && ((c = *ptr++) != '\''))
362           {
363             if (c == '\\')
364               {
365                 c = cpp_parse_escape (pfile, &ptr);
366                 if (width < HOST_BITS_PER_INT
367                   && (unsigned) c >= (1 << width))
368                     cpp_pedwarn (pfile,
369                                  "escape sequence out of range for character");
370               }
371
372             num_chars++;
373
374             /* Merge character into result; ignore excess chars.  */
375             if (num_chars < max_chars + 1)
376               {
377                 if (width < HOST_BITS_PER_INT)
378                   result = (result << width) | (c & ((1 << width) - 1));
379                 else
380                   result = c;
381                 token_buffer[num_chars - 1] = c;
382               }
383           }
384
385         token_buffer[num_chars] = 0;
386
387         if (c != '\'')
388           cpp_error (pfile, "malformatted character constant");
389         else if (num_chars == 0)
390           cpp_error (pfile, "empty character constant");
391         else if (num_chars > max_chars)
392           {
393             num_chars = max_chars;
394             cpp_error (pfile, "character constant too long");
395           }
396         else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile))
397           cpp_warning (pfile, "multi-character character constant");
398
399         /* If char type is signed, sign-extend the constant.  */
400         if (! wide_flag)
401           {
402             int num_bits = num_chars * width;
403
404             if (cpp_lookup (pfile, "__CHAR_UNSIGNED__",
405                             sizeof ("__CHAR_UNSIGNED__")-1, -1)
406                 || ((result >> (num_bits - 1)) & 1) == 0)
407                 op.value
408                     = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
409             else
410                 op.value
411                     = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits));
412           }
413         else
414           {
415 #ifdef MULTIBYTE_CHARS
416             /* Set the initial shift state and convert the next sequence.  */
417               result = 0;
418               /* In all locales L'\0' is zero and mbtowc will return zero,
419                  so don't use it.  */
420               if (num_chars > 1
421                   || (num_chars == 1 && token_buffer[0] != '\0'))
422                 {
423                   wchar_t wc;
424                   (void) mbtowc (NULL_PTR, NULL_PTR, 0);
425                   if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
426                     result = wc;
427                   else
428                     cpp_warning (pfile,"Ignoring invalid multibyte character");
429                 }
430 #endif
431               op.value = result;
432             }
433         }
434
435       /* This is always a signed type.  */
436       op.unsignedp = 0;
437       op.op = CHAR;
438     
439       return op;
440
441     case CPP_NAME:
442       return parse_number (pfile, "0", 0);
443
444     case CPP_OTHER:
445       /* See if it is a special token of length 2.  */
446       if (tok_start + 2 == tok_end)
447         {
448           for (toktab = tokentab2; toktab->operator != NULL; toktab++)
449             if (tok_start[0] == toktab->operator[0]
450                 && tok_start[1] == toktab->operator[1])
451                 break;
452           if (toktab->token == ERROR)
453             {
454               char *buf = (char *) alloca (40);
455               sprintf (buf, "`%s' not allowed in operand of `#if'", tok_start);
456               cpp_error (pfile, buf);
457             }
458           op.op = toktab->token; 
459           return op;
460         }
461       /* fall through */
462     default:
463       op.op = *tok_start;
464       return op;
465   }
466 }
467
468
469 /* Parse a C escape sequence.  STRING_PTR points to a variable
470    containing a pointer to the string to parse.  That pointer
471    is updated past the characters we use.  The value of the
472    escape sequence is returned.
473
474    A negative value means the sequence \ newline was seen,
475    which is supposed to be equivalent to nothing at all.
476
477    If \ is followed by a null character, we return a negative
478    value and leave the string pointer pointing at the null character.
479
480    If \ is followed by 000, we return 0 and leave the string pointer
481    after the zeros.  A value of 0 does not mean end of string.  */
482
483 int
484 cpp_parse_escape (pfile, string_ptr)
485      cpp_reader *pfile;
486      char **string_ptr;
487 {
488   register int c = *(*string_ptr)++;
489   switch (c)
490     {
491     case 'a':
492       return TARGET_BELL;
493     case 'b':
494       return TARGET_BS;
495     case 'e':
496     case 'E':
497       if (CPP_PEDANTIC (pfile))
498         cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
499       return 033;
500     case 'f':
501       return TARGET_FF;
502     case 'n':
503       return TARGET_NEWLINE;
504     case 'r':
505       return TARGET_CR;
506     case 't':
507       return TARGET_TAB;
508     case 'v':
509       return TARGET_VT;
510     case '\n':
511       return -2;
512     case 0:
513       (*string_ptr)--;
514       return 0;
515       
516     case '0':
517     case '1':
518     case '2':
519     case '3':
520     case '4':
521     case '5':
522     case '6':
523     case '7':
524       {
525         register int i = c - '0';
526         register int count = 0;
527         while (++count < 3)
528           {
529             c = *(*string_ptr)++;
530             if (c >= '0' && c <= '7')
531               i = (i << 3) + c - '0';
532             else
533               {
534                 (*string_ptr)--;
535                 break;
536               }
537           }
538         if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
539           {
540             i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
541             cpp_warning (pfile,
542                           "octal character constant does not fit in a byte");
543           }
544         return i;
545       }
546     case 'x':
547       {
548         register unsigned i = 0, overflow = 0, digits_found = 0, digit;
549         for (;;)
550           {
551             c = *(*string_ptr)++;
552             if (c >= '0' && c <= '9')
553               digit = c - '0';
554             else if (c >= 'a' && c <= 'f')
555               digit = c - 'a' + 10;
556             else if (c >= 'A' && c <= 'F')
557               digit = c - 'A' + 10;
558             else
559               {
560                 (*string_ptr)--;
561                 break;
562               }
563             overflow |= i ^ (i << 4 >> 4);
564             i = (i << 4) + digit;
565             digits_found = 1;
566           }
567         if (!digits_found)
568           cpp_error (pfile, "\\x used with no following hex digits");
569         if (overflow | (i & ~((1 << BITS_PER_UNIT) - 1)))
570           {
571             i &= (1 << BITS_PER_UNIT) - 1;
572             cpp_warning (pfile,
573                          "hex character constant does not fit in a byte");
574           }
575         return i;
576       }
577     default:
578       return c;
579     }
580 }
581
582 static void
583 integer_overflow (pfile)
584      cpp_reader *pfile;
585 {
586   if (CPP_PEDANTIC (pfile))
587     cpp_pedwarn (pfile, "integer overflow in preprocessor expression");
588 }
589
590 static long
591 left_shift (pfile, a, unsignedp, b)
592      cpp_reader *pfile;
593      long a;
594      int unsignedp;
595      unsigned long b;
596 {
597   if (b >= HOST_BITS_PER_LONG)
598     {
599       if (! unsignedp && a != 0)
600         integer_overflow (pfile);
601       return 0;
602     }
603   else if (unsignedp)
604     return (unsigned long) a << b;
605   else
606     {
607       long l = a << b;
608       if (l >> b != a)
609         integer_overflow (pfile);
610       return l;
611     }
612 }
613
614 static long
615 right_shift (pfile, a, unsignedp, b)
616      cpp_reader *pfile;
617      long a;
618      int unsignedp;
619      unsigned long b;
620 {
621   if (b >= HOST_BITS_PER_LONG)
622     return unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1);
623   else if (unsignedp)
624     return (unsigned long) a >> b;
625   else
626     return a >> b;
627 }
628 \f
629 /* These priorities are all even, so we can handle associatively. */
630 #define PAREN_INNER_PRIO 0
631 #define COMMA_PRIO 4
632 #define COND_PRIO (COMMA_PRIO+2)
633 #define OROR_PRIO (COND_PRIO+2)
634 #define ANDAND_PRIO (OROR_PRIO+2)
635 #define OR_PRIO (ANDAND_PRIO+2)
636 #define XOR_PRIO (OR_PRIO+2)
637 #define AND_PRIO (XOR_PRIO+2)
638 #define EQUAL_PRIO (AND_PRIO+2)
639 #define LESS_PRIO (EQUAL_PRIO+2)
640 #define SHIFT_PRIO (LESS_PRIO+2)
641 #define PLUS_PRIO (SHIFT_PRIO+2)
642 #define MUL_PRIO (PLUS_PRIO+2)
643 #define UNARY_PRIO (MUL_PRIO+2)
644 #define PAREN_OUTER_PRIO (UNARY_PRIO+2)
645
646 #define COMPARE(OP) \
647   top->unsignedp = 0;\
648   top->value = (unsigned1 || unsigned2) ? (unsigned long) v1 OP v2 : (v1 OP v2)
649
650 /* Parse and evaluate a C expression, reading from PFILE.
651    Returns the value of the expression.  */
652
653 HOST_WIDE_INT
654 cpp_parse_expr (pfile)
655      cpp_reader *pfile;
656 {
657   /* The implementation is an operator precedence parser,
658      i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
659
660      The stack base is 'stack', and the current stack pointer is 'top'.
661      There is a stack element for each operator (only),
662      and the most recently pushed operator is 'top->op'.
663      An operand (value) is stored in the 'value' field of the stack
664      element of the operator that precedes it.
665      In that case the 'flags' field has the HAVE_VALUE flag set.  */
666
667 #define INIT_STACK_SIZE 20
668   struct operation init_stack[INIT_STACK_SIZE];
669   struct operation *stack = init_stack;
670   struct operation *limit = stack + INIT_STACK_SIZE;
671   register struct operation *top = stack;
672   int lprio, rprio;
673
674   top->rprio = 0;
675   top->flags = 0;
676   for (;;)
677     {
678       struct operation op;
679       char flags = 0;
680
681       /* Read a token */
682       op =  cpp_lex (pfile);
683
684       /* See if the token is an operand, in which case go to set_value.
685          If the token is an operator, figure out its left and right
686          priorities, and then goto maybe_reduce. */
687
688       switch (op.op)
689         {
690         case NAME:
691           top->value = 0, top->unsignedp = 0;
692           goto set_value;
693         case INT:  case CHAR:
694           top->value = op.value;
695           top->unsignedp = op.unsignedp;
696           goto set_value;
697         case 0:
698           lprio = 0;  goto maybe_reduce;
699         case '+':  case '-':
700           /* Is this correct if unary ? FIXME */
701           flags = RIGHT_OPERAND_REQUIRED;
702           lprio = PLUS_PRIO;  rprio = lprio + 1;  goto maybe_reduce;
703         case '!':  case '~':
704           flags = RIGHT_OPERAND_REQUIRED;
705           rprio = UNARY_PRIO;  lprio = rprio + 1;  goto maybe_reduce;
706         case '*':  case '/':  case '%':
707           lprio = MUL_PRIO;  goto binop;
708         case '<':  case '>':  case LEQ:  case GEQ:
709           lprio = LESS_PRIO;  goto binop;
710         case EQUAL:  case NOTEQUAL:
711           lprio = EQUAL_PRIO;  goto binop;
712         case LSH:  case RSH:
713           lprio = SHIFT_PRIO;  goto binop;
714         case '&':  lprio = AND_PRIO;  goto binop;
715         case '^':  lprio = XOR_PRIO;  goto binop;
716         case '|':  lprio = OR_PRIO;  goto binop;
717         case ANDAND:  lprio = ANDAND_PRIO;  goto binop;
718         case OROR:  lprio = OROR_PRIO;  goto binop;
719         case ',':
720           lprio = COMMA_PRIO;  goto binop;
721         case '(':
722           lprio = PAREN_OUTER_PRIO;  rprio = PAREN_INNER_PRIO;
723           goto maybe_reduce;
724         case ')':
725           lprio = PAREN_INNER_PRIO;  rprio = PAREN_OUTER_PRIO;
726           goto maybe_reduce;
727         case ':':
728           lprio = COND_PRIO;  rprio = COND_PRIO;
729           goto maybe_reduce;
730         case '?':
731           lprio = COND_PRIO + 1;  rprio = COND_PRIO;
732           goto maybe_reduce;
733         binop:
734           flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
735           rprio = lprio + 1;
736           goto maybe_reduce;
737         default:
738           cpp_error (pfile, "invalid character in #if");
739           goto syntax_error;
740         }
741
742     set_value:
743       /* Push a value onto the stack. */
744       if (top->flags & HAVE_VALUE)
745         {
746           cpp_error (pfile, "syntax error in #if");
747           goto syntax_error;
748         }
749       top->flags |= HAVE_VALUE;
750       continue;
751
752     maybe_reduce:
753       /* Push an operator, and check if we can reduce now. */
754       while (top->rprio > lprio)
755         {
756           long v1 = top[-1].value, v2 = top[0].value;
757           int unsigned1 = top[-1].unsignedp, unsigned2 = top[0].unsignedp;
758           top--;
759           if ((top[1].flags & LEFT_OPERAND_REQUIRED)
760               && ! (top[0].flags & HAVE_VALUE))
761             {
762               cpp_error (pfile, "syntax error - missing left operand");
763               goto syntax_error;
764             }
765           if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
766               && ! (top[1].flags & HAVE_VALUE))
767             {
768               cpp_error (pfile, "syntax error - missing right operand");
769               goto syntax_error;
770             }
771           /* top[0].value = (top[1].op)(v1, v2);*/
772           switch (top[1].op)
773             {
774             case '+':
775               if (!(top->flags & HAVE_VALUE))
776                 { /* Unary '+' */
777                   top->value = v2;
778                   top->unsignedp = unsigned2;
779                   top->flags |= HAVE_VALUE;
780                 }
781               else
782                 {
783                   top->value = v1 + v2;
784                   top->unsignedp = unsigned1 || unsigned2;
785                   if (! top->unsignedp
786                       && ! possible_sum_sign (v1, v2, top->value))
787                     integer_overflow (pfile);
788                 }
789               break;
790             case '-':
791               if (!(top->flags & HAVE_VALUE))
792                 { /* Unary '-' */
793                   top->value = - v2;
794                   if ((top->value & v2) < 0 && ! unsigned2)
795                     integer_overflow (pfile);
796                   top->unsignedp = unsigned2;
797                   top->flags |= HAVE_VALUE;
798                 }
799               else
800                 { /* Binary '-' */
801                   top->value = v1 - v2;
802                   top->unsignedp = unsigned1 || unsigned2;
803                   if (! top->unsignedp
804                       && ! possible_sum_sign (top->value, v2, v1))
805                     integer_overflow (pfile);
806                 }
807               break;
808             case '*':
809               top->unsignedp = unsigned1 || unsigned2;
810               if (top->unsignedp)
811                 top->value = (unsigned long) v1 * v2;
812               else
813                 {
814                   top->value = v1 * v2;
815                   if (v1
816                       && (top->value / v1 != v2
817                           || (top->value & v1 & v2) < 0))
818                     integer_overflow (pfile);
819                 }
820               break;
821             case '/':
822               if (v2 == 0)
823                 {
824                   cpp_error (pfile, "division by zero in #if");
825                   v2 = 1;
826                 }
827               top->unsignedp = unsigned1 || unsigned2;
828               if (top->unsignedp)
829                 top->value = (unsigned long) v1 / v2;
830               else
831                 {
832                   top->value = v1 / v2;
833                   if ((top->value & v1 & v2) < 0)
834                     integer_overflow (pfile);
835                 }
836               break;
837             case '%':
838               if (v2 == 0)
839                 {
840                   cpp_error (pfile, "division by zero in #if");
841                   v2 = 1;
842                 }
843               top->unsignedp = unsigned1 || unsigned2;
844               if (top->unsignedp)
845                 top->value = (unsigned long) v1 % v2;
846               else
847                 top->value = v1 % v2;
848               break;
849             case '!':
850               if (top->flags & HAVE_VALUE)
851                 {
852                   cpp_error (pfile, "syntax error");
853                   goto syntax_error;
854                 }
855               top->value = ! v2;
856               top->unsignedp = 0;
857               top->flags |= HAVE_VALUE;
858               break;
859             case '~':
860               if (top->flags & HAVE_VALUE)
861                 {
862                   cpp_error (pfile, "syntax error");
863                   goto syntax_error;
864                 }
865               top->value = ~ v2;
866               top->unsignedp = unsigned2;
867               top->flags |= HAVE_VALUE;
868               break;
869             case '<':  COMPARE(<);  break;
870             case '>':  COMPARE(>);  break;
871             case LEQ:  COMPARE(<=); break;
872             case GEQ:  COMPARE(>=); break;
873             case EQUAL:
874               top->value = (v1 == v2);
875               top->unsignedp = 0;
876               break;
877             case NOTEQUAL:
878               top->value = (v1 != v2);
879               top->unsignedp = 0;
880               break;
881             case LSH:
882               top->unsignedp = unsigned1;
883               if (v2 < 0 && ! unsigned2)
884                 top->value = right_shift (pfile, v1, unsigned1, -v2);
885               else
886                 top->value = left_shift (pfile, v1, unsigned1, v2);
887               break;
888             case RSH:
889               top->unsignedp = unsigned1;
890               if (v2 < 0 && ! unsigned2)
891                 top->value = left_shift (pfile, v1, unsigned1, -v2);
892               else
893                 top->value = right_shift (pfile, v1, unsigned1, v2);
894               break;
895 #define LOGICAL(OP) \
896               top->value = v1 OP v2;\
897               top->unsignedp = unsigned1 || unsigned2;
898             case '&':  LOGICAL(&); break;
899             case '^':  LOGICAL(^);  break;
900             case '|':  LOGICAL(|);  break;
901             case ANDAND:
902               top->value = v1 && v2;  top->unsignedp = 0;  break;
903             case OROR:
904               top->value = v1 || v2;  top->unsignedp = 0;  break;
905             case ',':
906               if (CPP_PEDANTIC (pfile))
907                 cpp_pedwarn (pfile, "comma operator in operand of `#if'");
908               top->value = v2;
909               top->unsignedp = unsigned2;
910               break;
911             case '(':  case '?':
912               cpp_error (pfile, "syntax error in #if");
913               goto syntax_error;
914             case ':':
915               if (top[0].op != '?')
916                 {
917                   cpp_error (pfile,
918                              "syntax error ':' without preceding '?'");
919                   goto syntax_error;
920                 }
921               else if (! (top[1].flags & HAVE_VALUE)
922                        || !(top[-1].flags & HAVE_VALUE)
923                        || !(top[0].flags & HAVE_VALUE))
924                 {
925                   cpp_error (pfile, "bad syntax for ?: operator");
926                   goto syntax_error;
927                 }
928               else
929                 {
930                   top--;
931                   top->value = top->value ? v1 : v2;
932                   top->unsignedp = unsigned1 || unsigned2;
933                 }
934               break;
935             case ')':
936               if ((top[1].flags & HAVE_VALUE)
937                   || ! (top[0].flags & HAVE_VALUE)
938                   || top[0].op != '('
939                   || (top[-1].flags & HAVE_VALUE))
940                 {
941                   cpp_error (pfile, "mismatched parentheses in #if");
942                   goto syntax_error;
943                 }
944               else
945                 {
946                   top--;
947                   top->value = v1;
948                   top->unsignedp = unsigned1;
949                   top->flags |= HAVE_VALUE;
950                 }
951               break;
952             default:
953               fprintf (stderr,
954                        top[1].op >= ' ' && top[1].op <= '~'
955                        ? "unimplemented operator '%c'\n"
956                        : "unimplemented operator '\\%03o'\n",
957                        top[1].op);
958             }
959         }
960       if (op.op == 0)
961         {
962           if (top != stack)
963             cpp_error (pfile, "internal error in #if expression");
964           if (stack != init_stack)
965             free (stack);
966           return top->value;
967         }
968       top++;
969       
970       /* Check for and handle stack overflow. */
971       if (top == limit)
972         {
973           struct operation *new_stack;
974           int old_size = (char*)limit - (char*)stack;
975           int new_size = 2 * old_size;
976           if (stack != init_stack)
977             new_stack = (struct operation*) xrealloc (stack, new_size);
978           else
979             {
980               new_stack = (struct operation*) xmalloc (new_size);
981               bcopy ((char *) stack, (char *) new_stack, old_size);
982             }
983           stack = new_stack;
984           top = (struct operation*)((char*) new_stack + old_size);
985           limit = (struct operation*)((char*) new_stack + new_size);
986         }
987       
988       top->flags = flags;
989       top->rprio = rprio;
990       top->op = op.op;
991     }
992  syntax_error:
993   if (stack != init_stack)
994     free (stack);
995   skip_rest_of_line (pfile);
996   return 0;
997 }