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