]> andersk Git - splint.git/blame - src/cppexp.c
Fixed internal bug reporting for redefinition of __func__
[splint.git] / src / cppexp.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
6** This program is free software; you can redistribute it and/or modify it
7** under the terms of the GNU General Public License as published by the
8** Free Software Foundation; either version 2 of the License, or (at your
9** option) any later version.
10**
11** This program is distributed in the hope that it will be useful, but
12** WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14** General Public License for more details.
15**
16** The GNU General Public License is available from http://www.gnu.org/ or
17** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18** MA 02111-1307, USA.
19**
155af98d 20** For information on splint: info@splint.org
21** To report a bug: splint-bug@splint.org
11db3170 22** For more information: http://www.splint.org
616915dd 23*/
24/*
25** cppexp.c
26*/
27/* Parse C expressions for CCCP.
28 Copyright (C) 1987, 1992, 1994, 1995, 1997 Free Software Foundation.
29
30This program is free software; you can redistribute it and/or modify it
31under the terms of the GNU General Public License as published by the
32Free Software Foundation; either version 2, or (at your option) any
33later version.
34
35This program is distributed in the hope that it will be useful,
36but WITHOUT ANY WARRANTY; without even the implied warranty of
37MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38GNU General Public License for more details.
39
40You should have received a copy of the GNU General Public License
41along with this program; if not, write to the Free Software
42Foundation, 59 Temple Place - Suite 330,
43Boston, MA 02111-1307, USA.
44
45 In other words, you are welcome to use, share and improve this program.
46 You are forbidden to forbid anyone else to use, share and improve
47 what you give them. Help stamp out software-hoarding!
48
49Written by Per Bothner 1994. */
50
51/* Parse a C expression from text in a string */
52
53/*@+charint@*/
54/*@+ignorequals@*/
55/*@+ignoresigns@*/
56/*@+matchanyintegral@*/
616915dd 57
58# include <string.h>
1b8ae690 59# include "splintMacros.nf"
b73d1009 60# include "basic.h"
616915dd 61# include "cpplib.h"
62# include "cpphash.h"
63# include "cppexp.h"
64# include "cpperror.h"
65
66/* Yield nonzero if adding two numbers with A's and B's signs can yield a
67 number with SUM's sign, where A, B, and SUM are all C integers. */
68
69/*@function static bool possibleSumSign (sef int, int, int)
70 modifies nothing ; @*/
71
72#define possibleSumSign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
73
74/* these are guesses! */
75
a956d444 76/*@constant int BITS_PER_UNIT = 8@*/
616915dd 77# define BITS_PER_UNIT 8
78
79/*@constant size_t BITS_PER_CHAR@*/
80# define BITS_PER_CHAR 8
81
82/*@constant size_t BITS_PER_WORD@*/
83# define BITS_PER_WORD 32
84
85/*@constant size_t HOST_BITS_PER_INT@*/
86# define HOST_BITS_PER_INT 32
87
a956d444 88/*@constant size_t HOST_BITS_PER_LONG = 32@*/
616915dd 89# define HOST_BITS_PER_LONG 32
90
91/*@constant char TARGET_BELL@*/
92# define TARGET_BELL (char) 6
93
94/*@constant char TARGET_BS@*/
95# define TARGET_BS (char) 7
96
97/*@constant char TARGET_FF@*/
98# define TARGET_FF (char) 8
99
100/*@constant char TARGET_NEWLINE@*/
101# define TARGET_NEWLINE '\n'
102
103/*@constant char TARGET_CR@*/
104# define TARGET_CR '\n'
105
106/*@constant char TARGET_TAB@*/
107# define TARGET_TAB '\t'
108
109/*@constant char TARGET_VT@*/
110# define TARGET_VT '\v'
111
112#ifdef MULTIBYTE_CHARS
113#include <stdlib.h>
114#include <locale.h>
115#endif
116
117#include <stdio.h>
118
119#ifndef INT_TYPE_SIZE
120/*@constant size_t INT_TYPE_SIZE@*/
121#define INT_TYPE_SIZE BITS_PER_WORD
122#endif
123
124#ifndef LONG_TYPE_SIZE
125/*@constant size_t LONG_TYPE_SIZE@*/
126#define LONG_TYPE_SIZE BITS_PER_WORD
127#endif
128
129#ifndef WCHAR_TYPE_SIZE
130/*@constant size_t WCHAR_TYPE_SIZE@*/
131#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
132#endif
133
134# ifndef CHAR_TYPE_SIZE
135/*@constant size_t CHAR_TYPE_SIZE@*/
136# define CHAR_TYPE_SIZE BITS_PER_CHAR
137# endif
138
139#ifndef MAX_CHAR_TYPE_SIZE
140/*@constant size_t MAX_CHAR_TYPE_SIZE@*/
141#define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE
142#endif
143
144#ifndef MAX_LONG_TYPE_SIZE
145/*@constant size_t MAX_LONG_TYPE_SIZE@*/
146#define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE
147#endif
148
149#ifndef MAX_WCHAR_TYPE_SIZE
150/*@constant size_t MAX_WCHAR_TYPE_SIZE@*/
151#define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
152#endif
153
3e3ec469 154static struct operation cppexp_lex (cppReader *);
616915dd 155static void integer_overflow (cppReader *);
c3be2604 156static long left_shift (cppReader *, long, bool p_unsignedp, unsigned long);
616915dd 157static long right_shift (long, bool p_unsignedp, unsigned long);
158
159/*@constant short CPPREADER_ERRORTOK@*/
160#define CPPREADER_ERRORTOK 299
161
162/*@constant int OROR@*/
163#define OROR 300
164
165/*@constant int ANDAND@*/
166#define ANDAND 301
167
168/*@constant int CPP_EQUALTOK@*/
169#define CPP_EQUALTOK 302
170
171/*@constant int NOTEQUAL@*/
172#define NOTEQUAL 303
173
174/*@constant int LEQ@*/
175#define LEQ 304
176
177/*@constant int GEQ@*/
178#define GEQ 305
179
180/*@constant int LSH@*/
181#define LSH 306
182
183/*@constant int RSH@*/
184#define RSH 307
185
186/*@constant int NAME@*/
187#define NAME 308
188
189/*@constant short CPPEXP_INT@*/
190#define CPPEXP_INT 309
191
192/*@constant short CPPEXP_CHAR@*/
193#define CPPEXP_CHAR 310
194
195/*@constant int LEFT_OPERAND_REQUIRED@*/
196#define LEFT_OPERAND_REQUIRED 1
197
198/*@constant int RIGHT_OPERAND_REQUIRED@*/
199#define RIGHT_OPERAND_REQUIRED 2
200
201/*@constant int HAVE_VALUE@*/
202#define HAVE_VALUE 4
203
204#ifndef HOST_BITS_PER_WIDE_INT
205
206#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
207/*@constant int HOST_BITS_PER_WIDE_INT@*/
208#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
209/*@notfunction@*/
210#define HOST_WIDE_INT long
211#else
212/*@constant int HOST_BITS_PER_WIDE_INT@*/
213#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
214/*@notfunction@*/
215#define HOST_WIDE_INT long
216#endif
217
218#endif
219
220struct operation {
221 short op;
222
223 /* Priority of op (relative to it right operand). */
224 /*@reldef@*/ char rprio;
225
226 /*@reldef@*/ char flags;
227
228 /* true if value should be treated as unsigned */
229 /*@reldef@*/ bool unsignedp;
230
231 /* The value logically "right" of op. */
232 /*@reldef@*/ HOST_WIDE_INT value;
233} ;
234
235/* Take care of parsing a number (anything that starts with a digit).
236 LEN is the number of characters in it. */
237
238/* maybe needs to actually deal with floating point numbers */
239
240struct operation
86d93ed3 241cppReader_parseNumber (cppReader *pfile, char *start, int olen) /*@requires maxRead(start) >= (olen - 1) @*/
616915dd 242{
243 struct operation op;
244 char *p = start;
245 char c;
246 int i;
247 long n = 0;
248 unsigned long nd, ULONG_MAX_over_base;
249 int base = 10;
250 int len = olen;
251 bool overflow = FALSE;
252 int digit, largest_digit = 0;
253 bool spec_long = FALSE;
254
255 op.unsignedp = FALSE;
256
257 for (i = 0; i < len; i++)
258 {
8fd556fb 259 if (p[i] == '.') {
616915dd 260 /* It's a float since it contains a point. */
261 cppReader_errorLit
262 (pfile,
263 cstring_makeLiteralTemp
264 ("Floating point numbers not allowed in #if expressions"));
265 op.op = CPPREADER_ERRORTOK;
266 return op;
267 }
268 }
269
270 if (len >= 3 && (mstring_equalPrefix (p, "0x")
271 || mstring_equalPrefix (p, "0X")))
272 {
273 p += 2;
274 base = 16;
275 len -= 2;
276 }
277 else if (*p == '0')
278 {
279 base = 8;
280 }
281 else
282 {
283 ;
284 }
285
286 /* Some buggy compilers (e.g. MPW C) seem to need both casts. */
287 ULONG_MAX_over_base = ((unsigned long) -1) / ((unsigned long) base);
288
289 for (; len > 0; len--) {
290 c = *p++;
291
292 if (c >= '0' && c <= '9')
293 {
294 digit = (int) (c - '0');
295 }
296 else if (base == 16 && c >= 'a' && c <= 'f')
297 {
298 digit = (int) (c - 'a') + 10;
299 }
300 else if (base == 16 && c >= 'A' && c <= 'F')
301 {
302 digit = (int) (c - 'A') + 10;
303 }
304 else
305 {
306 /* `l' means long, and `u' means unsigned. */
307 while (TRUE)
308 {
309 if (c == 'l' || c == 'L')
310 {
311 if (spec_long)
312 cppReader_errorLit (pfile,
313 cstring_makeLiteralTemp ("two `l's in integer constant"));
314 spec_long = TRUE;
315 }
316 else if (c == 'u' || c == 'U')
317 {
318 if (op.unsignedp)
319 cppReader_errorLit (pfile,
320 cstring_makeLiteralTemp ("two `u's in integer constant"));
321 op.unsignedp = TRUE;
322 }
323 else
324 {
325 /*@innerbreak@*/ break;
326 }
327
328 if (--len == 0)
329 {
330 /*@innerbreak@*/ break;
331 }
332
8fd556fb 333 c = *p++;
616915dd 334 }
335 /* Don't look for any more digits after the suffixes. */
336 break;
337 }
338
339 if (largest_digit < digit)
340 {
341 largest_digit = digit;
342 }
343
344 nd = (long unsigned) (n * base + digit);
345 overflow |= (ULONG_MAX_over_base < (unsigned long) n)
346 | (nd < (unsigned long) n);
347 n = (long) nd;
348 }
349
350 if (len != 0)
351 {
352 cppReader_errorLit
353 (pfile,
354 cstring_makeLiteralTemp ("Invalid number in #if expression"));
355 op.op = CPPREADER_ERRORTOK;
356 return op;
357 }
358
359 if (base <= largest_digit)
360 {
361 cppReader_pedwarnLit
362 (pfile,
363 cstring_makeLiteralTemp
364 ("Integer constant contains digits beyond the radix"));
365 }
366
367 if (overflow)
368 {
369 cppReader_pedwarnLit
370 (pfile,
371 cstring_makeLiteralTemp ("Integer constant out of range"));
372 }
373
374 /* If too big to be signed, consider it unsigned. */
375 if ((long) n < 0 && ! op.unsignedp)
376 {
377 if (base == 10)
378 {
379 cppReader_warningLit
380 (pfile,
381 cstring_makeLiteralTemp ("Integer constant is so large that it is unsigned"));
382 }
383
384 op.unsignedp = TRUE;
385 }
386
387 op.value = n;
388 op.op = CPPEXP_INT;
3e3ec469 389 DPRINTF (("Parse number: %d", op.value));
616915dd 390 return op;
391}
392
393struct token {
394 /*@null@*/ /*@observer@*/ char *operator;
395 int token;
396};
397
398static struct token tokentab2[] = {
399 { "&&", ANDAND },
400 { "||", OROR },
401 { "<<", LSH },
402 { ">>", RSH },
403 { "==", CPP_EQUALTOK },
404 { "!=", NOTEQUAL },
405 { "<=", LEQ },
406 { ">=", GEQ },
407 { "++", CPPREADER_ERRORTOK },
408 { "--", CPPREADER_ERRORTOK },
409 { NULL, CPPREADER_ERRORTOK }
410} ;
411
412/* Read one token. */
413
3e3ec469 414struct operation cppexp_lex (cppReader *pfile)
616915dd 415{
416 int ic;
417 char c;
418 register struct token *toktab;
419 enum cpp_token token;
420 struct operation op;
421 char *tok_start, *tok_end;
422 int old_written;
423
424 retry:
3e3ec469 425
426 old_written = size_toInt (cpplib_getWritten (pfile));
616915dd 427 cppSkipHspace (pfile);
3e3ec469 428 ic = cpplib_bufPeek (cppReader_getBufferSafe (pfile));
616915dd 429
430 c = (char) ic;
abd7f895 431
432 if (c == '#')
433 {
434 /* was: llassert (c != '#'); - Solaris uses this, attempt to continue anyway... */
435 cppReader_pedwarn (pfile,
436 message ("non-standard pre-processor directive: %c", c));
437 }
438
3e3ec469 439 DPRINTF (("Read: %c", c));
440
616915dd 441 if (c == '\n')
442 {
443 op.op = 0;
444 return op;
445 }
446
3e3ec469 447 token = cpplib_getTokenForceExpand (pfile);
448
616915dd 449 tok_start = pfile->token_buffer + old_written;
3e3ec469 450 tok_end = cpplib_getPWritten (pfile);
451
452 DPRINTF (("Token: %s < %s", tok_start, tok_end));
453
616915dd 454 pfile->limit = tok_start;
455
456 switch (token)
3e3ec469 457 {
616915dd 458 case CPP_EOF: /* Should not happen ... */
459 case CPP_VSPACE:
460 op.op = 0;
461 return op;
462 case CPP_POP:
463 if (cstring_isDefined (cppReader_getBufferSafe (pfile)->fname))
464 {
465 op.op = 0;
466 return op;
467 }
468 (void) cppReader_popBuffer (pfile);
469 goto retry;
470 case CPP_HSPACE: case CPP_COMMENT:
471 goto retry;
472 case CPP_NUMBER:
473 return cppReader_parseNumber (pfile, tok_start, tok_end - tok_start);
474 case CPP_STRING:
475 cppReader_errorLit (pfile,
3e3ec469 476 cstring_makeLiteralTemp ("string constants not allowed in #if expressions"));
616915dd 477 op.op = CPPREADER_ERRORTOK;
478 return op;
479 case CPP_CHAR:
480 /* This code for reading a character constant
481 handles multicharacter constants and wide characters.
482 It is mostly copied from c-lex.c. */
483 {
484 int result = 0;
485 int num_chars = 0;
486 size_t width = MAX_CHAR_TYPE_SIZE;
487 int wide_flag = 0;
488 int max_chars;
489 char *ptr = tok_start;
490#ifdef MULTIBYTE_CHARS
491 char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + MB_CUR_MAX];
492#else
493 char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1];
494#endif
3e3ec469 495
616915dd 496 if (*ptr == 'L')
497 {
498 ptr++;
499 wide_flag = 1;
500 width = MAX_WCHAR_TYPE_SIZE;
501#ifdef MULTIBYTE_CHARS
502 max_chars = MB_CUR_MAX;
503#else
504 max_chars = 1;
505#endif
506 }
507 else
508 {
509 max_chars = size_toInt (MAX_LONG_TYPE_SIZE / width);
510 }
3e3ec469 511
616915dd 512 ++ptr;
8fd556fb 513 while (ptr < tok_end && ((c = *ptr++) != '\''))
616915dd 514 {
515 if (c == '\\')
516 {
517 c = cppReader_parseEscape (pfile, &ptr);
518 if (width < HOST_BITS_PER_INT && c >= (1 << width))
519 {
520 cppReader_pedwarnLit
521 (pfile,
522 cstring_makeLiteralTemp ("Escape sequence out of range for character"));
523 }
524 }
525
526 num_chars++;
527
528 /* Merge character into result; ignore excess chars. */
529 if (num_chars < max_chars + 1)
530 {
531 if (width < HOST_BITS_PER_INT)
532 {
533 result = (int) ((unsigned) result << width) | (c & ((1 << width) - 1));
534 }
535 else
536 {
537 result = c;
538 }
539
540 token_buffer[num_chars - 1] = c;
541 }
542 }
543
8fd556fb 544 token_buffer[num_chars] = 0;
616915dd 545
546 if (c != '\'')
547 cppReader_errorLit (pfile,
80489f0a 548 cstring_makeLiteralTemp ("malformatted character constant"));
616915dd 549 else if (num_chars == 0)
550 cppReader_errorLit (pfile,
80489f0a 551 cstring_makeLiteralTemp ("empty character constant"));
616915dd 552 else if (num_chars > max_chars)
553 {
554 num_chars = max_chars;
555 cppReader_errorLit (pfile,
80489f0a 556 cstring_makeLiteralTemp ("character constant too long"));
616915dd 557 }
558 else if (num_chars != 1 && ! cppReader_isTraditional (pfile))
559 {
560 cppReader_warningLit (pfile,
80489f0a 561 cstring_makeLiteralTemp ("multi-character character constant"));
616915dd 562 }
563 else
564 {
565 ;
566 }
567
568 /* If char type is signed, sign-extend the constant. */
569 if (wide_flag == 0)
570 {
571 int num_bits = num_chars * width;
572
3e3ec469 573 if ((cpphash_lookup ("__CHAR_UNSIGNED__",
616915dd 574 sizeof ("__CHAR_UNSIGNED__") - 1, -1) != NULL)
a956d444 575 || (((unsigned) result >> (int_toNonNegative (num_bits - 1))) & 1) == 0)
616915dd 576 {
577 op.value
a956d444 578 = result & ((unsigned long) ~0
579 >> int_toNonNegative ((HOST_BITS_PER_LONG - num_bits)));
616915dd 580 }
581 else
582 {
583 op.value
a956d444 584 = result | ~((unsigned long) ~0
585 >> int_toNonNegative ((HOST_BITS_PER_LONG - num_bits)));
616915dd 586 }
587 }
588 else
589 {
590#ifdef MULTIBYTE_CHARS
591 /* Set the initial shift state and convert the next sequence. */
592 result = 0;
593 /* In all locales L'\0' is zero and mbtowc will return zero,
594 so don't use it. */
595 if (num_chars > 1
596 || (num_chars == 1 && token_buffer[0] != '\0'))
597 {
598 wchar_t wc;
599 (void) mbtowc (NULL, NULL, 0);
600 if (mbtowc (& wc, token_buffer, num_chars) == num_chars)
601 result = wc;
602 else
603 cppReader_pedwarn (pfile,"Ignoring invalid multibyte character");
604 }
605#endif
606 op.value = result;
607 }
608 }
609
610 /* This is always a signed type. */
611 op.unsignedp = FALSE;
612 op.op = CPPEXP_CHAR;
613
614 return op;
615
616 case CPP_NAME:
3e3ec469 617 DPRINTF (("Name!"));
616915dd 618 return cppReader_parseNumber (pfile, "0", 0);
619
620 case CPP_OTHER:
621 /* See if it is a special token of length 2. */
622 if (tok_start + 2 == tok_end)
623 {
624 for (toktab = tokentab2; toktab->operator != NULL; toktab++)
625 {
8fd556fb 626 if (tok_start[0] == toktab->operator[0] &&
627 tok_start[1] == toktab->operator[1])
616915dd 628 {
629 /*@loopbreak@*/ break;
630 }
631 }
632
633 if (toktab->token == CPPREADER_ERRORTOK)
634 {
80489f0a 635 cppReader_error (pfile,
636 message ("`%s' not allowed in operand of `#if'",
637 cstring_fromChars (tok_start)));
616915dd 638 }
639
640 op.op = toktab->token;
641 return op;
642 }
643 /*@fallthrough@*/
644 default:
645 op.op = *tok_start;
646 return op;
647 }
648
649 BADEXIT;
650 /*@notreached@*/
651}
652
653
654/* Parse a C escape sequence. STRING_PTR points to a variable
655 containing a pointer to the string to parse. That pointer
656 is updated past the characters we use. The value of the
657 escape sequence is returned.
658
659 A negative value means the sequence \ newline was seen,
660 which is supposed to be equivalent to nothing at all.
661
662 If \ is followed by a null character, we return a negative
663 value and leave the string pointer pointing at the null character.
664
665 If \ is followed by 000, we return 0 and leave the string pointer
666 after the zeros. A value of 0 does not mean end of string. */
667
668int
669cppReader_parseEscape (cppReader *pfile, char **string_ptr)
670{
8fd556fb 671 char c = *(*string_ptr)++;
616915dd 672
673 switch (c)
674 {
675 case 'a':
676 return TARGET_BELL;
677 case 'b':
678 return TARGET_BS;
679 case 'e':
680 case 'E':
681 if (cppReader_isPedantic (pfile))
682 {
683 cppReader_pedwarn (pfile,
155af98d 684 message ("non-standard escape sequence, `\\%c'", c));
616915dd 685 }
686 return (char) 033;
687 case 'f':
688 return TARGET_FF;
689 case 'n':
690 return TARGET_NEWLINE;
691 case 'r':
692 return TARGET_CR;
693 case 't':
694 return TARGET_TAB;
695 case 'v':
696 return TARGET_VT;
697 case '\n':
698 return -2;
699 case 0:
700 (*string_ptr)--;
701 return 0;
702
703 case '0':
704 case '1':
705 case '2':
706 case '3':
707 case '4':
708 case '5':
709 case '6':
710 case '7':
711 {
712 int i = (int) c - '0';
713 int count = 0;
714
715 while (++count < 3)
716 {
717 c = *(*string_ptr)++;
718 if (c >= '0' && c <= '7')
719 {
720 i = ((unsigned) i << 3) + c - '0';
721 }
722
723 else
724 {
8fd556fb 725 (*string_ptr)--;
616915dd 726 /*@loopbreak@*/ break;
727 }
728 }
729 if ((i & ~((1 << MAX_CHAR_TYPE_SIZE) - 1)) != 0)
730 {
731 i &= (1 << MAX_CHAR_TYPE_SIZE) - 1;
732 cppReader_pedwarnLit (pfile,
733 cstring_makeLiteralTemp ("octal character constant does not fit in a byte"));
734 }
735 return i;
736 }
737 case 'x':
738 {
739 register unsigned i = 0, overflow = 0, digits_found = 0, digit;
740 for (;;)
741 {
742 c = *(*string_ptr)++;
743
744 if (c >= '0' && c <= '9')
745 {
746 digit = (unsigned int) (c - '0');
747 }
748 else if (c >= 'a' && c <= 'f')
749 {
750 digit = (unsigned int) (c - 'a') + 10;
751 }
752 else if (c >= 'A' && c <= 'F')
753 {
754 digit = (unsigned int) (c - 'A') + 10;
755 }
756 else
757 {
758 (*string_ptr)--;
759 /*@loopbreak@*/ break;
760 }
761 overflow |= i ^ (i << 4 >> 4);
762 i = (i << 4) + digit;
763 digits_found = 1;
764 }
765
766 if (digits_found == 0)
767 {
768 cppReader_errorLit (pfile,
769 cstring_makeLiteralTemp ("\\x used with no following hex digits"));
770 }
771
a956d444 772 if ((overflow | (i & ~((1 << int_toNonNegative (BITS_PER_UNIT)) - 1))) != 0)
616915dd 773 {
774 i &= (1 << BITS_PER_UNIT) - 1;
775 cppReader_pedwarnLit (pfile,
776 cstring_makeLiteralTemp ("hex character constant does not fit in a byte"));
777 }
778
779 return i;
780 }
781 default:
782 return c;
783 }
784}
785
786static void
787integer_overflow (cppReader *pfile)
788{
789 if (cppReader_isPedantic (pfile))
790 cppReader_pedwarnLit (pfile,
791 cstring_makeLiteralTemp ("integer overflow in preprocessor expression"));
792}
793
794static long
c3be2604 795left_shift (cppReader *pfile, long a, bool unsignedp, unsigned long b)
616915dd 796{
797 if (b >= HOST_BITS_PER_LONG)
798 {
799 if (!unsignedp && a != 0)
800 {
801 integer_overflow (pfile);
802 }
803
804 return 0;
805 }
806 else if (unsignedp)
807 {
808 return (unsigned long) a << b;
809 }
810 else
811 {
a956d444 812 long l = int_toNonNegative (a) << b;
4dd72714 813
814# ifdef WIN32
815# pragma warning( disable : 4018 )
816# endif
817
a956d444 818 if (int_toNonNegative (l) >> b != a)
616915dd 819 {
820 integer_overflow (pfile);
821 }
822
823 return l;
824 }
825}
826
827static long
828right_shift (long a, bool unsignedp, unsigned long b)
829{
830 if (b >= HOST_BITS_PER_LONG)
a956d444 831 return (unsignedp ? 0 : int_toNonNegative (a) >> (HOST_BITS_PER_LONG - 1));
616915dd 832 else if (unsignedp)
833 return (unsigned long) a >> b;
834 else
a956d444 835 return int_toNonNegative (a) >> b;
616915dd 836}
837
838/* These priorities are all even, so we can handle associatively. */
839
840/*@constant int PAREN_INNER_PRIO@*/
841#define PAREN_INNER_PRIO 0
842
843/*@constant int COMMA_PRIO@*/
844#define COMMA_PRIO 4
845
846/*@constant int COND_PRIO@*/
847#define COND_PRIO (COMMA_PRIO+2)
848
849/*@constant int OROR_PRIO@*/
850#define OROR_PRIO (COND_PRIO+2)
851
852/*@constant int ANDAND_PRIO@*/
853#define ANDAND_PRIO (OROR_PRIO+2)
854
855/*@constant int OR_PRIO@*/
856#define OR_PRIO (ANDAND_PRIO+2)
857
858/*@constant int XOR_PRIO@*/
859#define XOR_PRIO (OR_PRIO+2)
860
861/*@constant int AND_PRIO@*/
862#define AND_PRIO (XOR_PRIO+2)
863
864/*@constant int CPP_EQUAL_PRIO@*/
865#define CPP_EQUAL_PRIO (AND_PRIO+2)
866
867/*@constant int LESS_PRIO@*/
868#define LESS_PRIO (CPP_EQUAL_PRIO+2)
869
870/*@constant int SHIFT_PRIO@*/
871#define SHIFT_PRIO (LESS_PRIO+2)
872
873/*@constant int PLUS_PRIO@*/
874#define PLUS_PRIO (SHIFT_PRIO+2)
875
876/*@constant int MUL_PRIO@*/
877#define MUL_PRIO (PLUS_PRIO+2)
878
879/*@constant int UNARY_PRIO@*/
880#define UNARY_PRIO (MUL_PRIO+2)
881
882/*@constant int PAREN_OUTER_PRIO@*/
883#define PAREN_OUTER_PRIO (UNARY_PRIO+2)
884
885/*@notfunction@*/
886#define COMPARE(OP) \
887 top->unsignedp = FALSE;\
888 top->value = ((unsigned1 || unsigned2) \
889 ? (unsigned long) v1 OP (unsigned long) v2 \
890 : ((long) v1 OP (long) v2)) ? 1 : 0
891
892/* Parse and evaluate a C expression, reading from PFILE.
893 Returns the value of the expression. */
894
895/*@constant int INIT_STACK_SIZE@*/
896# define INIT_STACK_SIZE 20
897
898HOST_WIDE_INT
899cppReader_parseExpression (cppReader *pfile)
900{
901 /* The implementation is an operator precedence parser,
902 i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
903
904 The stack base is 'stack', and the current stack pointer is 'top'.
905 There is a stack element for each operator (only),
906 and the most recently pushed operator is 'top->op'.
907 An operand (value) is stored in the 'value' field of the stack
908 element of the operator that precedes it.
909 In that case the 'flags' field has the HAVE_VALUE flag set. */
910
911 struct operation init_stack[INIT_STACK_SIZE];
912 struct operation *stack = init_stack;
913 struct operation *limit = stack + INIT_STACK_SIZE;
914 register struct operation *top = stack;
915 int lprio, rprio = 0;
916 int skip_evaluation = 0;
917
918 top->rprio = 0;
919 top->flags = 0;
920
921 for (;;)
922 {
923 struct operation op;
924 int flags = 0;
925
926 /* Read a token */
3e3ec469 927 op = cppexp_lex (pfile);
616915dd 928
929 /* See if the token is an operand, in which case go to set_value.
930 If the token is an operator, figure out its left and right
931 priorities, and then goto maybe_reduce. */
932
933 switch (op.op)
934 {
935 case NAME:
936 top->value = 0, top->unsignedp = FALSE;
937 goto set_value;
938 case CPPEXP_INT:
939 case CPPEXP_CHAR:
940 top->value = op.value;
941 top->unsignedp = op.unsignedp;
942 goto set_value;
943 case 0:
944 lprio = 0; goto maybe_reduce;
945 case '+': case '-':
946 /* Is this correct if unary ? FIXME */
947 flags = RIGHT_OPERAND_REQUIRED;
948 lprio = PLUS_PRIO; rprio = lprio + 1; goto maybe_reduce;
949 case '!': case '~':
950 flags = RIGHT_OPERAND_REQUIRED;
951 rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
952 case '*': case '/': case '%':
953 lprio = MUL_PRIO; goto binop;
954 case '<': case '>': case LEQ: case GEQ:
955 lprio = LESS_PRIO; goto binop;
956 case CPP_EQUALTOK: case NOTEQUAL:
957 lprio = CPP_EQUAL_PRIO; goto binop;
958 case LSH: case RSH:
959 lprio = SHIFT_PRIO; goto binop;
960 case '&': lprio = AND_PRIO; goto binop;
961 case '^': lprio = XOR_PRIO; goto binop;
962 case '|': lprio = OR_PRIO; goto binop;
963 case ANDAND: lprio = ANDAND_PRIO; goto binop;
964 case OROR: lprio = OROR_PRIO; goto binop;
965 case ',':
966 lprio = COMMA_PRIO; goto binop;
967 case '(':
968 lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO;
969 goto maybe_reduce;
970 case ')':
971 lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO;
972 goto maybe_reduce;
973 case ':':
974 lprio = COND_PRIO; rprio = COND_PRIO;
975 goto maybe_reduce;
976 case '?':
977 lprio = COND_PRIO + 1; rprio = COND_PRIO;
978 goto maybe_reduce;
979 binop:
980 flags = LEFT_OPERAND_REQUIRED | RIGHT_OPERAND_REQUIRED;
981 rprio = lprio + 1;
982 goto maybe_reduce;
983 default:
984 cppReader_error
985 (pfile,
986 message ("Invalid character in #if: %c",
987 (char) op.op));
988 goto syntax_error;
989 }
990
991 set_value:
992 /* Push a value onto the stack. */
993 if ((top->flags & HAVE_VALUE) != 0)
994 {
995 cppReader_errorLit (pfile,
80489f0a 996 cstring_makeLiteralTemp ("syntax error in #if"));
616915dd 997 goto syntax_error;
998 }
999 top->flags |= HAVE_VALUE;
1000 continue;
1001
1002 maybe_reduce:
1003 /* Push an operator, and check if we can reduce now. */
1004 while (top->rprio > lprio)
1005 {
1006 /*@-usedef@*/
2f2892c2 1007 HOST_WIDE_INT v1 = top[-1].value;
1008 HOST_WIDE_INT v2 = top[0].value;
616915dd 1009 bool unsigned1 = top[-1].unsignedp;
1010 bool unsigned2 = top[0].unsignedp;
1011
1012 top--;
1013
1014 if (((top[1].flags & LEFT_OPERAND_REQUIRED) != 0)
1015 && ((top[0].flags & HAVE_VALUE) == 0))
1016 {
1017 cppReader_errorLit (pfile,
80489f0a 1018 cstring_makeLiteralTemp ("syntax error - missing left operand"));
616915dd 1019 goto syntax_error;
1020 }
1021 if (((top[1].flags & RIGHT_OPERAND_REQUIRED) != 0)
1022 && ((top[1].flags & HAVE_VALUE) == 0))
1023 {
1024 cppReader_errorLit (pfile,
80489f0a 1025 cstring_makeLiteralTemp ("syntax error - missing right operand"));
616915dd 1026 goto syntax_error;
1027 }
1028 /* top[0].value = (top[1].op)(v1, v2);*/
1029 switch (top[1].op)
1030 {
1031 case '+':
1032 if ((top->flags & HAVE_VALUE) == 0)
1033 { /* Unary '+' */
1034 top->value = v2;
1035 top->unsignedp = unsigned2;
1036 top->flags |= HAVE_VALUE;
1037 }
1038 else
1039 {
1040 top->value = v1 + v2;
1041 top->unsignedp = unsigned1 || unsigned2;
1042 if (!top->unsignedp && (skip_evaluation == 0)
1043 && ! possibleSumSign (v1, v2, top->value))
1044 integer_overflow (pfile);
1045 }
1046 /*@switchbreak@*/ break;
1047 case '-':
1048 if ((top->flags & HAVE_VALUE) == 0)
1049 { /* Unary '-' */
1050 top->value = - v2;
1051 if ((skip_evaluation == 0)
1052 && (top->value & v2) < 0 && !unsigned2)
1053 integer_overflow (pfile);
1054 top->unsignedp = unsigned2;
1055 top->flags |= HAVE_VALUE;
1056 }
1057 else
1058 { /* Binary '-' */
1059 top->value = v1 - v2;
1060 top->unsignedp = unsigned1 || unsigned2;
1061 if (!top->unsignedp && (skip_evaluation == 0)
1062 && !possibleSumSign (top->value, v2, v1))
1063 {
1064 integer_overflow (pfile);
1065 }
1066 }
1067 /*@switchbreak@*/ break;
1068 case '*':
1069 top->unsignedp = unsigned1 || unsigned2;
1070
1071 if (top->unsignedp)
1072 {
1073 top->value = (unsigned long) v1 * v2;
1074 }
1075 else if (skip_evaluation == 0)
1076 {
1077 top->value = v1 * v2;
1078 if ((v1 != 0)
1079 && (top->value / v1 != v2
1080 || (top->value & v1 & v2) < 0))
1081 {
1082 integer_overflow (pfile);
1083 }
1084 }
1085 else
1086 {
1087 ;
1088 }
1089
1090 /*@switchbreak@*/ break;
1091 case '/':
1092 if (skip_evaluation != 0)
1093 /*@switchbreak@*/ break;
1094 if (v2 == 0)
1095 {
1096 cppReader_errorLit (pfile,
80489f0a 1097 cstring_makeLiteralTemp ("Division by zero in #if"));
616915dd 1098 v2 = 1;
1099 }
1100 top->unsignedp = unsigned1 || unsigned2;
1101 if (top->unsignedp)
1102 top->value = (unsigned long) v1 / v2;
1103 else
1104 {
1105 top->value = v1 / v2;
1106 if ((top->value & v1 & v2) < 0)
1107 integer_overflow (pfile);
1108 }
1109 /*@switchbreak@*/ break;
1110 case '%':
1111 if (skip_evaluation != 0)
1112 /*@switchbreak@*/ break;
1113 if (v2 == 0)
1114 {
1115 cppReader_errorLit (pfile,
80489f0a 1116 cstring_makeLiteralTemp ("Division by zero in #if"));
616915dd 1117 v2 = 1;
1118 }
1119 top->unsignedp = unsigned1 || unsigned2;
1120 if (top->unsignedp)
1121 top->value = (unsigned long) v1 % v2;
1122 else
1123 top->value = v1 % v2;
1124 /*@switchbreak@*/ break;
1125 case '!':
1126 if ((top->flags & HAVE_VALUE) != 0)
1127 {
1128 cppReader_errorLit (pfile,
1129 cstring_makeLiteralTemp ("Syntax error"));
1130 goto syntax_error;
1131 }
1132
1133 top->value = (v2 == 0) ? 1 : 0;
1134 top->unsignedp = FALSE;
1135 top->flags |= HAVE_VALUE;
1136 /*@switchbreak@*/ break;
1137 case '~':
1138 if ((top->flags & HAVE_VALUE) != 0)
1139 {
1140 cppReader_errorLit (pfile,
80489f0a 1141 cstring_makeLiteralTemp ("syntax error"));
616915dd 1142 goto syntax_error;
1143 }
1144 top->value = ~ v2;
1145 top->unsignedp = unsigned2;
1146 top->flags |= HAVE_VALUE;
1147 /*@switchbreak@*/ break;
1148 case '<': COMPARE(<); /*@switchbreak@*/ break;
1149 case '>': COMPARE(>); /*@switchbreak@*/ break;
1150 case LEQ: COMPARE(<=); /*@switchbreak@*/ break;
1151 case GEQ: COMPARE(>=); /*@switchbreak@*/ break;
1152 case CPP_EQUALTOK:
1153 top->value = (v1 == v2) ? 1 : 0;
1154 top->unsignedp = FALSE;
1155 /*@switchbreak@*/ break;
1156 case NOTEQUAL:
1157 top->value = (v1 != v2) ? 1 : 0;
1158 top->unsignedp = FALSE;
1159 /*@switchbreak@*/ break;
1160 case LSH:
1161 if (skip_evaluation != 0)
1162 {
1163 /*@switchbreak@*/ break;
1164 }
1165
1166 top->unsignedp = unsigned1;
1167 if (v2 < 0 && ! unsigned2)
1168 top->value = right_shift (v1, unsigned1, -v2);
1169 else
1170 top->value = left_shift (pfile, v1, unsigned1, v2);
1171 /*@switchbreak@*/ break;
1172 case RSH:
1173 if (skip_evaluation != 0)
1174 {
1175 /*@switchbreak@*/ break;
1176 }
1177 top->unsignedp = unsigned1;
1178 if (v2 < 0 && ! unsigned2)
1179 top->value = left_shift (pfile, v1, unsigned1, -v2);
1180 else
1181 top->value = right_shift (v1, unsigned1, v2);
1182 /*@switchbreak@*/ break;
1183
1184/*@notfunction@*/
1185#define LOGICAL(OP) \
1186 top->value = v1 OP v2;\
1187 top->unsignedp = unsigned1 || unsigned2;
1188
1189 case '&': LOGICAL(&); /*@switchbreak@*/ break;
1190 case '^': LOGICAL(^); /*@switchbreak@*/ break;
1191 case '|': LOGICAL(|); /*@switchbreak@*/ break;
1192 case ANDAND:
1193 top->value = ((v1 != 0) && (v2 != 0)) ? 1 : 0;
1194 top->unsignedp = FALSE;
1195
1196 if (v1 == 0)
1197 {
1198 skip_evaluation--;
1199 }
1200 /*@switchbreak@*/ break;
1201 case OROR:
1202 top->value = ((v1 != 0) || (v2 != 0)) ? 1 : 0;
1203 top->unsignedp = FALSE;
1204 if (v1 != 0)
1205 {
1206 skip_evaluation--;
1207 }
1208 /*@switchbreak@*/ break;
1209 case ',':
1210 if (cppReader_isPedantic (pfile))
1211 cppReader_pedwarnLit (pfile,
1212 cstring_makeLiteralTemp ("comma operator in operand of `#if'"));
1213 top->value = v2;
1214 top->unsignedp = unsigned2;
1215 /*@switchbreak@*/ break;
1216 case '(': case '?':
1217 cppReader_errorLit (pfile,
80489f0a 1218 cstring_makeLiteralTemp ("syntax error in #if"));
616915dd 1219 goto syntax_error;
1220 case ':':
1221 if (top[0].op != '?')
1222 {
1223 cppReader_errorLit (pfile,
80489f0a 1224 cstring_makeLiteralTemp ("syntax error ':' without preceding '?'"));
616915dd 1225 goto syntax_error;
1226 }
1227 else if (((top[1].flags & HAVE_VALUE) == 0)
1228 || ((top[-1].flags & HAVE_VALUE) == 0)
1229 || ((top[0].flags & HAVE_VALUE) == 0))
1230 {
1231 cppReader_errorLit (pfile,
80489f0a 1232 cstring_makeLiteralTemp ("bad syntax for ?: operator"));
616915dd 1233 goto syntax_error;
1234 }
1235 else
1236 {
1237 top--;
1238 if (top->value != 0)
1239 {
1240 skip_evaluation--;
1241 }
1242
1243 top->value = (top->value != 0) ? v1 : v2;
1244 top->unsignedp = unsigned1 || unsigned2;
1245 }
1246 /*@switchbreak@*/ break;
1247 case ')':
1248 if (((top[1].flags & HAVE_VALUE) != 0)
1249 || ((top[0].flags & HAVE_VALUE) == 0)
1250 || top[0].op != '('
1251 || ((top[-1].flags & HAVE_VALUE) != 0))
1252 {
1253 cppReader_errorLit (pfile,
80489f0a 1254 cstring_makeLiteralTemp ("mismatched parentheses in #if"));
616915dd 1255 goto syntax_error;
1256 }
1257 else
1258 {
1259 top--;
1260 top->value = v1;
1261 top->unsignedp = unsigned1;
1262 top->flags |= HAVE_VALUE;
1263 }
1264 /*@switchbreak@*/ break;
1265 default:
28bf4b0b 1266 /*@-formatconst@*/
616915dd 1267 fprintf (stderr,
1268 top[1].op >= ' ' && top[1].op <= '~'
1269 ? "unimplemented operator '%c'\n"
1270 : "unimplemented operator '\\%03o'\n",
1271 top[1].op);
28bf4b0b 1272 /*@=formatconst@*/
616915dd 1273 }
1274 }
1275 if (op.op == 0)
1276 {
1277 long val;
1278
1279 if (top != stack)
1280 {
1281 cppReader_errorLit (pfile,
80489f0a 1282 cstring_makeLiteralTemp ("internal error in #if expression"));
616915dd 1283 }
1284
1285 val = top->value;
1286
1287 if (stack != init_stack)
1288 {
1289 sfree (stack);
1290 /*@-branchstate@*/
1291 } /*@=branchstate@*/
1292
1293 return val;
1294 }
1295 top++;
1296
1297 /* Check for and handle stack overflow. */
1298 if (top == limit)
1299 {
1300 struct operation *new_stack;
2f2892c2 1301 size_t old_size = size_fromInt ((char *) limit - (char *) stack);
53306cab 1302 size_t new_size = (size_t) (2 * old_size);
616915dd 1303
1304 if (stack != init_stack)
1305 {
1306 new_stack = (struct operation *) drealloc ((char *) stack,
1307 new_size);
1308 }
1309 else
1310 {
1311 new_stack = (struct operation *) dmalloc (new_size);
1312
1313 /* Bug: the parameters were in the wrong order! */
1314 memcpy ((char *) new_stack, (char *) stack, old_size);
1315 /*@-branchstate@*/
1316 } /*@=branchstate@*/
1317
1318 stack = new_stack;
1319 top = (struct operation *) ((char *) new_stack + old_size);
1320 limit = (struct operation *) ((char *) new_stack + new_size);
1321 /*@-branchstate@*/
1322 } /*@=branchstate@*/
1323
1324 top->flags = flags;
1325 top->rprio = rprio;
1326 top->op = op.op;
1327 if ((op.op == OROR && (top[-1].value != 0))
1328 || (op.op == ANDAND && (top[-1].value == 0))
1329 || (op.op == '?' && (top[-1].value == 0)))
1330 {
1331 skip_evaluation++;
1332 }
1333 else if (op.op == ':')
1334 {
1335 if (top[-2].value != 0) /* Was condition true? */
1336 {
1337 skip_evaluation++;
1338 }
1339 else
1340 {
1341 skip_evaluation--;
1342 }
1343 }
1344 else
1345 {
1346 ;
1347 }
1348 }
1349 syntax_error:
1350 /*@-usereleased@*/
1351 if (stack != init_stack)
1352 {
1353 sfree (stack);
1354 /*@-branchstate@*/
1355 } /*@=branchstate@*/
1356 /*@=usereleased@*/
1357
1358 cppReader_skipRestOfLine (pfile);
1359 return 0;
1360}
This page took 0.251298 seconds and 5 git commands to generate.