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