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