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