xref: /openbsd-src/gnu/gcc/libcpp/expr.c (revision 9506a00be4eb0d9bebf50b5d13c6e396e3241a22)
1404b540aSrobert /* Parse C expressions for cpplib.
2404b540aSrobert    Copyright (C) 1987, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3404b540aSrobert    2002, 2004 Free Software Foundation.
4404b540aSrobert    Contributed by Per Bothner, 1994.
5404b540aSrobert 
6404b540aSrobert This program is free software; you can redistribute it and/or modify it
7404b540aSrobert under the terms of the GNU General Public License as published by the
8404b540aSrobert Free Software Foundation; either version 2, or (at your option) any
9404b540aSrobert later version.
10404b540aSrobert 
11404b540aSrobert This program is distributed in the hope that it will be useful,
12404b540aSrobert but WITHOUT ANY WARRANTY; without even the implied warranty of
13404b540aSrobert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14404b540aSrobert GNU General Public License for more details.
15404b540aSrobert 
16404b540aSrobert You should have received a copy of the GNU General Public License
17404b540aSrobert along with this program; if not, write to the Free Software
18404b540aSrobert Foundation, 51 Franklin Street, Fifth Floor,
19404b540aSrobert Boston, MA 02110-1301, USA.  */
20404b540aSrobert 
21404b540aSrobert #include "config.h"
22404b540aSrobert #include "system.h"
23404b540aSrobert #include "cpplib.h"
24404b540aSrobert #include "internal.h"
25404b540aSrobert 
26404b540aSrobert #define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT)
27404b540aSrobert #define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2))
28404b540aSrobert #define LOW_PART(num_part) (num_part & HALF_MASK)
29404b540aSrobert #define HIGH_PART(num_part) (num_part >> (PART_PRECISION / 2))
30404b540aSrobert 
31404b540aSrobert struct op
32404b540aSrobert {
33404b540aSrobert   const cpp_token *token;	/* The token forming op (for diagnostics).  */
34404b540aSrobert   cpp_num value;		/* The value logically "right" of op.  */
35404b540aSrobert   enum cpp_ttype op;
36404b540aSrobert };
37404b540aSrobert 
38404b540aSrobert /* Some simple utility routines on double integers.  */
39404b540aSrobert #define num_zerop(num) ((num.low | num.high) == 0)
40404b540aSrobert #define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
41404b540aSrobert static bool num_positive (cpp_num, size_t);
42404b540aSrobert static bool num_greater_eq (cpp_num, cpp_num, size_t);
43404b540aSrobert static cpp_num num_trim (cpp_num, size_t);
44404b540aSrobert static cpp_num num_part_mul (cpp_num_part, cpp_num_part);
45404b540aSrobert 
46404b540aSrobert static cpp_num num_unary_op (cpp_reader *, cpp_num, enum cpp_ttype);
47404b540aSrobert static cpp_num num_binary_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
48404b540aSrobert static cpp_num num_negate (cpp_num, size_t);
49404b540aSrobert static cpp_num num_bitwise_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
50404b540aSrobert static cpp_num num_inequality_op (cpp_reader *, cpp_num, cpp_num,
51404b540aSrobert 				  enum cpp_ttype);
52404b540aSrobert static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num,
53404b540aSrobert 				enum cpp_ttype);
54404b540aSrobert static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num);
55404b540aSrobert static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
56404b540aSrobert static cpp_num num_lshift (cpp_num, size_t, size_t);
57404b540aSrobert static cpp_num num_rshift (cpp_num, size_t, size_t);
58404b540aSrobert 
59404b540aSrobert static cpp_num append_digit (cpp_num, int, int, size_t);
60404b540aSrobert static cpp_num parse_defined (cpp_reader *);
61404b540aSrobert static cpp_num eval_token (cpp_reader *, const cpp_token *);
62404b540aSrobert static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype);
63404b540aSrobert static unsigned int interpret_float_suffix (const uchar *, size_t);
64404b540aSrobert static unsigned int interpret_int_suffix (const uchar *, size_t);
65404b540aSrobert static void check_promotion (cpp_reader *, const struct op *);
66404b540aSrobert 
67404b540aSrobert /* Token type abuse to create unary plus and minus operators.  */
68404b540aSrobert #define CPP_UPLUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 1))
69404b540aSrobert #define CPP_UMINUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 2))
70404b540aSrobert 
71404b540aSrobert /* With -O2, gcc appears to produce nice code, moving the error
72404b540aSrobert    message load and subsequent jump completely out of the main path.  */
73404b540aSrobert #define SYNTAX_ERROR(msgid) \
74404b540aSrobert   do { cpp_error (pfile, CPP_DL_ERROR, msgid); goto syntax_error; } while(0)
75404b540aSrobert #define SYNTAX_ERROR2(msgid, arg) \
76404b540aSrobert   do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \
77404b540aSrobert   while(0)
78404b540aSrobert 
79404b540aSrobert /* Subroutine of cpp_classify_number.  S points to a float suffix of
80404b540aSrobert    length LEN, possibly zero.  Returns 0 for an invalid suffix, or a
81404b540aSrobert    flag vector describing the suffix.  */
82404b540aSrobert static unsigned int
interpret_float_suffix(const uchar * s,size_t len)83404b540aSrobert interpret_float_suffix (const uchar *s, size_t len)
84404b540aSrobert {
85341535f4Smartynas   size_t f = 0, l = 0, i = 0, d = 0, d0 = 0;
86404b540aSrobert 
87404b540aSrobert   while (len--)
88404b540aSrobert     switch (s[len])
89404b540aSrobert       {
90404b540aSrobert       case 'f': case 'F': f++; break;
91404b540aSrobert       case 'l': case 'L': l++; break;
92404b540aSrobert       case 'i': case 'I':
93404b540aSrobert       case 'j': case 'J': i++; break;
94404b540aSrobert       case 'd': case 'D':
95404b540aSrobert 	/* Disallow fd, ld suffixes.  */
96404b540aSrobert 	if (d && (f || l))
97404b540aSrobert 	  return 0;
98404b540aSrobert 	d++;
99404b540aSrobert 	break;
100404b540aSrobert       default:
101404b540aSrobert 	return 0;
102404b540aSrobert       }
103404b540aSrobert 
104341535f4Smartynas   if (d == 1 && !f && !l) {
105341535f4Smartynas     d = 0;
106341535f4Smartynas     d0 = 1;
107341535f4Smartynas   }
108341535f4Smartynas 
109341535f4Smartynas   if (f + d0 + l > 1 || i > 1)
110404b540aSrobert     return 0;
111404b540aSrobert 
112404b540aSrobert   /* Allow dd, df, dl suffixes for decimal float constants.  */
113404b540aSrobert   if (d && ((d + f + l != 2) || i))
114404b540aSrobert     return 0;
115404b540aSrobert 
116404b540aSrobert   return ((i ? CPP_N_IMAGINARY : 0)
117404b540aSrobert 	  | (f ? CPP_N_SMALL :
118341535f4Smartynas 	     d0 ? CPP_N_MEDIUM :
119341535f4Smartynas 	     l ? CPP_N_LARGE : CPP_N_DEFAULT)
120404b540aSrobert 	  | (d ? CPP_N_DFLOAT : 0));
121404b540aSrobert }
122404b540aSrobert 
123404b540aSrobert /* Subroutine of cpp_classify_number.  S points to an integer suffix
124404b540aSrobert    of length LEN, possibly zero. Returns 0 for an invalid suffix, or a
125404b540aSrobert    flag vector describing the suffix.  */
126404b540aSrobert static unsigned int
interpret_int_suffix(const uchar * s,size_t len)127404b540aSrobert interpret_int_suffix (const uchar *s, size_t len)
128404b540aSrobert {
129404b540aSrobert   size_t u, l, i;
130404b540aSrobert 
131404b540aSrobert   u = l = i = 0;
132404b540aSrobert 
133404b540aSrobert   while (len--)
134404b540aSrobert     switch (s[len])
135404b540aSrobert       {
136404b540aSrobert       case 'u': case 'U':	u++; break;
137404b540aSrobert       case 'i': case 'I':
138404b540aSrobert       case 'j': case 'J':	i++; break;
139404b540aSrobert       case 'l': case 'L':	l++;
140404b540aSrobert 	/* If there are two Ls, they must be adjacent and the same case.  */
141404b540aSrobert 	if (l == 2 && s[len] != s[len + 1])
142404b540aSrobert 	  return 0;
143404b540aSrobert 	break;
144404b540aSrobert       default:
145404b540aSrobert 	return 0;
146404b540aSrobert       }
147404b540aSrobert 
148404b540aSrobert   if (l > 2 || u > 1 || i > 1)
149404b540aSrobert     return 0;
150404b540aSrobert 
151404b540aSrobert   return ((i ? CPP_N_IMAGINARY : 0)
152404b540aSrobert 	  | (u ? CPP_N_UNSIGNED : 0)
153404b540aSrobert 	  | ((l == 0) ? CPP_N_SMALL
154404b540aSrobert 	     : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE));
155404b540aSrobert }
156404b540aSrobert 
157404b540aSrobert /* Categorize numeric constants according to their field (integer,
158404b540aSrobert    floating point, or invalid), radix (decimal, octal, hexadecimal),
159404b540aSrobert    and type suffixes.  */
160404b540aSrobert unsigned int
cpp_classify_number(cpp_reader * pfile,const cpp_token * token)161404b540aSrobert cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
162404b540aSrobert {
163404b540aSrobert   const uchar *str = token->val.str.text;
164404b540aSrobert   const uchar *limit;
165404b540aSrobert   unsigned int max_digit, result, radix;
166404b540aSrobert   enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;
167404b540aSrobert 
168404b540aSrobert   /* If the lexer has done its job, length one can only be a single
169404b540aSrobert      digit.  Fast-path this very common case.  */
170404b540aSrobert   if (token->val.str.len == 1)
171404b540aSrobert     return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL;
172404b540aSrobert 
173404b540aSrobert   limit = str + token->val.str.len;
174404b540aSrobert   float_flag = NOT_FLOAT;
175404b540aSrobert   max_digit = 0;
176404b540aSrobert   radix = 10;
177404b540aSrobert 
178404b540aSrobert   /* First, interpret the radix.  */
179404b540aSrobert   if (*str == '0')
180404b540aSrobert     {
181404b540aSrobert       radix = 8;
182404b540aSrobert       str++;
183404b540aSrobert 
184404b540aSrobert       /* Require at least one hex digit to classify it as hex.  */
185404b540aSrobert       if ((*str == 'x' || *str == 'X')
186404b540aSrobert 	  && (str[1] == '.' || ISXDIGIT (str[1])))
187404b540aSrobert 	{
188404b540aSrobert 	  radix = 16;
189404b540aSrobert 	  str++;
190404b540aSrobert 	}
191*9506a00bSjsg       else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1'))
192*9506a00bSjsg 	{
193*9506a00bSjsg 	  radix = 2;
194*9506a00bSjsg 	  str++;
195*9506a00bSjsg 	}
196404b540aSrobert     }
197404b540aSrobert 
198404b540aSrobert   /* Now scan for a well-formed integer or float.  */
199404b540aSrobert   for (;;)
200404b540aSrobert     {
201404b540aSrobert       unsigned int c = *str++;
202404b540aSrobert 
203404b540aSrobert       if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))
204404b540aSrobert 	{
205404b540aSrobert 	  c = hex_value (c);
206404b540aSrobert 	  if (c > max_digit)
207404b540aSrobert 	    max_digit = c;
208404b540aSrobert 	}
209404b540aSrobert       else if (c == '.')
210404b540aSrobert 	{
211404b540aSrobert 	  if (float_flag == NOT_FLOAT)
212404b540aSrobert 	    float_flag = AFTER_POINT;
213404b540aSrobert 	  else
214404b540aSrobert 	    SYNTAX_ERROR ("too many decimal points in number");
215404b540aSrobert 	}
216404b540aSrobert       else if ((radix <= 10 && (c == 'e' || c == 'E'))
217404b540aSrobert 	       || (radix == 16 && (c == 'p' || c == 'P')))
218404b540aSrobert 	{
219404b540aSrobert 	  float_flag = AFTER_EXPON;
220404b540aSrobert 	  break;
221404b540aSrobert 	}
222404b540aSrobert       else
223404b540aSrobert 	{
224404b540aSrobert 	  /* Start of suffix.  */
225404b540aSrobert 	  str--;
226404b540aSrobert 	  break;
227404b540aSrobert 	}
228404b540aSrobert     }
229404b540aSrobert 
230404b540aSrobert   if (float_flag != NOT_FLOAT && radix == 8)
231404b540aSrobert     radix = 10;
232404b540aSrobert 
233404b540aSrobert   if (max_digit >= radix)
234*9506a00bSjsg     {
235*9506a00bSjsg       if (radix == 2)
236*9506a00bSjsg 	SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + max_digit);
237*9506a00bSjsg       else
238404b540aSrobert 	SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
239*9506a00bSjsg     }
240404b540aSrobert 
241404b540aSrobert   if (float_flag != NOT_FLOAT)
242404b540aSrobert     {
243*9506a00bSjsg       if (radix == 2)
244*9506a00bSjsg 	{
245*9506a00bSjsg 	  cpp_error (pfile, CPP_DL_ERROR,
246*9506a00bSjsg 		     "invalid prefix \"0b\" for floating constant");
247*9506a00bSjsg 	  return CPP_N_INVALID;
248*9506a00bSjsg 	}
249*9506a00bSjsg 
250404b540aSrobert       if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
251404b540aSrobert 	cpp_error (pfile, CPP_DL_PEDWARN,
252404b540aSrobert 		   "use of C99 hexadecimal floating constant");
253404b540aSrobert 
254404b540aSrobert       if (float_flag == AFTER_EXPON)
255404b540aSrobert 	{
256404b540aSrobert 	  if (*str == '+' || *str == '-')
257404b540aSrobert 	    str++;
258404b540aSrobert 
259404b540aSrobert 	  /* Exponent is decimal, even if string is a hex float.  */
260404b540aSrobert 	  if (!ISDIGIT (*str))
261404b540aSrobert 	    SYNTAX_ERROR ("exponent has no digits");
262404b540aSrobert 
263404b540aSrobert 	  do
264404b540aSrobert 	    str++;
265404b540aSrobert 	  while (ISDIGIT (*str));
266404b540aSrobert 	}
267404b540aSrobert       else if (radix == 16)
268404b540aSrobert 	SYNTAX_ERROR ("hexadecimal floating constants require an exponent");
269404b540aSrobert 
270404b540aSrobert       result = interpret_float_suffix (str, limit - str);
271404b540aSrobert       if (result == 0)
272404b540aSrobert 	{
273404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR,
274404b540aSrobert 		     "invalid suffix \"%.*s\" on floating constant",
275404b540aSrobert 		     (int) (limit - str), str);
276404b540aSrobert 	  return CPP_N_INVALID;
277404b540aSrobert 	}
278404b540aSrobert 
279404b540aSrobert       /* Traditional C didn't accept any floating suffixes.  */
280404b540aSrobert       if (limit != str
281404b540aSrobert 	  && CPP_WTRADITIONAL (pfile)
282404b540aSrobert 	  && ! cpp_sys_macro_p (pfile))
283404b540aSrobert 	cpp_error (pfile, CPP_DL_WARNING,
284404b540aSrobert 		   "traditional C rejects the \"%.*s\" suffix",
285404b540aSrobert 		   (int) (limit - str), str);
286404b540aSrobert 
287341535f4Smartynas       /* A suffix for double is a GCC extension via decimal float support.
288341535f4Smartynas 	 If the suffix also specifies an imaginary value we'll catch that
289341535f4Smartynas 	 later.  */
290341535f4Smartynas       if ((result == CPP_N_MEDIUM) && CPP_PEDANTIC (pfile))
291341535f4Smartynas 	cpp_error (pfile, CPP_DL_PEDWARN,
292341535f4Smartynas 		   "suffix for double constant is a GCC extension");
293341535f4Smartynas 
294404b540aSrobert       /* Radix must be 10 for decimal floats.  */
295404b540aSrobert       if ((result & CPP_N_DFLOAT) && radix != 10)
296404b540aSrobert         {
297404b540aSrobert           cpp_error (pfile, CPP_DL_ERROR,
298404b540aSrobert                      "invalid suffix \"%.*s\" with hexadecimal floating constant",
299404b540aSrobert                      (int) (limit - str), str);
300404b540aSrobert           return CPP_N_INVALID;
301404b540aSrobert         }
302404b540aSrobert 
303404b540aSrobert       result |= CPP_N_FLOATING;
304404b540aSrobert     }
305404b540aSrobert   else
306404b540aSrobert     {
307404b540aSrobert       result = interpret_int_suffix (str, limit - str);
308404b540aSrobert       if (result == 0)
309404b540aSrobert 	{
310404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR,
311404b540aSrobert 		     "invalid suffix \"%.*s\" on integer constant",
312404b540aSrobert 		     (int) (limit - str), str);
313404b540aSrobert 	  return CPP_N_INVALID;
314404b540aSrobert 	}
315404b540aSrobert 
316404b540aSrobert       /* Traditional C only accepted the 'L' suffix.
317404b540aSrobert          Suppress warning about 'LL' with -Wno-long-long.  */
318404b540aSrobert       if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
319404b540aSrobert 	{
320404b540aSrobert 	  int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
321404b540aSrobert 	  int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
322404b540aSrobert 
323404b540aSrobert 	  if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
324404b540aSrobert 	    cpp_error (pfile, CPP_DL_WARNING,
325404b540aSrobert 		       "traditional C rejects the \"%.*s\" suffix",
326404b540aSrobert 		       (int) (limit - str), str);
327404b540aSrobert 	}
328404b540aSrobert 
329404b540aSrobert       if ((result & CPP_N_WIDTH) == CPP_N_LARGE
330404b540aSrobert 	  && ! CPP_OPTION (pfile, c99)
331404b540aSrobert 	  && CPP_OPTION (pfile, warn_long_long))
332404b540aSrobert 	cpp_error (pfile, CPP_DL_PEDWARN,
333404b540aSrobert 		   "use of C99 long long integer constant");
334404b540aSrobert 
335404b540aSrobert       result |= CPP_N_INTEGER;
336404b540aSrobert     }
337404b540aSrobert 
338404b540aSrobert   if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
339404b540aSrobert     cpp_error (pfile, CPP_DL_PEDWARN,
340404b540aSrobert 	       "imaginary constants are a GCC extension");
341*9506a00bSjsg   if (radix == 2 && CPP_PEDANTIC (pfile))
342*9506a00bSjsg     cpp_error (pfile, CPP_DL_PEDWARN,
343*9506a00bSjsg 	       "binary constants are a GCC extension");
344404b540aSrobert 
345404b540aSrobert   if (radix == 10)
346404b540aSrobert     result |= CPP_N_DECIMAL;
347404b540aSrobert   else if (radix == 16)
348404b540aSrobert     result |= CPP_N_HEX;
349*9506a00bSjsg   else if (radix == 2)
350*9506a00bSjsg     result |= CPP_N_BINARY;
351404b540aSrobert   else
352404b540aSrobert     result |= CPP_N_OCTAL;
353404b540aSrobert 
354404b540aSrobert   return result;
355404b540aSrobert 
356404b540aSrobert  syntax_error:
357404b540aSrobert   return CPP_N_INVALID;
358404b540aSrobert }
359404b540aSrobert 
360404b540aSrobert /* cpp_interpret_integer converts an integer constant into a cpp_num,
361404b540aSrobert    of precision options->precision.
362404b540aSrobert 
363404b540aSrobert    We do not provide any interface for decimal->float conversion,
364404b540aSrobert    because the preprocessor doesn't need it and we don't want to
365404b540aSrobert    drag in GCC's floating point emulator.  */
366404b540aSrobert cpp_num
cpp_interpret_integer(cpp_reader * pfile,const cpp_token * token,unsigned int type)367404b540aSrobert cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token,
368404b540aSrobert 		       unsigned int type)
369404b540aSrobert {
370404b540aSrobert   const uchar *p, *end;
371404b540aSrobert   cpp_num result;
372404b540aSrobert 
373404b540aSrobert   result.low = 0;
374404b540aSrobert   result.high = 0;
375404b540aSrobert   result.unsignedp = !!(type & CPP_N_UNSIGNED);
376404b540aSrobert   result.overflow = false;
377404b540aSrobert 
378404b540aSrobert   p = token->val.str.text;
379404b540aSrobert   end = p + token->val.str.len;
380404b540aSrobert 
381404b540aSrobert   /* Common case of a single digit.  */
382404b540aSrobert   if (token->val.str.len == 1)
383404b540aSrobert     result.low = p[0] - '0';
384404b540aSrobert   else
385404b540aSrobert     {
386404b540aSrobert       cpp_num_part max;
387404b540aSrobert       size_t precision = CPP_OPTION (pfile, precision);
388404b540aSrobert       unsigned int base = 10, c = 0;
389404b540aSrobert       bool overflow = false;
390404b540aSrobert 
391404b540aSrobert       if ((type & CPP_N_RADIX) == CPP_N_OCTAL)
392404b540aSrobert 	{
393404b540aSrobert 	  base = 8;
394404b540aSrobert 	  p++;
395404b540aSrobert 	}
396404b540aSrobert       else if ((type & CPP_N_RADIX) == CPP_N_HEX)
397404b540aSrobert 	{
398404b540aSrobert 	  base = 16;
399404b540aSrobert 	  p += 2;
400404b540aSrobert 	}
401*9506a00bSjsg       else if ((type & CPP_N_RADIX) == CPP_N_BINARY)
402*9506a00bSjsg 	{
403*9506a00bSjsg 	  base = 2;
404*9506a00bSjsg 	  p += 2;
405*9506a00bSjsg 	}
406404b540aSrobert 
407404b540aSrobert       /* We can add a digit to numbers strictly less than this without
408404b540aSrobert 	 needing the precision and slowness of double integers.  */
409404b540aSrobert       max = ~(cpp_num_part) 0;
410404b540aSrobert       if (precision < PART_PRECISION)
411404b540aSrobert 	max >>= PART_PRECISION - precision;
412404b540aSrobert       max = (max - base + 1) / base + 1;
413404b540aSrobert 
414404b540aSrobert       for (; p < end; p++)
415404b540aSrobert 	{
416404b540aSrobert 	  c = *p;
417404b540aSrobert 
418404b540aSrobert 	  if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))
419404b540aSrobert 	    c = hex_value (c);
420404b540aSrobert 	  else
421404b540aSrobert 	    break;
422404b540aSrobert 
423404b540aSrobert 	  /* Strict inequality for when max is set to zero.  */
424404b540aSrobert 	  if (result.low < max)
425404b540aSrobert 	    result.low = result.low * base + c;
426404b540aSrobert 	  else
427404b540aSrobert 	    {
428404b540aSrobert 	      result = append_digit (result, c, base, precision);
429404b540aSrobert 	      overflow |= result.overflow;
430404b540aSrobert 	      max = 0;
431404b540aSrobert 	    }
432404b540aSrobert 	}
433404b540aSrobert 
434404b540aSrobert       if (overflow)
435404b540aSrobert 	cpp_error (pfile, CPP_DL_PEDWARN,
436404b540aSrobert 		   "integer constant is too large for its type");
437404b540aSrobert       /* If too big to be signed, consider it unsigned.  Only warn for
438404b540aSrobert 	 decimal numbers.  Traditional numbers were always signed (but
439404b540aSrobert 	 we still honor an explicit U suffix); but we only have
440404b540aSrobert 	 traditional semantics in directives.  */
441404b540aSrobert       else if (!result.unsignedp
442404b540aSrobert 	       && !(CPP_OPTION (pfile, traditional)
443404b540aSrobert 		    && pfile->state.in_directive)
444404b540aSrobert 	       && !num_positive (result, precision))
445404b540aSrobert 	{
446404b540aSrobert 	  if (base == 10)
447404b540aSrobert 	    cpp_error (pfile, CPP_DL_WARNING,
448404b540aSrobert 		       "integer constant is so large that it is unsigned");
449404b540aSrobert 	  result.unsignedp = true;
450404b540aSrobert 	}
451404b540aSrobert     }
452404b540aSrobert 
453404b540aSrobert   return result;
454404b540aSrobert }
455404b540aSrobert 
456404b540aSrobert /* Append DIGIT to NUM, a number of PRECISION bits being read in base BASE.  */
457404b540aSrobert static cpp_num
append_digit(cpp_num num,int digit,int base,size_t precision)458404b540aSrobert append_digit (cpp_num num, int digit, int base, size_t precision)
459404b540aSrobert {
460404b540aSrobert   cpp_num result;
461*9506a00bSjsg   unsigned int shift;
462404b540aSrobert   bool overflow;
463404b540aSrobert   cpp_num_part add_high, add_low;
464404b540aSrobert 
465*9506a00bSjsg   /* Multiply by 2, 8 or 16.  Catching this overflow here means we don't
466404b540aSrobert      need to worry about add_high overflowing.  */
467*9506a00bSjsg   switch (base)
468*9506a00bSjsg     {
469*9506a00bSjsg     case 2:
470*9506a00bSjsg       shift = 1;
471*9506a00bSjsg       break;
472*9506a00bSjsg 
473*9506a00bSjsg     case 16:
474*9506a00bSjsg       shift = 4;
475*9506a00bSjsg       break;
476*9506a00bSjsg 
477*9506a00bSjsg     default:
478*9506a00bSjsg       shift = 3;
479*9506a00bSjsg     }
480404b540aSrobert   overflow = !!(num.high >> (PART_PRECISION - shift));
481404b540aSrobert   result.high = num.high << shift;
482404b540aSrobert   result.low = num.low << shift;
483404b540aSrobert   result.high |= num.low >> (PART_PRECISION - shift);
484404b540aSrobert   result.unsignedp = num.unsignedp;
485404b540aSrobert 
486404b540aSrobert   if (base == 10)
487404b540aSrobert     {
488404b540aSrobert       add_low = num.low << 1;
489404b540aSrobert       add_high = (num.high << 1) + (num.low >> (PART_PRECISION - 1));
490404b540aSrobert     }
491404b540aSrobert   else
492404b540aSrobert     add_high = add_low = 0;
493404b540aSrobert 
494404b540aSrobert   if (add_low + digit < add_low)
495404b540aSrobert     add_high++;
496404b540aSrobert   add_low += digit;
497404b540aSrobert 
498404b540aSrobert   if (result.low + add_low < result.low)
499404b540aSrobert     add_high++;
500404b540aSrobert   if (result.high + add_high < result.high)
501404b540aSrobert     overflow = true;
502404b540aSrobert 
503404b540aSrobert   result.low += add_low;
504404b540aSrobert   result.high += add_high;
505404b540aSrobert   result.overflow = overflow;
506404b540aSrobert 
507404b540aSrobert   /* The above code catches overflow of a cpp_num type.  This catches
508404b540aSrobert      overflow of the (possibly shorter) target precision.  */
509404b540aSrobert   num.low = result.low;
510404b540aSrobert   num.high = result.high;
511404b540aSrobert   result = num_trim (result, precision);
512404b540aSrobert   if (!num_eq (result, num))
513404b540aSrobert     result.overflow = true;
514404b540aSrobert 
515404b540aSrobert   return result;
516404b540aSrobert }
517404b540aSrobert 
518404b540aSrobert /* Handle meeting "defined" in a preprocessor expression.  */
519404b540aSrobert static cpp_num
parse_defined(cpp_reader * pfile)520404b540aSrobert parse_defined (cpp_reader *pfile)
521404b540aSrobert {
522404b540aSrobert   cpp_num result;
523404b540aSrobert   int paren = 0;
524404b540aSrobert   cpp_hashnode *node = 0;
525404b540aSrobert   const cpp_token *token;
526404b540aSrobert   cpp_context *initial_context = pfile->context;
527404b540aSrobert 
528404b540aSrobert   /* Don't expand macros.  */
529404b540aSrobert   pfile->state.prevent_expansion++;
530404b540aSrobert 
531404b540aSrobert   token = cpp_get_token (pfile);
532404b540aSrobert   if (token->type == CPP_OPEN_PAREN)
533404b540aSrobert     {
534404b540aSrobert       paren = 1;
535404b540aSrobert       token = cpp_get_token (pfile);
536404b540aSrobert     }
537404b540aSrobert 
538404b540aSrobert   if (token->type == CPP_NAME)
539404b540aSrobert     {
540404b540aSrobert       node = token->val.node;
541404b540aSrobert       if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
542404b540aSrobert 	{
543404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\"");
544404b540aSrobert 	  node = 0;
545404b540aSrobert 	}
546404b540aSrobert     }
547404b540aSrobert   else
548404b540aSrobert     {
549404b540aSrobert       cpp_error (pfile, CPP_DL_ERROR,
550404b540aSrobert 		 "operator \"defined\" requires an identifier");
551404b540aSrobert       if (token->flags & NAMED_OP)
552404b540aSrobert 	{
553404b540aSrobert 	  cpp_token op;
554404b540aSrobert 
555404b540aSrobert 	  op.flags = 0;
556404b540aSrobert 	  op.type = token->type;
557404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR,
558404b540aSrobert 		     "(\"%s\" is an alternative token for \"%s\" in C++)",
559404b540aSrobert 		     cpp_token_as_text (pfile, token),
560404b540aSrobert 		     cpp_token_as_text (pfile, &op));
561404b540aSrobert 	}
562404b540aSrobert     }
563404b540aSrobert 
564404b540aSrobert   if (node)
565404b540aSrobert     {
566404b540aSrobert       if (pfile->context != initial_context && CPP_PEDANTIC (pfile))
567404b540aSrobert 	cpp_error (pfile, CPP_DL_WARNING,
568404b540aSrobert 		   "this use of \"defined\" may not be portable");
569404b540aSrobert 
570404b540aSrobert       _cpp_mark_macro_used (node);
571404b540aSrobert 
572404b540aSrobert       /* A possible controlling macro of the form #if !defined ().
573404b540aSrobert 	 _cpp_parse_expr checks there was no other junk on the line.  */
574404b540aSrobert       pfile->mi_ind_cmacro = node;
575404b540aSrobert     }
576404b540aSrobert 
577404b540aSrobert   pfile->state.prevent_expansion--;
578404b540aSrobert 
579404b540aSrobert   result.unsignedp = false;
580404b540aSrobert   result.high = 0;
581404b540aSrobert   result.overflow = false;
582404b540aSrobert   result.low = node && node->type == NT_MACRO;
583404b540aSrobert   return result;
584404b540aSrobert }
585404b540aSrobert 
586404b540aSrobert /* Convert a token into a CPP_NUMBER (an interpreted preprocessing
587404b540aSrobert    number or character constant, or the result of the "defined" or "#"
588404b540aSrobert    operators).  */
589404b540aSrobert static cpp_num
eval_token(cpp_reader * pfile,const cpp_token * token)590404b540aSrobert eval_token (cpp_reader *pfile, const cpp_token *token)
591404b540aSrobert {
592404b540aSrobert   cpp_num result;
593404b540aSrobert   unsigned int temp;
594404b540aSrobert   int unsignedp = 0;
595404b540aSrobert 
596404b540aSrobert   result.unsignedp = false;
597404b540aSrobert   result.overflow = false;
598404b540aSrobert 
599404b540aSrobert   switch (token->type)
600404b540aSrobert     {
601404b540aSrobert     case CPP_NUMBER:
602404b540aSrobert       temp = cpp_classify_number (pfile, token);
603404b540aSrobert       switch (temp & CPP_N_CATEGORY)
604404b540aSrobert 	{
605404b540aSrobert 	case CPP_N_FLOATING:
606404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR,
607404b540aSrobert 		     "floating constant in preprocessor expression");
608404b540aSrobert 	  break;
609404b540aSrobert 	case CPP_N_INTEGER:
610404b540aSrobert 	  if (!(temp & CPP_N_IMAGINARY))
611404b540aSrobert 	    return cpp_interpret_integer (pfile, token, temp);
612404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR,
613404b540aSrobert 		     "imaginary number in preprocessor expression");
614404b540aSrobert 	  break;
615404b540aSrobert 
616404b540aSrobert 	case CPP_N_INVALID:
617404b540aSrobert 	  /* Error already issued.  */
618404b540aSrobert 	  break;
619404b540aSrobert 	}
620404b540aSrobert       result.high = result.low = 0;
621404b540aSrobert       break;
622404b540aSrobert 
623404b540aSrobert     case CPP_WCHAR:
624404b540aSrobert     case CPP_CHAR:
625404b540aSrobert       {
626404b540aSrobert 	cppchar_t cc = cpp_interpret_charconst (pfile, token,
627404b540aSrobert 						&temp, &unsignedp);
628404b540aSrobert 
629404b540aSrobert 	result.high = 0;
630404b540aSrobert 	result.low = cc;
631404b540aSrobert 	/* Sign-extend the result if necessary.  */
632404b540aSrobert 	if (!unsignedp && (cppchar_signed_t) cc < 0)
633404b540aSrobert 	  {
634404b540aSrobert 	    if (PART_PRECISION > BITS_PER_CPPCHAR_T)
635404b540aSrobert 	      result.low |= ~(~(cpp_num_part) 0
636404b540aSrobert 			      >> (PART_PRECISION - BITS_PER_CPPCHAR_T));
637404b540aSrobert 	    result.high = ~(cpp_num_part) 0;
638404b540aSrobert 	    result = num_trim (result, CPP_OPTION (pfile, precision));
639404b540aSrobert 	  }
640404b540aSrobert       }
641404b540aSrobert       break;
642404b540aSrobert 
643404b540aSrobert     case CPP_NAME:
644404b540aSrobert       if (token->val.node == pfile->spec_nodes.n_defined)
645404b540aSrobert 	return parse_defined (pfile);
646404b540aSrobert       else if (CPP_OPTION (pfile, cplusplus)
647404b540aSrobert 	       && (token->val.node == pfile->spec_nodes.n_true
648404b540aSrobert 		   || token->val.node == pfile->spec_nodes.n_false))
649404b540aSrobert 	{
650404b540aSrobert 	  result.high = 0;
651404b540aSrobert 	  result.low = (token->val.node == pfile->spec_nodes.n_true);
652404b540aSrobert 	}
653404b540aSrobert       else
654404b540aSrobert 	{
655404b540aSrobert 	  result.high = 0;
656404b540aSrobert 	  result.low = 0;
657404b540aSrobert 	  if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
658404b540aSrobert 	    cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined",
659404b540aSrobert 		       NODE_NAME (token->val.node));
660404b540aSrobert 	}
661404b540aSrobert       break;
662404b540aSrobert 
663404b540aSrobert     default: /* CPP_HASH */
664404b540aSrobert       _cpp_test_assertion (pfile, &temp);
665404b540aSrobert       result.high = 0;
666404b540aSrobert       result.low = temp;
667404b540aSrobert     }
668404b540aSrobert 
669404b540aSrobert   result.unsignedp = !!unsignedp;
670404b540aSrobert   return result;
671404b540aSrobert }
672404b540aSrobert 
673404b540aSrobert /* Operator precedence and flags table.
674404b540aSrobert 
675404b540aSrobert After an operator is returned from the lexer, if it has priority less
676404b540aSrobert than the operator on the top of the stack, we reduce the stack by one
677404b540aSrobert operator and repeat the test.  Since equal priorities do not reduce,
678404b540aSrobert this is naturally right-associative.
679404b540aSrobert 
680404b540aSrobert We handle left-associative operators by decrementing the priority of
681404b540aSrobert just-lexed operators by one, but retaining the priority of operators
682404b540aSrobert already on the stack.
683404b540aSrobert 
684404b540aSrobert The remaining cases are '(' and ')'.  We handle '(' by skipping the
685404b540aSrobert reduction phase completely.  ')' is given lower priority than
686404b540aSrobert everything else, including '(', effectively forcing a reduction of the
687404b540aSrobert parenthesized expression.  If there is a matching '(', the routine
688404b540aSrobert reduce() exits immediately.  If the normal exit route sees a ')', then
689404b540aSrobert there cannot have been a matching '(' and an error message is output.
690404b540aSrobert 
691404b540aSrobert The parser assumes all shifted operators require a left operand unless
692404b540aSrobert the flag NO_L_OPERAND is set.  These semantics are automatic; any
693404b540aSrobert extra semantics need to be handled with operator-specific code.  */
694404b540aSrobert 
695404b540aSrobert /* Flags.  If CHECK_PROMOTION, we warn if the effective sign of an
696404b540aSrobert    operand changes because of integer promotions.  */
697404b540aSrobert #define NO_L_OPERAND	(1 << 0)
698404b540aSrobert #define LEFT_ASSOC	(1 << 1)
699404b540aSrobert #define CHECK_PROMOTION	(1 << 2)
700404b540aSrobert 
701404b540aSrobert /* Operator to priority map.  Must be in the same order as the first
702404b540aSrobert    N entries of enum cpp_ttype.  */
703404b540aSrobert static const struct cpp_operator
704404b540aSrobert {
705404b540aSrobert   uchar prio;
706404b540aSrobert   uchar flags;
707404b540aSrobert } optab[] =
708404b540aSrobert {
709404b540aSrobert   /* EQ */		{0, 0},	/* Shouldn't happen.  */
710404b540aSrobert   /* NOT */		{16, NO_L_OPERAND},
711404b540aSrobert   /* GREATER */		{12, LEFT_ASSOC | CHECK_PROMOTION},
712404b540aSrobert   /* LESS */		{12, LEFT_ASSOC | CHECK_PROMOTION},
713404b540aSrobert   /* PLUS */		{14, LEFT_ASSOC | CHECK_PROMOTION},
714404b540aSrobert   /* MINUS */		{14, LEFT_ASSOC | CHECK_PROMOTION},
715404b540aSrobert   /* MULT */		{15, LEFT_ASSOC | CHECK_PROMOTION},
716404b540aSrobert   /* DIV */		{15, LEFT_ASSOC | CHECK_PROMOTION},
717404b540aSrobert   /* MOD */		{15, LEFT_ASSOC | CHECK_PROMOTION},
718404b540aSrobert   /* AND */		{9, LEFT_ASSOC | CHECK_PROMOTION},
719404b540aSrobert   /* OR */		{7, LEFT_ASSOC | CHECK_PROMOTION},
720404b540aSrobert   /* XOR */		{8, LEFT_ASSOC | CHECK_PROMOTION},
721404b540aSrobert   /* RSHIFT */		{13, LEFT_ASSOC},
722404b540aSrobert   /* LSHIFT */		{13, LEFT_ASSOC},
723404b540aSrobert 
724404b540aSrobert   /* COMPL */		{16, NO_L_OPERAND},
725404b540aSrobert   /* AND_AND */		{6, LEFT_ASSOC},
726404b540aSrobert   /* OR_OR */		{5, LEFT_ASSOC},
727404b540aSrobert   /* QUERY */		{3, 0},
728404b540aSrobert   /* COLON */		{4, LEFT_ASSOC | CHECK_PROMOTION},
729404b540aSrobert   /* COMMA */		{2, LEFT_ASSOC},
730404b540aSrobert   /* OPEN_PAREN */	{1, NO_L_OPERAND},
731404b540aSrobert   /* CLOSE_PAREN */	{0, 0},
732404b540aSrobert   /* EOF */		{0, 0},
733404b540aSrobert   /* EQ_EQ */		{11, LEFT_ASSOC},
734404b540aSrobert   /* NOT_EQ */		{11, LEFT_ASSOC},
735404b540aSrobert   /* GREATER_EQ */	{12, LEFT_ASSOC | CHECK_PROMOTION},
736404b540aSrobert   /* LESS_EQ */		{12, LEFT_ASSOC | CHECK_PROMOTION},
737404b540aSrobert   /* UPLUS */		{16, NO_L_OPERAND},
738404b540aSrobert   /* UMINUS */		{16, NO_L_OPERAND}
739404b540aSrobert };
740404b540aSrobert 
741404b540aSrobert /* Parse and evaluate a C expression, reading from PFILE.
742404b540aSrobert    Returns the truth value of the expression.
743404b540aSrobert 
744404b540aSrobert    The implementation is an operator precedence parser, i.e. a
745404b540aSrobert    bottom-up parser, using a stack for not-yet-reduced tokens.
746404b540aSrobert 
747404b540aSrobert    The stack base is op_stack, and the current stack pointer is 'top'.
748404b540aSrobert    There is a stack element for each operator (only), and the most
749404b540aSrobert    recently pushed operator is 'top->op'.  An operand (value) is
750404b540aSrobert    stored in the 'value' field of the stack element of the operator
751404b540aSrobert    that precedes it.  */
752404b540aSrobert bool
_cpp_parse_expr(cpp_reader * pfile)753404b540aSrobert _cpp_parse_expr (cpp_reader *pfile)
754404b540aSrobert {
755404b540aSrobert   struct op *top = pfile->op_stack;
756404b540aSrobert   unsigned int lex_count;
757404b540aSrobert   bool saw_leading_not, want_value = true;
758404b540aSrobert 
759404b540aSrobert   pfile->state.skip_eval = 0;
760404b540aSrobert 
761404b540aSrobert   /* Set up detection of #if ! defined().  */
762404b540aSrobert   pfile->mi_ind_cmacro = 0;
763404b540aSrobert   saw_leading_not = false;
764404b540aSrobert   lex_count = 0;
765404b540aSrobert 
766404b540aSrobert   /* Lowest priority operator prevents further reductions.  */
767404b540aSrobert   top->op = CPP_EOF;
768404b540aSrobert 
769404b540aSrobert   for (;;)
770404b540aSrobert     {
771404b540aSrobert       struct op op;
772404b540aSrobert 
773404b540aSrobert       lex_count++;
774404b540aSrobert       op.token = cpp_get_token (pfile);
775404b540aSrobert       op.op = op.token->type;
776404b540aSrobert 
777404b540aSrobert       switch (op.op)
778404b540aSrobert 	{
779404b540aSrobert 	  /* These tokens convert into values.  */
780404b540aSrobert 	case CPP_NUMBER:
781404b540aSrobert 	case CPP_CHAR:
782404b540aSrobert 	case CPP_WCHAR:
783404b540aSrobert 	case CPP_NAME:
784404b540aSrobert 	case CPP_HASH:
785404b540aSrobert 	  if (!want_value)
786404b540aSrobert 	    SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
787404b540aSrobert 			   cpp_token_as_text (pfile, op.token));
788404b540aSrobert 	  want_value = false;
789404b540aSrobert 	  top->value = eval_token (pfile, op.token);
790404b540aSrobert 	  continue;
791404b540aSrobert 
792404b540aSrobert 	case CPP_NOT:
793404b540aSrobert 	  saw_leading_not = lex_count == 1;
794404b540aSrobert 	  break;
795404b540aSrobert 	case CPP_PLUS:
796404b540aSrobert 	  if (want_value)
797404b540aSrobert 	    op.op = CPP_UPLUS;
798404b540aSrobert 	  break;
799404b540aSrobert 	case CPP_MINUS:
800404b540aSrobert 	  if (want_value)
801404b540aSrobert 	    op.op = CPP_UMINUS;
802404b540aSrobert 	  break;
803404b540aSrobert 
804404b540aSrobert 	default:
805404b540aSrobert 	  if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
806404b540aSrobert 	    SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions",
807404b540aSrobert 			   cpp_token_as_text (pfile, op.token));
808404b540aSrobert 	  break;
809404b540aSrobert 	}
810404b540aSrobert 
811404b540aSrobert       /* Check we have a value or operator as appropriate.  */
812404b540aSrobert       if (optab[op.op].flags & NO_L_OPERAND)
813404b540aSrobert 	{
814404b540aSrobert 	  if (!want_value)
815404b540aSrobert 	    SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
816404b540aSrobert 			   cpp_token_as_text (pfile, op.token));
817404b540aSrobert 	}
818404b540aSrobert       else if (want_value)
819404b540aSrobert 	{
820404b540aSrobert 	  /* We want a number (or expression) and haven't got one.
821404b540aSrobert 	     Try to emit a specific diagnostic.  */
822404b540aSrobert 	  if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
823404b540aSrobert 	    SYNTAX_ERROR ("missing expression between '(' and ')'");
824404b540aSrobert 
825404b540aSrobert 	  if (op.op == CPP_EOF && top->op == CPP_EOF)
826404b540aSrobert  	    SYNTAX_ERROR ("#if with no expression");
827404b540aSrobert 
828404b540aSrobert  	  if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
829404b540aSrobert  	    SYNTAX_ERROR2 ("operator '%s' has no right operand",
830404b540aSrobert  			   cpp_token_as_text (pfile, top->token));
831404b540aSrobert 	  else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
832404b540aSrobert 	    /* Complain about missing paren during reduction.  */;
833404b540aSrobert 	  else
834404b540aSrobert 	    SYNTAX_ERROR2 ("operator '%s' has no left operand",
835404b540aSrobert 			   cpp_token_as_text (pfile, op.token));
836404b540aSrobert 	}
837404b540aSrobert 
838404b540aSrobert       top = reduce (pfile, top, op.op);
839404b540aSrobert       if (!top)
840404b540aSrobert 	goto syntax_error;
841404b540aSrobert 
842404b540aSrobert       if (op.op == CPP_EOF)
843404b540aSrobert 	break;
844404b540aSrobert 
845404b540aSrobert       switch (op.op)
846404b540aSrobert 	{
847404b540aSrobert 	case CPP_CLOSE_PAREN:
848404b540aSrobert 	  continue;
849404b540aSrobert 	case CPP_OR_OR:
850404b540aSrobert 	  if (!num_zerop (top->value))
851404b540aSrobert 	    pfile->state.skip_eval++;
852404b540aSrobert 	  break;
853404b540aSrobert 	case CPP_AND_AND:
854404b540aSrobert 	case CPP_QUERY:
855404b540aSrobert 	  if (num_zerop (top->value))
856404b540aSrobert 	    pfile->state.skip_eval++;
857404b540aSrobert 	  break;
858404b540aSrobert 	case CPP_COLON:
859404b540aSrobert 	  if (top->op != CPP_QUERY)
860404b540aSrobert 	    SYNTAX_ERROR (" ':' without preceding '?'");
861404b540aSrobert 	  if (!num_zerop (top[-1].value)) /* Was '?' condition true?  */
862404b540aSrobert 	    pfile->state.skip_eval++;
863404b540aSrobert 	  else
864404b540aSrobert 	    pfile->state.skip_eval--;
865404b540aSrobert 	default:
866404b540aSrobert 	  break;
867404b540aSrobert 	}
868404b540aSrobert 
869404b540aSrobert       want_value = true;
870404b540aSrobert 
871404b540aSrobert       /* Check for and handle stack overflow.  */
872404b540aSrobert       if (++top == pfile->op_limit)
873404b540aSrobert 	top = _cpp_expand_op_stack (pfile);
874404b540aSrobert 
875404b540aSrobert       top->op = op.op;
876404b540aSrobert       top->token = op.token;
877404b540aSrobert     }
878404b540aSrobert 
879404b540aSrobert   /* The controlling macro expression is only valid if we called lex 3
880404b540aSrobert      times: <!> <defined expression> and <EOF>.  push_conditional ()
881404b540aSrobert      checks that we are at top-of-file.  */
882404b540aSrobert   if (pfile->mi_ind_cmacro && !(saw_leading_not && lex_count == 3))
883404b540aSrobert     pfile->mi_ind_cmacro = 0;
884404b540aSrobert 
885404b540aSrobert   if (top != pfile->op_stack)
886404b540aSrobert     {
887404b540aSrobert       cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in #if");
888404b540aSrobert     syntax_error:
889404b540aSrobert       return false;  /* Return false on syntax error.  */
890404b540aSrobert     }
891404b540aSrobert 
892404b540aSrobert   return !num_zerop (top->value);
893404b540aSrobert }
894404b540aSrobert 
895404b540aSrobert /* Reduce the operator / value stack if possible, in preparation for
896404b540aSrobert    pushing operator OP.  Returns NULL on error, otherwise the top of
897404b540aSrobert    the stack.  */
898404b540aSrobert static struct op *
reduce(cpp_reader * pfile,struct op * top,enum cpp_ttype op)899404b540aSrobert reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op)
900404b540aSrobert {
901404b540aSrobert   unsigned int prio;
902404b540aSrobert 
903404b540aSrobert   if (top->op <= CPP_EQ || top->op > CPP_LAST_CPP_OP + 2)
904404b540aSrobert     {
905404b540aSrobert     bad_op:
906404b540aSrobert       cpp_error (pfile, CPP_DL_ICE, "impossible operator '%u'", top->op);
907404b540aSrobert       return 0;
908404b540aSrobert     }
909404b540aSrobert 
910404b540aSrobert   if (op == CPP_OPEN_PAREN)
911404b540aSrobert     return top;
912404b540aSrobert 
913404b540aSrobert   /* Decrement the priority of left-associative operators to force a
914404b540aSrobert      reduction with operators of otherwise equal priority.  */
915404b540aSrobert   prio = optab[op].prio - ((optab[op].flags & LEFT_ASSOC) != 0);
916404b540aSrobert   while (prio < optab[top->op].prio)
917404b540aSrobert     {
918404b540aSrobert       if (CPP_OPTION (pfile, warn_num_sign_change)
919404b540aSrobert 	  && optab[top->op].flags & CHECK_PROMOTION)
920404b540aSrobert 	check_promotion (pfile, top);
921404b540aSrobert 
922404b540aSrobert       switch (top->op)
923404b540aSrobert 	{
924404b540aSrobert 	case CPP_UPLUS:
925404b540aSrobert 	case CPP_UMINUS:
926404b540aSrobert 	case CPP_NOT:
927404b540aSrobert 	case CPP_COMPL:
928404b540aSrobert 	  top[-1].value = num_unary_op (pfile, top->value, top->op);
929404b540aSrobert 	  break;
930404b540aSrobert 
931404b540aSrobert 	case CPP_PLUS:
932404b540aSrobert 	case CPP_MINUS:
933404b540aSrobert 	case CPP_RSHIFT:
934404b540aSrobert 	case CPP_LSHIFT:
935404b540aSrobert 	case CPP_COMMA:
936404b540aSrobert 	  top[-1].value = num_binary_op (pfile, top[-1].value,
937404b540aSrobert 					 top->value, top->op);
938404b540aSrobert 	  break;
939404b540aSrobert 
940404b540aSrobert 	case CPP_GREATER:
941404b540aSrobert 	case CPP_LESS:
942404b540aSrobert 	case CPP_GREATER_EQ:
943404b540aSrobert 	case CPP_LESS_EQ:
944404b540aSrobert 	  top[-1].value
945404b540aSrobert 	    = num_inequality_op (pfile, top[-1].value, top->value, top->op);
946404b540aSrobert 	  break;
947404b540aSrobert 
948404b540aSrobert 	case CPP_EQ_EQ:
949404b540aSrobert 	case CPP_NOT_EQ:
950404b540aSrobert 	  top[-1].value
951404b540aSrobert 	    = num_equality_op (pfile, top[-1].value, top->value, top->op);
952404b540aSrobert 	  break;
953404b540aSrobert 
954404b540aSrobert 	case CPP_AND:
955404b540aSrobert 	case CPP_OR:
956404b540aSrobert 	case CPP_XOR:
957404b540aSrobert 	  top[-1].value
958404b540aSrobert 	    = num_bitwise_op (pfile, top[-1].value, top->value, top->op);
959404b540aSrobert 	  break;
960404b540aSrobert 
961404b540aSrobert 	case CPP_MULT:
962404b540aSrobert 	  top[-1].value = num_mul (pfile, top[-1].value, top->value);
963404b540aSrobert 	  break;
964404b540aSrobert 
965404b540aSrobert 	case CPP_DIV:
966404b540aSrobert 	case CPP_MOD:
967404b540aSrobert 	  top[-1].value = num_div_op (pfile, top[-1].value,
968404b540aSrobert 				      top->value, top->op);
969404b540aSrobert 	  break;
970404b540aSrobert 
971404b540aSrobert 	case CPP_OR_OR:
972404b540aSrobert 	  top--;
973404b540aSrobert 	  if (!num_zerop (top->value))
974404b540aSrobert 	    pfile->state.skip_eval--;
975404b540aSrobert 	  top->value.low = (!num_zerop (top->value)
976404b540aSrobert 			    || !num_zerop (top[1].value));
977404b540aSrobert 	  top->value.high = 0;
978404b540aSrobert 	  top->value.unsignedp = false;
979404b540aSrobert 	  top->value.overflow = false;
980404b540aSrobert 	  continue;
981404b540aSrobert 
982404b540aSrobert 	case CPP_AND_AND:
983404b540aSrobert 	  top--;
984404b540aSrobert 	  if (num_zerop (top->value))
985404b540aSrobert 	    pfile->state.skip_eval--;
986404b540aSrobert 	  top->value.low = (!num_zerop (top->value)
987404b540aSrobert 			    && !num_zerop (top[1].value));
988404b540aSrobert 	  top->value.high = 0;
989404b540aSrobert 	  top->value.unsignedp = false;
990404b540aSrobert 	  top->value.overflow = false;
991404b540aSrobert 	  continue;
992404b540aSrobert 
993404b540aSrobert 	case CPP_OPEN_PAREN:
994404b540aSrobert 	  if (op != CPP_CLOSE_PAREN)
995404b540aSrobert 	    {
996404b540aSrobert 	      cpp_error (pfile, CPP_DL_ERROR, "missing ')' in expression");
997404b540aSrobert 	      return 0;
998404b540aSrobert 	    }
999404b540aSrobert 	  top--;
1000404b540aSrobert 	  top->value = top[1].value;
1001404b540aSrobert 	  return top;
1002404b540aSrobert 
1003404b540aSrobert 	case CPP_COLON:
1004404b540aSrobert 	  top -= 2;
1005404b540aSrobert 	  if (!num_zerop (top->value))
1006404b540aSrobert 	    {
1007404b540aSrobert 	      pfile->state.skip_eval--;
1008404b540aSrobert 	      top->value = top[1].value;
1009404b540aSrobert 	    }
1010404b540aSrobert 	  else
1011404b540aSrobert 	    top->value = top[2].value;
1012404b540aSrobert 	  top->value.unsignedp = (top[1].value.unsignedp
1013404b540aSrobert 				  || top[2].value.unsignedp);
1014404b540aSrobert 	  continue;
1015404b540aSrobert 
1016404b540aSrobert 	case CPP_QUERY:
1017404b540aSrobert 	  cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'");
1018404b540aSrobert 	  return 0;
1019404b540aSrobert 
1020404b540aSrobert 	default:
1021404b540aSrobert 	  goto bad_op;
1022404b540aSrobert 	}
1023404b540aSrobert 
1024404b540aSrobert       top--;
1025404b540aSrobert       if (top->value.overflow && !pfile->state.skip_eval)
1026404b540aSrobert 	cpp_error (pfile, CPP_DL_PEDWARN,
1027404b540aSrobert 		   "integer overflow in preprocessor expression");
1028404b540aSrobert     }
1029404b540aSrobert 
1030404b540aSrobert   if (op == CPP_CLOSE_PAREN)
1031404b540aSrobert     {
1032404b540aSrobert       cpp_error (pfile, CPP_DL_ERROR, "missing '(' in expression");
1033404b540aSrobert       return 0;
1034404b540aSrobert     }
1035404b540aSrobert 
1036404b540aSrobert   return top;
1037404b540aSrobert }
1038404b540aSrobert 
1039404b540aSrobert /* Returns the position of the old top of stack after expansion.  */
1040404b540aSrobert struct op *
_cpp_expand_op_stack(cpp_reader * pfile)1041404b540aSrobert _cpp_expand_op_stack (cpp_reader *pfile)
1042404b540aSrobert {
1043404b540aSrobert   size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
1044404b540aSrobert   size_t new_size = old_size * 2 + 20;
1045404b540aSrobert 
1046404b540aSrobert   pfile->op_stack = XRESIZEVEC (struct op, pfile->op_stack, new_size);
1047404b540aSrobert   pfile->op_limit = pfile->op_stack + new_size;
1048404b540aSrobert 
1049404b540aSrobert   return pfile->op_stack + old_size;
1050404b540aSrobert }
1051404b540aSrobert 
1052404b540aSrobert /* Emits a warning if the effective sign of either operand of OP
1053404b540aSrobert    changes because of integer promotions.  */
1054404b540aSrobert static void
check_promotion(cpp_reader * pfile,const struct op * op)1055404b540aSrobert check_promotion (cpp_reader *pfile, const struct op *op)
1056404b540aSrobert {
1057404b540aSrobert   if (op->value.unsignedp == op[-1].value.unsignedp)
1058404b540aSrobert     return;
1059404b540aSrobert 
1060404b540aSrobert   if (op->value.unsignedp)
1061404b540aSrobert     {
1062404b540aSrobert       if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision)))
1063404b540aSrobert 	cpp_error (pfile, CPP_DL_WARNING,
1064404b540aSrobert 		   "the left operand of \"%s\" changes sign when promoted",
1065404b540aSrobert 		   cpp_token_as_text (pfile, op->token));
1066404b540aSrobert     }
1067404b540aSrobert   else if (!num_positive (op->value, CPP_OPTION (pfile, precision)))
1068404b540aSrobert     cpp_error (pfile, CPP_DL_WARNING,
1069404b540aSrobert 	       "the right operand of \"%s\" changes sign when promoted",
1070404b540aSrobert 	       cpp_token_as_text (pfile, op->token));
1071404b540aSrobert }
1072404b540aSrobert 
1073404b540aSrobert /* Clears the unused high order bits of the number pointed to by PNUM.  */
1074404b540aSrobert static cpp_num
num_trim(cpp_num num,size_t precision)1075404b540aSrobert num_trim (cpp_num num, size_t precision)
1076404b540aSrobert {
1077404b540aSrobert   if (precision > PART_PRECISION)
1078404b540aSrobert     {
1079404b540aSrobert       precision -= PART_PRECISION;
1080404b540aSrobert       if (precision < PART_PRECISION)
1081404b540aSrobert 	num.high &= ((cpp_num_part) 1 << precision) - 1;
1082404b540aSrobert     }
1083404b540aSrobert   else
1084404b540aSrobert     {
1085404b540aSrobert       if (precision < PART_PRECISION)
1086404b540aSrobert 	num.low &= ((cpp_num_part) 1 << precision) - 1;
1087404b540aSrobert       num.high = 0;
1088404b540aSrobert     }
1089404b540aSrobert 
1090404b540aSrobert   return num;
1091404b540aSrobert }
1092404b540aSrobert 
1093404b540aSrobert /* True iff A (presumed signed) >= 0.  */
1094404b540aSrobert static bool
num_positive(cpp_num num,size_t precision)1095404b540aSrobert num_positive (cpp_num num, size_t precision)
1096404b540aSrobert {
1097404b540aSrobert   if (precision > PART_PRECISION)
1098404b540aSrobert     {
1099404b540aSrobert       precision -= PART_PRECISION;
1100404b540aSrobert       return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
1101404b540aSrobert     }
1102404b540aSrobert 
1103404b540aSrobert   return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
1104404b540aSrobert }
1105404b540aSrobert 
1106404b540aSrobert /* Sign extend a number, with PRECISION significant bits and all
1107404b540aSrobert    others assumed clear, to fill out a cpp_num structure.  */
1108404b540aSrobert cpp_num
cpp_num_sign_extend(cpp_num num,size_t precision)1109404b540aSrobert cpp_num_sign_extend (cpp_num num, size_t precision)
1110404b540aSrobert {
1111404b540aSrobert   if (!num.unsignedp)
1112404b540aSrobert     {
1113404b540aSrobert       if (precision > PART_PRECISION)
1114404b540aSrobert 	{
1115404b540aSrobert 	  precision -= PART_PRECISION;
1116404b540aSrobert 	  if (precision < PART_PRECISION
1117404b540aSrobert 	      && (num.high & (cpp_num_part) 1 << (precision - 1)))
1118404b540aSrobert 	    num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
1119404b540aSrobert 	}
1120404b540aSrobert       else if (num.low & (cpp_num_part) 1 << (precision - 1))
1121404b540aSrobert 	{
1122404b540aSrobert 	  if (precision < PART_PRECISION)
1123404b540aSrobert 	    num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
1124404b540aSrobert 	  num.high = ~(cpp_num_part) 0;
1125404b540aSrobert 	}
1126404b540aSrobert     }
1127404b540aSrobert 
1128404b540aSrobert   return num;
1129404b540aSrobert }
1130404b540aSrobert 
1131404b540aSrobert /* Returns the negative of NUM.  */
1132404b540aSrobert static cpp_num
num_negate(cpp_num num,size_t precision)1133404b540aSrobert num_negate (cpp_num num, size_t precision)
1134404b540aSrobert {
1135404b540aSrobert   cpp_num copy;
1136404b540aSrobert 
1137404b540aSrobert   copy = num;
1138404b540aSrobert   num.high = ~num.high;
1139404b540aSrobert   num.low = ~num.low;
1140404b540aSrobert   if (++num.low == 0)
1141404b540aSrobert     num.high++;
1142404b540aSrobert   num = num_trim (num, precision);
1143404b540aSrobert   num.overflow = (!num.unsignedp && num_eq (num, copy) && !num_zerop (num));
1144404b540aSrobert 
1145404b540aSrobert   return num;
1146404b540aSrobert }
1147404b540aSrobert 
1148404b540aSrobert /* Returns true if A >= B.  */
1149404b540aSrobert static bool
num_greater_eq(cpp_num pa,cpp_num pb,size_t precision)1150404b540aSrobert num_greater_eq (cpp_num pa, cpp_num pb, size_t precision)
1151404b540aSrobert {
1152404b540aSrobert   bool unsignedp;
1153404b540aSrobert 
1154404b540aSrobert   unsignedp = pa.unsignedp || pb.unsignedp;
1155404b540aSrobert 
1156404b540aSrobert   if (!unsignedp)
1157404b540aSrobert     {
1158404b540aSrobert       /* Both numbers have signed type.  If they are of different
1159404b540aSrobert        sign, the answer is the sign of A.  */
1160404b540aSrobert       unsignedp = num_positive (pa, precision);
1161404b540aSrobert 
1162404b540aSrobert       if (unsignedp != num_positive (pb, precision))
1163404b540aSrobert 	return unsignedp;
1164404b540aSrobert 
1165404b540aSrobert       /* Otherwise we can do an unsigned comparison.  */
1166404b540aSrobert     }
1167404b540aSrobert 
1168404b540aSrobert   return (pa.high > pb.high) || (pa.high == pb.high && pa.low >= pb.low);
1169404b540aSrobert }
1170404b540aSrobert 
1171404b540aSrobert /* Returns LHS OP RHS, where OP is a bit-wise operation.  */
1172404b540aSrobert static cpp_num
num_bitwise_op(cpp_reader * pfile ATTRIBUTE_UNUSED,cpp_num lhs,cpp_num rhs,enum cpp_ttype op)1173404b540aSrobert num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
1174404b540aSrobert 		cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
1175404b540aSrobert {
1176404b540aSrobert   lhs.overflow = false;
1177404b540aSrobert   lhs.unsignedp = lhs.unsignedp || rhs.unsignedp;
1178404b540aSrobert 
1179404b540aSrobert   /* As excess precision is zeroed, there is no need to num_trim () as
1180404b540aSrobert      these operations cannot introduce a set bit there.  */
1181404b540aSrobert   if (op == CPP_AND)
1182404b540aSrobert     {
1183404b540aSrobert       lhs.low &= rhs.low;
1184404b540aSrobert       lhs.high &= rhs.high;
1185404b540aSrobert     }
1186404b540aSrobert   else if (op == CPP_OR)
1187404b540aSrobert     {
1188404b540aSrobert       lhs.low |= rhs.low;
1189404b540aSrobert       lhs.high |= rhs.high;
1190404b540aSrobert     }
1191404b540aSrobert   else
1192404b540aSrobert     {
1193404b540aSrobert       lhs.low ^= rhs.low;
1194404b540aSrobert       lhs.high ^= rhs.high;
1195404b540aSrobert     }
1196404b540aSrobert 
1197404b540aSrobert   return lhs;
1198404b540aSrobert }
1199404b540aSrobert 
1200404b540aSrobert /* Returns LHS OP RHS, where OP is an inequality.  */
1201404b540aSrobert static cpp_num
num_inequality_op(cpp_reader * pfile,cpp_num lhs,cpp_num rhs,enum cpp_ttype op)1202404b540aSrobert num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs,
1203404b540aSrobert 		   enum cpp_ttype op)
1204404b540aSrobert {
1205404b540aSrobert   bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision));
1206404b540aSrobert 
1207404b540aSrobert   if (op == CPP_GREATER_EQ)
1208404b540aSrobert     lhs.low = gte;
1209404b540aSrobert   else if (op == CPP_LESS)
1210404b540aSrobert     lhs.low = !gte;
1211404b540aSrobert   else if (op == CPP_GREATER)
1212404b540aSrobert     lhs.low = gte && !num_eq (lhs, rhs);
1213404b540aSrobert   else /* CPP_LESS_EQ.  */
1214404b540aSrobert     lhs.low = !gte || num_eq (lhs, rhs);
1215404b540aSrobert 
1216404b540aSrobert   lhs.high = 0;
1217404b540aSrobert   lhs.overflow = false;
1218404b540aSrobert   lhs.unsignedp = false;
1219404b540aSrobert   return lhs;
1220404b540aSrobert }
1221404b540aSrobert 
1222404b540aSrobert /* Returns LHS OP RHS, where OP is == or !=.  */
1223404b540aSrobert static cpp_num
num_equality_op(cpp_reader * pfile ATTRIBUTE_UNUSED,cpp_num lhs,cpp_num rhs,enum cpp_ttype op)1224404b540aSrobert num_equality_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
1225404b540aSrobert 		 cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
1226404b540aSrobert {
1227404b540aSrobert   /* Work around a 3.0.4 bug; see PR 6950.  */
1228404b540aSrobert   bool eq = num_eq (lhs, rhs);
1229404b540aSrobert   if (op == CPP_NOT_EQ)
1230404b540aSrobert     eq = !eq;
1231404b540aSrobert   lhs.low = eq;
1232404b540aSrobert   lhs.high = 0;
1233404b540aSrobert   lhs.overflow = false;
1234404b540aSrobert   lhs.unsignedp = false;
1235404b540aSrobert   return lhs;
1236404b540aSrobert }
1237404b540aSrobert 
1238404b540aSrobert /* Shift NUM, of width PRECISION, right by N bits.  */
1239404b540aSrobert static cpp_num
num_rshift(cpp_num num,size_t precision,size_t n)1240404b540aSrobert num_rshift (cpp_num num, size_t precision, size_t n)
1241404b540aSrobert {
1242404b540aSrobert   cpp_num_part sign_mask;
1243404b540aSrobert   bool x = num_positive (num, precision);
1244404b540aSrobert 
1245404b540aSrobert   if (num.unsignedp || x)
1246404b540aSrobert     sign_mask = 0;
1247404b540aSrobert   else
1248404b540aSrobert     sign_mask = ~(cpp_num_part) 0;
1249404b540aSrobert 
1250404b540aSrobert   if (n >= precision)
1251404b540aSrobert     num.high = num.low = sign_mask;
1252404b540aSrobert   else
1253404b540aSrobert     {
1254404b540aSrobert       /* Sign-extend.  */
1255404b540aSrobert       if (precision < PART_PRECISION)
1256404b540aSrobert 	num.high = sign_mask, num.low |= sign_mask << precision;
1257404b540aSrobert       else if (precision < 2 * PART_PRECISION)
1258404b540aSrobert 	num.high |= sign_mask << (precision - PART_PRECISION);
1259404b540aSrobert 
1260404b540aSrobert       if (n >= PART_PRECISION)
1261404b540aSrobert 	{
1262404b540aSrobert 	  n -= PART_PRECISION;
1263404b540aSrobert 	  num.low = num.high;
1264404b540aSrobert 	  num.high = sign_mask;
1265404b540aSrobert 	}
1266404b540aSrobert 
1267404b540aSrobert       if (n)
1268404b540aSrobert 	{
1269404b540aSrobert 	  num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
1270404b540aSrobert 	  num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
1271404b540aSrobert 	}
1272404b540aSrobert     }
1273404b540aSrobert 
1274404b540aSrobert   num = num_trim (num, precision);
1275404b540aSrobert   num.overflow = false;
1276404b540aSrobert   return num;
1277404b540aSrobert }
1278404b540aSrobert 
1279404b540aSrobert /* Shift NUM, of width PRECISION, left by N bits.  */
1280404b540aSrobert static cpp_num
num_lshift(cpp_num num,size_t precision,size_t n)1281404b540aSrobert num_lshift (cpp_num num, size_t precision, size_t n)
1282404b540aSrobert {
1283404b540aSrobert   if (n >= precision)
1284404b540aSrobert     {
1285404b540aSrobert       num.overflow = !num.unsignedp && !num_zerop (num);
1286404b540aSrobert       num.high = num.low = 0;
1287404b540aSrobert     }
1288404b540aSrobert   else
1289404b540aSrobert     {
1290404b540aSrobert       cpp_num orig, maybe_orig;
1291404b540aSrobert       size_t m = n;
1292404b540aSrobert 
1293404b540aSrobert       orig = num;
1294404b540aSrobert       if (m >= PART_PRECISION)
1295404b540aSrobert 	{
1296404b540aSrobert 	  m -= PART_PRECISION;
1297404b540aSrobert 	  num.high = num.low;
1298404b540aSrobert 	  num.low = 0;
1299404b540aSrobert 	}
1300404b540aSrobert       if (m)
1301404b540aSrobert 	{
1302404b540aSrobert 	  num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
1303404b540aSrobert 	  num.low <<= m;
1304404b540aSrobert 	}
1305404b540aSrobert       num = num_trim (num, precision);
1306404b540aSrobert 
1307404b540aSrobert       if (num.unsignedp)
1308404b540aSrobert 	num.overflow = false;
1309404b540aSrobert       else
1310404b540aSrobert 	{
1311404b540aSrobert 	  maybe_orig = num_rshift (num, precision, n);
1312404b540aSrobert 	  num.overflow = !num_eq (orig, maybe_orig);
1313404b540aSrobert 	}
1314404b540aSrobert     }
1315404b540aSrobert 
1316404b540aSrobert   return num;
1317404b540aSrobert }
1318404b540aSrobert 
1319404b540aSrobert /* The four unary operators: +, -, ! and ~.  */
1320404b540aSrobert static cpp_num
num_unary_op(cpp_reader * pfile,cpp_num num,enum cpp_ttype op)1321404b540aSrobert num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op)
1322404b540aSrobert {
1323404b540aSrobert   switch (op)
1324404b540aSrobert     {
1325404b540aSrobert     case CPP_UPLUS:
1326404b540aSrobert       if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
1327404b540aSrobert 	cpp_error (pfile, CPP_DL_WARNING,
1328404b540aSrobert 		   "traditional C rejects the unary plus operator");
1329404b540aSrobert       num.overflow = false;
1330404b540aSrobert       break;
1331404b540aSrobert 
1332404b540aSrobert     case CPP_UMINUS:
1333404b540aSrobert       num = num_negate (num, CPP_OPTION (pfile, precision));
1334404b540aSrobert       break;
1335404b540aSrobert 
1336404b540aSrobert     case CPP_COMPL:
1337404b540aSrobert       num.high = ~num.high;
1338404b540aSrobert       num.low = ~num.low;
1339404b540aSrobert       num = num_trim (num, CPP_OPTION (pfile, precision));
1340404b540aSrobert       num.overflow = false;
1341404b540aSrobert       break;
1342404b540aSrobert 
1343404b540aSrobert     default: /* case CPP_NOT: */
1344404b540aSrobert       num.low = num_zerop (num);
1345404b540aSrobert       num.high = 0;
1346404b540aSrobert       num.overflow = false;
1347404b540aSrobert       num.unsignedp = false;
1348404b540aSrobert       break;
1349404b540aSrobert     }
1350404b540aSrobert 
1351404b540aSrobert   return num;
1352404b540aSrobert }
1353404b540aSrobert 
1354404b540aSrobert /* The various binary operators.  */
1355404b540aSrobert static cpp_num
num_binary_op(cpp_reader * pfile,cpp_num lhs,cpp_num rhs,enum cpp_ttype op)1356404b540aSrobert num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
1357404b540aSrobert {
1358404b540aSrobert   cpp_num result;
1359404b540aSrobert   size_t precision = CPP_OPTION (pfile, precision);
1360404b540aSrobert   size_t n;
1361404b540aSrobert 
1362404b540aSrobert   switch (op)
1363404b540aSrobert     {
1364404b540aSrobert       /* Shifts.  */
1365404b540aSrobert     case CPP_LSHIFT:
1366404b540aSrobert     case CPP_RSHIFT:
1367404b540aSrobert       if (!rhs.unsignedp && !num_positive (rhs, precision))
1368404b540aSrobert 	{
1369404b540aSrobert 	  /* A negative shift is a positive shift the other way.  */
1370404b540aSrobert 	  if (op == CPP_LSHIFT)
1371404b540aSrobert 	    op = CPP_RSHIFT;
1372404b540aSrobert 	  else
1373404b540aSrobert 	    op = CPP_LSHIFT;
1374404b540aSrobert 	  rhs = num_negate (rhs, precision);
1375404b540aSrobert 	}
1376404b540aSrobert       if (rhs.high)
1377404b540aSrobert 	n = ~0;			/* Maximal.  */
1378404b540aSrobert       else
1379404b540aSrobert 	n = rhs.low;
1380404b540aSrobert       if (op == CPP_LSHIFT)
1381404b540aSrobert 	lhs = num_lshift (lhs, precision, n);
1382404b540aSrobert       else
1383404b540aSrobert 	lhs = num_rshift (lhs, precision, n);
1384404b540aSrobert       break;
1385404b540aSrobert 
1386404b540aSrobert       /* Arithmetic.  */
1387404b540aSrobert     case CPP_MINUS:
1388404b540aSrobert       rhs = num_negate (rhs, precision);
1389404b540aSrobert     case CPP_PLUS:
1390404b540aSrobert       result.low = lhs.low + rhs.low;
1391404b540aSrobert       result.high = lhs.high + rhs.high;
1392404b540aSrobert       if (result.low < lhs.low)
1393404b540aSrobert 	result.high++;
1394404b540aSrobert       result.unsignedp = lhs.unsignedp || rhs.unsignedp;
1395404b540aSrobert       result.overflow = false;
1396404b540aSrobert 
1397404b540aSrobert       result = num_trim (result, precision);
1398404b540aSrobert       if (!result.unsignedp)
1399404b540aSrobert 	{
1400404b540aSrobert 	  bool lhsp = num_positive (lhs, precision);
1401404b540aSrobert 	  result.overflow = (lhsp == num_positive (rhs, precision)
1402404b540aSrobert 			     && lhsp != num_positive (result, precision));
1403404b540aSrobert 	}
1404404b540aSrobert       return result;
1405404b540aSrobert 
1406404b540aSrobert       /* Comma.  */
1407404b540aSrobert     default: /* case CPP_COMMA: */
1408404b540aSrobert       if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99)
1409404b540aSrobert 				   || !pfile->state.skip_eval))
1410404b540aSrobert 	cpp_error (pfile, CPP_DL_PEDWARN,
1411404b540aSrobert 		   "comma operator in operand of #if");
1412404b540aSrobert       lhs = rhs;
1413404b540aSrobert       break;
1414404b540aSrobert     }
1415404b540aSrobert 
1416404b540aSrobert   return lhs;
1417404b540aSrobert }
1418404b540aSrobert 
1419404b540aSrobert /* Multiplies two unsigned cpp_num_parts to give a cpp_num.  This
1420404b540aSrobert    cannot overflow.  */
1421404b540aSrobert static cpp_num
num_part_mul(cpp_num_part lhs,cpp_num_part rhs)1422404b540aSrobert num_part_mul (cpp_num_part lhs, cpp_num_part rhs)
1423404b540aSrobert {
1424404b540aSrobert   cpp_num result;
1425404b540aSrobert   cpp_num_part middle[2], temp;
1426404b540aSrobert 
1427404b540aSrobert   result.low = LOW_PART (lhs) * LOW_PART (rhs);
1428404b540aSrobert   result.high = HIGH_PART (lhs) * HIGH_PART (rhs);
1429404b540aSrobert 
1430404b540aSrobert   middle[0] = LOW_PART (lhs) * HIGH_PART (rhs);
1431404b540aSrobert   middle[1] = HIGH_PART (lhs) * LOW_PART (rhs);
1432404b540aSrobert 
1433404b540aSrobert   temp = result.low;
1434404b540aSrobert   result.low += LOW_PART (middle[0]) << (PART_PRECISION / 2);
1435404b540aSrobert   if (result.low < temp)
1436404b540aSrobert     result.high++;
1437404b540aSrobert 
1438404b540aSrobert   temp = result.low;
1439404b540aSrobert   result.low += LOW_PART (middle[1]) << (PART_PRECISION / 2);
1440404b540aSrobert   if (result.low < temp)
1441404b540aSrobert     result.high++;
1442404b540aSrobert 
1443404b540aSrobert   result.high += HIGH_PART (middle[0]);
1444404b540aSrobert   result.high += HIGH_PART (middle[1]);
1445404b540aSrobert   result.unsignedp = true;
1446404b540aSrobert   result.overflow = false;
1447404b540aSrobert 
1448404b540aSrobert   return result;
1449404b540aSrobert }
1450404b540aSrobert 
1451404b540aSrobert /* Multiply two preprocessing numbers.  */
1452404b540aSrobert static cpp_num
num_mul(cpp_reader * pfile,cpp_num lhs,cpp_num rhs)1453404b540aSrobert num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs)
1454404b540aSrobert {
1455404b540aSrobert   cpp_num result, temp;
1456404b540aSrobert   bool unsignedp = lhs.unsignedp || rhs.unsignedp;
1457404b540aSrobert   bool overflow, negate = false;
1458404b540aSrobert   size_t precision = CPP_OPTION (pfile, precision);
1459404b540aSrobert 
1460404b540aSrobert   /* Prepare for unsigned multiplication.  */
1461404b540aSrobert   if (!unsignedp)
1462404b540aSrobert     {
1463404b540aSrobert       if (!num_positive (lhs, precision))
1464404b540aSrobert 	negate = !negate, lhs = num_negate (lhs, precision);
1465404b540aSrobert       if (!num_positive (rhs, precision))
1466404b540aSrobert 	negate = !negate, rhs = num_negate (rhs, precision);
1467404b540aSrobert     }
1468404b540aSrobert 
1469404b540aSrobert   overflow = lhs.high && rhs.high;
1470404b540aSrobert   result = num_part_mul (lhs.low, rhs.low);
1471404b540aSrobert 
1472404b540aSrobert   temp = num_part_mul (lhs.high, rhs.low);
1473404b540aSrobert   result.high += temp.low;
1474404b540aSrobert   if (temp.high)
1475404b540aSrobert     overflow = true;
1476404b540aSrobert 
1477404b540aSrobert   temp = num_part_mul (lhs.low, rhs.high);
1478404b540aSrobert   result.high += temp.low;
1479404b540aSrobert   if (temp.high)
1480404b540aSrobert     overflow = true;
1481404b540aSrobert 
1482404b540aSrobert   temp.low = result.low, temp.high = result.high;
1483404b540aSrobert   result = num_trim (result, precision);
1484404b540aSrobert   if (!num_eq (result, temp))
1485404b540aSrobert     overflow = true;
1486404b540aSrobert 
1487404b540aSrobert   if (negate)
1488404b540aSrobert     result = num_negate (result, precision);
1489404b540aSrobert 
1490404b540aSrobert   if (unsignedp)
1491404b540aSrobert     result.overflow = false;
1492404b540aSrobert   else
1493404b540aSrobert     result.overflow = overflow || (num_positive (result, precision) ^ !negate
1494404b540aSrobert 				   && !num_zerop (result));
1495404b540aSrobert   result.unsignedp = unsignedp;
1496404b540aSrobert 
1497404b540aSrobert   return result;
1498404b540aSrobert }
1499404b540aSrobert 
1500404b540aSrobert /* Divide two preprocessing numbers, returning the answer or the
1501404b540aSrobert    remainder depending upon OP.  */
1502404b540aSrobert static cpp_num
num_div_op(cpp_reader * pfile,cpp_num lhs,cpp_num rhs,enum cpp_ttype op)1503404b540aSrobert num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
1504404b540aSrobert {
1505404b540aSrobert   cpp_num result, sub;
1506404b540aSrobert   cpp_num_part mask;
1507404b540aSrobert   bool unsignedp = lhs.unsignedp || rhs.unsignedp;
1508404b540aSrobert   bool negate = false, lhs_neg = false;
1509404b540aSrobert   size_t i, precision = CPP_OPTION (pfile, precision);
1510404b540aSrobert 
1511404b540aSrobert   /* Prepare for unsigned division.  */
1512404b540aSrobert   if (!unsignedp)
1513404b540aSrobert     {
1514404b540aSrobert       if (!num_positive (lhs, precision))
1515404b540aSrobert 	negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision);
1516404b540aSrobert       if (!num_positive (rhs, precision))
1517404b540aSrobert 	negate = !negate, rhs = num_negate (rhs, precision);
1518404b540aSrobert     }
1519404b540aSrobert 
1520404b540aSrobert   /* Find the high bit.  */
1521404b540aSrobert   if (rhs.high)
1522404b540aSrobert     {
1523404b540aSrobert       i = precision - 1;
1524404b540aSrobert       mask = (cpp_num_part) 1 << (i - PART_PRECISION);
1525404b540aSrobert       for (; ; i--, mask >>= 1)
1526404b540aSrobert 	if (rhs.high & mask)
1527404b540aSrobert 	  break;
1528404b540aSrobert     }
1529404b540aSrobert   else if (rhs.low)
1530404b540aSrobert     {
1531404b540aSrobert       if (precision > PART_PRECISION)
1532404b540aSrobert 	i = precision - PART_PRECISION - 1;
1533404b540aSrobert       else
1534404b540aSrobert 	i = precision - 1;
1535404b540aSrobert       mask = (cpp_num_part) 1 << i;
1536404b540aSrobert       for (; ; i--, mask >>= 1)
1537404b540aSrobert 	if (rhs.low & mask)
1538404b540aSrobert 	  break;
1539404b540aSrobert     }
1540404b540aSrobert   else
1541404b540aSrobert     {
1542404b540aSrobert       if (!pfile->state.skip_eval)
1543404b540aSrobert 	cpp_error (pfile, CPP_DL_ERROR, "division by zero in #if");
1544404b540aSrobert       return lhs;
1545404b540aSrobert     }
1546404b540aSrobert 
1547404b540aSrobert   /* First nonzero bit of RHS is bit I.  Do naive division by
1548404b540aSrobert      shifting the RHS fully left, and subtracting from LHS if LHS is
1549404b540aSrobert      at least as big, and then repeating but with one less shift.
1550404b540aSrobert      This is not very efficient, but is easy to understand.  */
1551404b540aSrobert 
1552404b540aSrobert   rhs.unsignedp = true;
1553404b540aSrobert   lhs.unsignedp = true;
1554404b540aSrobert   i = precision - i - 1;
1555404b540aSrobert   sub = num_lshift (rhs, precision, i);
1556404b540aSrobert 
1557404b540aSrobert   result.high = result.low = 0;
1558404b540aSrobert   for (;;)
1559404b540aSrobert     {
1560404b540aSrobert       if (num_greater_eq (lhs, sub, precision))
1561404b540aSrobert 	{
1562404b540aSrobert 	  lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS);
1563404b540aSrobert 	  if (i >= PART_PRECISION)
1564404b540aSrobert 	    result.high |= (cpp_num_part) 1 << (i - PART_PRECISION);
1565404b540aSrobert 	  else
1566404b540aSrobert 	    result.low |= (cpp_num_part) 1 << i;
1567404b540aSrobert 	}
1568404b540aSrobert       if (i-- == 0)
1569404b540aSrobert 	break;
1570404b540aSrobert       sub.low = (sub.low >> 1) | (sub.high << (PART_PRECISION - 1));
1571404b540aSrobert       sub.high >>= 1;
1572404b540aSrobert     }
1573404b540aSrobert 
1574404b540aSrobert   /* We divide so that the remainder has the sign of the LHS.  */
1575404b540aSrobert   if (op == CPP_DIV)
1576404b540aSrobert     {
1577404b540aSrobert       result.unsignedp = unsignedp;
1578404b540aSrobert       result.overflow = false;
1579404b540aSrobert       if (!unsignedp)
1580404b540aSrobert 	{
1581404b540aSrobert 	  if (negate)
1582404b540aSrobert 	    result = num_negate (result, precision);
1583404b540aSrobert 	  result.overflow = num_positive (result, precision) ^ !negate;
1584404b540aSrobert 	}
1585404b540aSrobert 
1586404b540aSrobert       return result;
1587404b540aSrobert     }
1588404b540aSrobert 
1589404b540aSrobert   /* CPP_MOD.  */
1590404b540aSrobert   lhs.unsignedp = unsignedp;
1591404b540aSrobert   lhs.overflow = false;
1592404b540aSrobert   if (lhs_neg)
1593404b540aSrobert     lhs = num_negate (lhs, precision);
1594404b540aSrobert 
1595404b540aSrobert   return lhs;
1596404b540aSrobert }
1597