00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "cpplib.h"
00024 #include "internal.h"
00025
00026 #define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT)
00027 #define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2))
00028 #define LOW_PART(num_part) (num_part & HALF_MASK)
00029 #define HIGH_PART(num_part) (num_part >> (PART_PRECISION / 2))
00030
00031 struct op
00032 {
00033 const cpp_token *token;
00034 cpp_num value;
00035 enum cpp_ttype op;
00036 };
00037
00038
00039 #define num_zerop(num) ((num.low | num.high) == 0)
00040 #define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
00041 static bool num_positive (cpp_num, size_t);
00042 static bool num_greater_eq (cpp_num, cpp_num, size_t);
00043 static cpp_num num_trim (cpp_num, size_t);
00044 static cpp_num num_part_mul (cpp_num_part, cpp_num_part);
00045
00046 static cpp_num num_unary_op (cpp_reader *, cpp_num, enum cpp_ttype);
00047 static cpp_num num_binary_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
00048 static cpp_num num_negate (cpp_num, size_t);
00049 static cpp_num num_bitwise_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
00050 static cpp_num num_inequality_op (cpp_reader *, cpp_num, cpp_num,
00051 enum cpp_ttype);
00052 static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num,
00053 enum cpp_ttype);
00054 static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num);
00055 static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
00056 static cpp_num num_lshift (cpp_num, size_t, size_t);
00057 static cpp_num num_rshift (cpp_num, size_t, size_t);
00058
00059 static cpp_num append_digit (cpp_num, int, int, size_t);
00060 static cpp_num parse_defined (cpp_reader *);
00061 static cpp_num eval_token (cpp_reader *, const cpp_token *);
00062 static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype);
00063 static unsigned int interpret_float_suffix (const uchar *, size_t);
00064 static unsigned int interpret_int_suffix (const uchar *, size_t);
00065 static void check_promotion (cpp_reader *, const struct op *);
00066
00067
00068 #define CPP_UPLUS (CPP_LAST_CPP_OP + 1)
00069 #define CPP_UMINUS (CPP_LAST_CPP_OP + 2)
00070
00071
00072
00073 #define SYNTAX_ERROR(msgid) \
00074 do { cpp_error (pfile, CPP_DL_ERROR, msgid); goto syntax_error; } while(0)
00075 #define SYNTAX_ERROR2(msgid, arg) \
00076 do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \
00077 while(0)
00078
00079
00080
00081
00082 static unsigned int
00083 interpret_float_suffix (const uchar *s, size_t len)
00084 {
00085 size_t f = 0, l = 0, i = 0;
00086
00087 while (len--)
00088 switch (s[len])
00089 {
00090 case 'f': case 'F': f++; break;
00091 case 'l': case 'L': l++; break;
00092 case 'i': case 'I':
00093 case 'j': case 'J': i++; break;
00094 default:
00095 return 0;
00096 }
00097
00098 if (f + l > 1 || i > 1)
00099 return 0;
00100
00101 return ((i ? CPP_N_IMAGINARY : 0)
00102 | (f ? CPP_N_SMALL :
00103 l ? CPP_N_LARGE : CPP_N_MEDIUM));
00104 }
00105
00106
00107
00108
00109 static unsigned int
00110 interpret_int_suffix (const uchar *s, size_t len)
00111 {
00112 size_t u, l, i;
00113
00114 u = l = i = 0;
00115
00116 while (len--)
00117 switch (s[len])
00118 {
00119 case 'u': case 'U': u++; break;
00120 case 'i': case 'I':
00121 case 'j': case 'J': i++; break;
00122 case 'l': case 'L': l++;
00123
00124 if (l == 2 && s[len] != s[len + 1])
00125 return 0;
00126 break;
00127 default:
00128 return 0;
00129 }
00130
00131 if (l > 2 || u > 1 || i > 1)
00132 return 0;
00133
00134 return ((i ? CPP_N_IMAGINARY : 0)
00135 | (u ? CPP_N_UNSIGNED : 0)
00136 | ((l == 0) ? CPP_N_SMALL
00137 : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE));
00138 }
00139
00140
00141
00142
00143 unsigned int
00144 cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
00145 {
00146 const uchar *str = token->val.str.text;
00147 const uchar *limit;
00148 unsigned int max_digit, result, radix;
00149 enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;
00150
00151
00152
00153 if (token->val.str.len == 1)
00154 return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL;
00155
00156 limit = str + token->val.str.len;
00157 float_flag = NOT_FLOAT;
00158 max_digit = 0;
00159 radix = 10;
00160
00161
00162 if (*str == '0')
00163 {
00164 radix = 8;
00165 str++;
00166
00167
00168 if ((*str == 'x' || *str == 'X')
00169 && (str[1] == '.' || ISXDIGIT (str[1])))
00170 {
00171 radix = 16;
00172 str++;
00173 }
00174 }
00175
00176
00177 for (;;)
00178 {
00179 unsigned int c = *str++;
00180
00181 if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))
00182 {
00183 c = hex_value (c);
00184 if (c > max_digit)
00185 max_digit = c;
00186 }
00187 else if (c == '.')
00188 {
00189 if (float_flag == NOT_FLOAT)
00190 float_flag = AFTER_POINT;
00191 else
00192 SYNTAX_ERROR ("too many decimal points in number");
00193 }
00194 else if ((radix <= 10 && (c == 'e' || c == 'E'))
00195 || (radix == 16 && (c == 'p' || c == 'P')))
00196 {
00197 float_flag = AFTER_EXPON;
00198 break;
00199 }
00200 else
00201 {
00202
00203 str--;
00204 break;
00205 }
00206 }
00207
00208 if (float_flag != NOT_FLOAT && radix == 8)
00209 radix = 10;
00210
00211 if (max_digit >= radix)
00212 SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
00213
00214 if (float_flag != NOT_FLOAT)
00215 {
00216 if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
00217 cpp_error (pfile, CPP_DL_PEDWARN,
00218 "use of C99 hexadecimal floating constant");
00219
00220 if (float_flag == AFTER_EXPON)
00221 {
00222 if (*str == '+' || *str == '-')
00223 str++;
00224
00225
00226 if (!ISDIGIT (*str))
00227 SYNTAX_ERROR ("exponent has no digits");
00228
00229 do
00230 str++;
00231 while (ISDIGIT (*str));
00232 }
00233 else if (radix == 16)
00234 SYNTAX_ERROR ("hexadecimal floating constants require an exponent");
00235
00236 result = interpret_float_suffix (str, limit - str);
00237 if (result == 0)
00238 {
00239 cpp_error (pfile, CPP_DL_ERROR,
00240 "invalid suffix \"%.*s\" on floating constant",
00241 (int) (limit - str), str);
00242 return CPP_N_INVALID;
00243 }
00244
00245
00246 if (limit != str
00247 && CPP_WTRADITIONAL (pfile)
00248 && ! cpp_sys_macro_p (pfile))
00249 cpp_error (pfile, CPP_DL_WARNING,
00250 "traditional C rejects the \"%.*s\" suffix",
00251 (int) (limit - str), str);
00252
00253 result |= CPP_N_FLOATING;
00254 }
00255 else
00256 {
00257 result = interpret_int_suffix (str, limit - str);
00258 if (result == 0)
00259 {
00260 cpp_error (pfile, CPP_DL_ERROR,
00261 "invalid suffix \"%.*s\" on integer constant",
00262 (int) (limit - str), str);
00263 return CPP_N_INVALID;
00264 }
00265
00266
00267
00268 if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
00269 {
00270 int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
00271 int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
00272
00273 if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
00274 cpp_error (pfile, CPP_DL_WARNING,
00275 "traditional C rejects the \"%.*s\" suffix",
00276 (int) (limit - str), str);
00277 }
00278
00279 if ((result & CPP_N_WIDTH) == CPP_N_LARGE
00280 && ! CPP_OPTION (pfile, c99)
00281 && CPP_OPTION (pfile, warn_long_long))
00282 cpp_error (pfile, CPP_DL_PEDWARN,
00283 "use of C99 long long integer constant");
00284
00285 result |= CPP_N_INTEGER;
00286 }
00287
00288 if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
00289 cpp_error (pfile, CPP_DL_PEDWARN,
00290 "imaginary constants are a GCC extension");
00291
00292 if (radix == 10)
00293 result |= CPP_N_DECIMAL;
00294 else if (radix == 16)
00295 result |= CPP_N_HEX;
00296 else
00297 result |= CPP_N_OCTAL;
00298
00299 return result;
00300
00301 syntax_error:
00302 return CPP_N_INVALID;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 cpp_num
00312 cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token,
00313 unsigned int type)
00314 {
00315 const uchar *p, *end;
00316 cpp_num result;
00317
00318 result.low = 0;
00319 result.high = 0;
00320 result.unsignedp = !!(type & CPP_N_UNSIGNED);
00321 result.overflow = false;
00322
00323 p = token->val.str.text;
00324 end = p + token->val.str.len;
00325
00326
00327 if (token->val.str.len == 1)
00328 result.low = p[0] - '0';
00329 else
00330 {
00331 cpp_num_part max;
00332 size_t precision = CPP_OPTION (pfile, precision);
00333 unsigned int base = 10, c = 0;
00334 bool overflow = false;
00335
00336 if ((type & CPP_N_RADIX) == CPP_N_OCTAL)
00337 {
00338 base = 8;
00339 p++;
00340 }
00341 else if ((type & CPP_N_RADIX) == CPP_N_HEX)
00342 {
00343 base = 16;
00344 p += 2;
00345 }
00346
00347
00348
00349 max = ~(cpp_num_part) 0;
00350 if (precision < PART_PRECISION)
00351 max >>= PART_PRECISION - precision;
00352 max = (max - base + 1) / base + 1;
00353
00354 for (; p < end; p++)
00355 {
00356 c = *p;
00357
00358 if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))
00359 c = hex_value (c);
00360 else
00361 break;
00362
00363
00364 if (result.low < max)
00365 result.low = result.low * base + c;
00366 else
00367 {
00368 result = append_digit (result, c, base, precision);
00369 overflow |= result.overflow;
00370 max = 0;
00371 }
00372 }
00373
00374 if (overflow)
00375 cpp_error (pfile, CPP_DL_PEDWARN,
00376 "integer constant is too large for its type");
00377
00378
00379
00380
00381 else if (!result.unsignedp
00382 && !(CPP_OPTION (pfile, traditional)
00383 && pfile->state.in_directive)
00384 && !num_positive (result, precision))
00385 {
00386 if (base == 10)
00387 cpp_error (pfile, CPP_DL_WARNING,
00388 "integer constant is so large that it is unsigned");
00389 result.unsignedp = true;
00390 }
00391 }
00392
00393 return result;
00394 }
00395
00396
00397 static cpp_num
00398 append_digit (cpp_num num, int digit, int base, size_t precision)
00399 {
00400 cpp_num result;
00401 unsigned int shift = 3 + (base == 16);
00402 bool overflow;
00403 cpp_num_part add_high, add_low;
00404
00405
00406
00407 overflow = !!(num.high >> (PART_PRECISION - shift));
00408 result.high = num.high << shift;
00409 result.low = num.low << shift;
00410 result.high |= num.low >> (PART_PRECISION - shift);
00411 result.unsignedp = num.unsignedp;
00412
00413 if (base == 10)
00414 {
00415 add_low = num.low << 1;
00416 add_high = (num.high << 1) + (num.low >> (PART_PRECISION - 1));
00417 }
00418 else
00419 add_high = add_low = 0;
00420
00421 if (add_low + digit < add_low)
00422 add_high++;
00423 add_low += digit;
00424
00425 if (result.low + add_low < result.low)
00426 add_high++;
00427 if (result.high + add_high < result.high)
00428 overflow = true;
00429
00430 result.low += add_low;
00431 result.high += add_high;
00432 result.overflow = overflow;
00433
00434
00435
00436 num.low = result.low;
00437 num.high = result.high;
00438 result = num_trim (result, precision);
00439 if (!num_eq (result, num))
00440 result.overflow = true;
00441
00442 return result;
00443 }
00444
00445
00446 static cpp_num
00447 parse_defined (cpp_reader *pfile)
00448 {
00449 cpp_num result;
00450 int paren = 0;
00451 cpp_hashnode *node = 0;
00452 const cpp_token *token;
00453 cpp_context *initial_context = pfile->context;
00454
00455
00456 pfile->state.prevent_expansion++;
00457
00458 token = cpp_get_token (pfile);
00459 if (token->type == CPP_OPEN_PAREN)
00460 {
00461 paren = 1;
00462 token = cpp_get_token (pfile);
00463 }
00464
00465 if (token->type == CPP_NAME)
00466 {
00467 node = token->val.node;
00468 if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
00469 {
00470 cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\"");
00471 node = 0;
00472 }
00473 }
00474 else
00475 {
00476 cpp_error (pfile, CPP_DL_ERROR,
00477 "operator \"defined\" requires an identifier");
00478 if (token->flags & NAMED_OP)
00479 {
00480 cpp_token op;
00481
00482 op.flags = 0;
00483 op.type = token->type;
00484 cpp_error (pfile, CPP_DL_ERROR,
00485 "(\"%s\" is an alternative token for \"%s\" in C++)",
00486 cpp_token_as_text (pfile, token),
00487 cpp_token_as_text (pfile, &op));
00488 }
00489 }
00490
00491 if (node)
00492 {
00493 if (pfile->context != initial_context && CPP_PEDANTIC (pfile))
00494 cpp_error (pfile, CPP_DL_WARNING,
00495 "this use of \"defined\" may not be portable");
00496
00497 _cpp_mark_macro_used (node);
00498
00499
00500
00501 pfile->mi_ind_cmacro = node;
00502 }
00503
00504 pfile->state.prevent_expansion--;
00505
00506 result.unsignedp = false;
00507 result.high = 0;
00508 result.overflow = false;
00509 result.low = node && node->type == NT_MACRO;
00510 return result;
00511 }
00512
00513
00514
00515
00516 static cpp_num
00517 eval_token (cpp_reader *pfile, const cpp_token *token)
00518 {
00519 cpp_num result;
00520 unsigned int temp;
00521 int unsignedp = 0;
00522
00523 result.unsignedp = false;
00524 result.overflow = false;
00525
00526 switch (token->type)
00527 {
00528 case CPP_NUMBER:
00529 temp = cpp_classify_number (pfile, token);
00530 switch (temp & CPP_N_CATEGORY)
00531 {
00532 case CPP_N_FLOATING:
00533 cpp_error (pfile, CPP_DL_ERROR,
00534 "floating constant in preprocessor expression");
00535 break;
00536 case CPP_N_INTEGER:
00537 if (!(temp & CPP_N_IMAGINARY))
00538 return cpp_interpret_integer (pfile, token, temp);
00539 cpp_error (pfile, CPP_DL_ERROR,
00540 "imaginary number in preprocessor expression");
00541 break;
00542
00543 case CPP_N_INVALID:
00544
00545 break;
00546 }
00547 result.high = result.low = 0;
00548 break;
00549
00550 case CPP_WCHAR:
00551 case CPP_CHAR:
00552 {
00553 cppchar_t cc = cpp_interpret_charconst (pfile, token,
00554 &temp, &unsignedp);
00555
00556 result.high = 0;
00557 result.low = cc;
00558
00559 if (!unsignedp && (cppchar_signed_t) cc < 0)
00560 {
00561 if (PART_PRECISION > BITS_PER_CPPCHAR_T)
00562 result.low |= ~(~(cpp_num_part) 0
00563 >> (PART_PRECISION - BITS_PER_CPPCHAR_T));
00564 result.high = ~(cpp_num_part) 0;
00565 result = num_trim (result, CPP_OPTION (pfile, precision));
00566 }
00567 }
00568 break;
00569
00570 case CPP_NAME:
00571 if (token->val.node == pfile->spec_nodes.n_defined)
00572 return parse_defined (pfile);
00573 else if (CPP_OPTION (pfile, cplusplus)
00574 && (token->val.node == pfile->spec_nodes.n_true
00575 || token->val.node == pfile->spec_nodes.n_false))
00576 {
00577 result.high = 0;
00578 result.low = (token->val.node == pfile->spec_nodes.n_true);
00579 }
00580 else
00581 {
00582 result.high = 0;
00583 result.low = 0;
00584 if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
00585 cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined",
00586 NODE_NAME (token->val.node));
00587 }
00588 break;
00589
00590 default:
00591 _cpp_test_assertion (pfile, &temp);
00592 result.high = 0;
00593 result.low = temp;
00594 }
00595
00596 result.unsignedp = !!unsignedp;
00597 return result;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624 #define NO_L_OPERAND (1 << 0)
00625 #define LEFT_ASSOC (1 << 1)
00626 #define CHECK_PROMOTION (1 << 2)
00627
00628
00629
00630 static const struct operator
00631 {
00632 uchar prio;
00633 uchar flags;
00634 } optab[] =
00635 {
00636 {0, 0},
00637 {16, NO_L_OPERAND},
00638 {12, LEFT_ASSOC | CHECK_PROMOTION},
00639 {12, LEFT_ASSOC | CHECK_PROMOTION},
00640 {14, LEFT_ASSOC | CHECK_PROMOTION},
00641 {14, LEFT_ASSOC | CHECK_PROMOTION},
00642 {15, LEFT_ASSOC | CHECK_PROMOTION},
00643 {15, LEFT_ASSOC | CHECK_PROMOTION},
00644 {15, LEFT_ASSOC | CHECK_PROMOTION},
00645 {9, LEFT_ASSOC | CHECK_PROMOTION},
00646 {7, LEFT_ASSOC | CHECK_PROMOTION},
00647 {8, LEFT_ASSOC | CHECK_PROMOTION},
00648 {13, LEFT_ASSOC},
00649 {13, LEFT_ASSOC},
00650
00651 {10, LEFT_ASSOC | CHECK_PROMOTION},
00652 {10, LEFT_ASSOC | CHECK_PROMOTION},
00653
00654 {16, NO_L_OPERAND},
00655 {6, LEFT_ASSOC},
00656 {5, LEFT_ASSOC},
00657 {3, 0},
00658 {4, LEFT_ASSOC | CHECK_PROMOTION},
00659 {2, LEFT_ASSOC},
00660 {1, NO_L_OPERAND},
00661 {0, 0},
00662 {0, 0},
00663 {11, LEFT_ASSOC},
00664 {11, LEFT_ASSOC},
00665 {12, LEFT_ASSOC | CHECK_PROMOTION},
00666 {12, LEFT_ASSOC | CHECK_PROMOTION},
00667 {16, NO_L_OPERAND},
00668 {16, NO_L_OPERAND}
00669 };
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 bool
00683 _cpp_parse_expr (cpp_reader *pfile)
00684 {
00685 struct op *top = pfile->op_stack;
00686 unsigned int lex_count;
00687 bool saw_leading_not, want_value = true;
00688
00689 pfile->state.skip_eval = 0;
00690
00691
00692 pfile->mi_ind_cmacro = 0;
00693 saw_leading_not = false;
00694 lex_count = 0;
00695
00696
00697 top->op = CPP_EOF;
00698
00699 for (;;)
00700 {
00701 struct op op;
00702
00703 lex_count++;
00704 op.token = cpp_get_token (pfile);
00705 op.op = op.token->type;
00706
00707 switch (op.op)
00708 {
00709
00710 case CPP_NUMBER:
00711 case CPP_CHAR:
00712 case CPP_WCHAR:
00713 case CPP_NAME:
00714 case CPP_HASH:
00715 if (!want_value)
00716 SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
00717 cpp_token_as_text (pfile, op.token));
00718 want_value = false;
00719 top->value = eval_token (pfile, op.token);
00720 continue;
00721
00722 case CPP_NOT:
00723 saw_leading_not = lex_count == 1;
00724 break;
00725 case CPP_PLUS:
00726 if (want_value)
00727 op.op = CPP_UPLUS;
00728 break;
00729 case CPP_MINUS:
00730 if (want_value)
00731 op.op = CPP_UMINUS;
00732 break;
00733
00734 default:
00735 if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
00736 SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions",
00737 cpp_token_as_text (pfile, op.token));
00738 break;
00739 }
00740
00741
00742 if (optab[op.op].flags & NO_L_OPERAND)
00743 {
00744 if (!want_value)
00745 SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
00746 cpp_token_as_text (pfile, op.token));
00747 }
00748 else if (want_value)
00749 {
00750
00751
00752 if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
00753 SYNTAX_ERROR ("missing expression between '(' and ')'");
00754
00755 if (op.op == CPP_EOF && top->op == CPP_EOF)
00756 SYNTAX_ERROR ("#if with no expression");
00757
00758 if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
00759 SYNTAX_ERROR2 ("operator '%s' has no right operand",
00760 cpp_token_as_text (pfile, top->token));
00761 else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
00762 ;
00763 else
00764 SYNTAX_ERROR2 ("operator '%s' has no left operand",
00765 cpp_token_as_text (pfile, op.token));
00766 }
00767
00768 top = reduce (pfile, top, op.op);
00769 if (!top)
00770 goto syntax_error;
00771
00772 if (op.op == CPP_EOF)
00773 break;
00774
00775 switch (op.op)
00776 {
00777 case CPP_CLOSE_PAREN:
00778 continue;
00779 case CPP_OR_OR:
00780 if (!num_zerop (top->value))
00781 pfile->state.skip_eval++;
00782 break;
00783 case CPP_AND_AND:
00784 case CPP_QUERY:
00785 if (num_zerop (top->value))
00786 pfile->state.skip_eval++;
00787 break;
00788 case CPP_COLON:
00789 if (top->op != CPP_QUERY)
00790 SYNTAX_ERROR (" ':' without preceding '?'");
00791 if (!num_zerop (top[-1].value))
00792 pfile->state.skip_eval++;
00793 else
00794 pfile->state.skip_eval--;
00795 default:
00796 break;
00797 }
00798
00799 want_value = true;
00800
00801
00802 if (++top == pfile->op_limit)
00803 top = _cpp_expand_op_stack (pfile);
00804
00805 top->op = op.op;
00806 top->token = op.token;
00807 }
00808
00809
00810
00811
00812 if (pfile->mi_ind_cmacro && !(saw_leading_not && lex_count == 3))
00813 pfile->mi_ind_cmacro = 0;
00814
00815 if (top != pfile->op_stack)
00816 {
00817 cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in #if");
00818 syntax_error:
00819 return false;
00820 }
00821
00822 return !num_zerop (top->value);
00823 }
00824
00825
00826
00827
00828 static struct op *
00829 reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op)
00830 {
00831 unsigned int prio;
00832
00833 if (top->op <= CPP_EQ || top->op > CPP_LAST_CPP_OP + 2)
00834 {
00835 bad_op:
00836 cpp_error (pfile, CPP_DL_ICE, "impossible operator '%u'", top->op);
00837 return 0;
00838 }
00839
00840 if (op == CPP_OPEN_PAREN)
00841 return top;
00842
00843
00844
00845 prio = optab[op].prio - ((optab[op].flags & LEFT_ASSOC) != 0);
00846 while (prio < optab[top->op].prio)
00847 {
00848 if (CPP_OPTION (pfile, warn_num_sign_change)
00849 && optab[top->op].flags & CHECK_PROMOTION)
00850 check_promotion (pfile, top);
00851
00852 switch (top->op)
00853 {
00854 case CPP_UPLUS:
00855 case CPP_UMINUS:
00856 case CPP_NOT:
00857 case CPP_COMPL:
00858 top[-1].value = num_unary_op (pfile, top->value, top->op);
00859 break;
00860
00861 case CPP_PLUS:
00862 case CPP_MINUS:
00863 case CPP_RSHIFT:
00864 case CPP_LSHIFT:
00865 case CPP_MIN:
00866 case CPP_MAX:
00867 case CPP_COMMA:
00868 top[-1].value = num_binary_op (pfile, top[-1].value,
00869 top->value, top->op);
00870 break;
00871
00872 case CPP_GREATER:
00873 case CPP_LESS:
00874 case CPP_GREATER_EQ:
00875 case CPP_LESS_EQ:
00876 top[-1].value
00877 = num_inequality_op (pfile, top[-1].value, top->value, top->op);
00878 break;
00879
00880 case CPP_EQ_EQ:
00881 case CPP_NOT_EQ:
00882 top[-1].value
00883 = num_equality_op (pfile, top[-1].value, top->value, top->op);
00884 break;
00885
00886 case CPP_AND:
00887 case CPP_OR:
00888 case CPP_XOR:
00889 top[-1].value
00890 = num_bitwise_op (pfile, top[-1].value, top->value, top->op);
00891 break;
00892
00893 case CPP_MULT:
00894 top[-1].value = num_mul (pfile, top[-1].value, top->value);
00895 break;
00896
00897 case CPP_DIV:
00898 case CPP_MOD:
00899 top[-1].value = num_div_op (pfile, top[-1].value,
00900 top->value, top->op);
00901 break;
00902
00903 case CPP_OR_OR:
00904 top--;
00905 if (!num_zerop (top->value))
00906 pfile->state.skip_eval--;
00907 top->value.low = (!num_zerop (top->value)
00908 || !num_zerop (top[1].value));
00909 top->value.high = 0;
00910 top->value.unsignedp = false;
00911 top->value.overflow = false;
00912 continue;
00913
00914 case CPP_AND_AND:
00915 top--;
00916 if (num_zerop (top->value))
00917 pfile->state.skip_eval--;
00918 top->value.low = (!num_zerop (top->value)
00919 && !num_zerop (top[1].value));
00920 top->value.high = 0;
00921 top->value.unsignedp = false;
00922 top->value.overflow = false;
00923 continue;
00924
00925 case CPP_OPEN_PAREN:
00926 if (op != CPP_CLOSE_PAREN)
00927 {
00928 cpp_error (pfile, CPP_DL_ERROR, "missing ')' in expression");
00929 return 0;
00930 }
00931 top--;
00932 top->value = top[1].value;
00933 return top;
00934
00935 case CPP_COLON:
00936 top -= 2;
00937 if (!num_zerop (top->value))
00938 {
00939 pfile->state.skip_eval--;
00940 top->value = top[1].value;
00941 }
00942 else
00943 top->value = top[2].value;
00944 top->value.unsignedp = (top[1].value.unsignedp
00945 || top[2].value.unsignedp);
00946 continue;
00947
00948 case CPP_QUERY:
00949 cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'");
00950 return 0;
00951
00952 default:
00953 goto bad_op;
00954 }
00955
00956 top--;
00957 if (top->value.overflow && !pfile->state.skip_eval)
00958 cpp_error (pfile, CPP_DL_PEDWARN,
00959 "integer overflow in preprocessor expression");
00960 }
00961
00962 if (op == CPP_CLOSE_PAREN)
00963 {
00964 cpp_error (pfile, CPP_DL_ERROR, "missing '(' in expression");
00965 return 0;
00966 }
00967
00968 return top;
00969 }
00970
00971
00972 struct op *
00973 _cpp_expand_op_stack (cpp_reader *pfile)
00974 {
00975 size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
00976 size_t new_size = old_size * 2 + 20;
00977
00978 pfile->op_stack = xrealloc (pfile->op_stack, new_size * sizeof (struct op));
00979 pfile->op_limit = pfile->op_stack + new_size;
00980
00981 return pfile->op_stack + old_size;
00982 }
00983
00984
00985
00986 static void
00987 check_promotion (cpp_reader *pfile, const struct op *op)
00988 {
00989 if (op->value.unsignedp == op[-1].value.unsignedp)
00990 return;
00991
00992 if (op->value.unsignedp)
00993 {
00994 if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision)))
00995 cpp_error (pfile, CPP_DL_WARNING,
00996 "the left operand of \"%s\" changes sign when promoted",
00997 cpp_token_as_text (pfile, op->token));
00998 }
00999 else if (!num_positive (op->value, CPP_OPTION (pfile, precision)))
01000 cpp_error (pfile, CPP_DL_WARNING,
01001 "the right operand of \"%s\" changes sign when promoted",
01002 cpp_token_as_text (pfile, op->token));
01003 }
01004
01005
01006 static cpp_num
01007 num_trim (cpp_num num, size_t precision)
01008 {
01009 if (precision > PART_PRECISION)
01010 {
01011 precision -= PART_PRECISION;
01012 if (precision < PART_PRECISION)
01013 num.high &= ((cpp_num_part) 1 << precision) - 1;
01014 }
01015 else
01016 {
01017 if (precision < PART_PRECISION)
01018 num.low &= ((cpp_num_part) 1 << precision) - 1;
01019 num.high = 0;
01020 }
01021
01022 return num;
01023 }
01024
01025
01026 static bool
01027 num_positive (cpp_num num, size_t precision)
01028 {
01029 if (precision > PART_PRECISION)
01030 {
01031 precision -= PART_PRECISION;
01032 return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
01033 }
01034
01035 return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
01036 }
01037
01038
01039
01040 cpp_num
01041 cpp_num_sign_extend (cpp_num num, size_t precision)
01042 {
01043 if (!num.unsignedp)
01044 {
01045 if (precision > PART_PRECISION)
01046 {
01047 precision -= PART_PRECISION;
01048 if (precision < PART_PRECISION
01049 && (num.high & (cpp_num_part) 1 << (precision - 1)))
01050 num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
01051 }
01052 else if (num.low & (cpp_num_part) 1 << (precision - 1))
01053 {
01054 if (precision < PART_PRECISION)
01055 num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
01056 num.high = ~(cpp_num_part) 0;
01057 }
01058 }
01059
01060 return num;
01061 }
01062
01063
01064 static cpp_num
01065 num_negate (cpp_num num, size_t precision)
01066 {
01067 cpp_num copy;
01068
01069 copy = num;
01070 num.high = ~num.high;
01071 num.low = ~num.low;
01072 if (++num.low == 0)
01073 num.high++;
01074 num = num_trim (num, precision);
01075 num.overflow = (!num.unsignedp && num_eq (num, copy) && !num_zerop (num));
01076
01077 return num;
01078 }
01079
01080
01081 static bool
01082 num_greater_eq (cpp_num pa, cpp_num pb, size_t precision)
01083 {
01084 bool unsignedp;
01085
01086 unsignedp = pa.unsignedp || pb.unsignedp;
01087
01088 if (!unsignedp)
01089 {
01090
01091
01092 unsignedp = num_positive (pa, precision);
01093
01094 if (unsignedp != num_positive (pb, precision))
01095 return unsignedp;
01096
01097
01098 }
01099
01100 return (pa.high > pb.high) || (pa.high == pb.high && pa.low >= pb.low);
01101 }
01102
01103
01104 static cpp_num
01105 num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
01106 cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
01107 {
01108 lhs.overflow = false;
01109 lhs.unsignedp = lhs.unsignedp || rhs.unsignedp;
01110
01111
01112
01113 if (op == CPP_AND)
01114 {
01115 lhs.low &= rhs.low;
01116 lhs.high &= rhs.high;
01117 }
01118 else if (op == CPP_OR)
01119 {
01120 lhs.low |= rhs.low;
01121 lhs.high |= rhs.high;
01122 }
01123 else
01124 {
01125 lhs.low ^= rhs.low;
01126 lhs.high ^= rhs.high;
01127 }
01128
01129 return lhs;
01130 }
01131
01132
01133 static cpp_num
01134 num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs,
01135 enum cpp_ttype op)
01136 {
01137 bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision));
01138
01139 if (op == CPP_GREATER_EQ)
01140 lhs.low = gte;
01141 else if (op == CPP_LESS)
01142 lhs.low = !gte;
01143 else if (op == CPP_GREATER)
01144 lhs.low = gte && !num_eq (lhs, rhs);
01145 else
01146 lhs.low = !gte || num_eq (lhs, rhs);
01147
01148 lhs.high = 0;
01149 lhs.overflow = false;
01150 lhs.unsignedp = false;
01151 return lhs;
01152 }
01153
01154
01155 static cpp_num
01156 num_equality_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
01157 cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
01158 {
01159
01160 bool eq = num_eq (lhs, rhs);
01161 if (op == CPP_NOT_EQ)
01162 eq = !eq;
01163 lhs.low = eq;
01164 lhs.high = 0;
01165 lhs.overflow = false;
01166 lhs.unsignedp = false;
01167 return lhs;
01168 }
01169
01170
01171 static cpp_num
01172 num_rshift (cpp_num num, size_t precision, size_t n)
01173 {
01174 cpp_num_part sign_mask;
01175 bool x = num_positive (num, precision);
01176
01177 if (num.unsignedp || x)
01178 sign_mask = 0;
01179 else
01180 sign_mask = ~(cpp_num_part) 0;
01181
01182 if (n >= precision)
01183 num.high = num.low = sign_mask;
01184 else
01185 {
01186
01187 if (precision < PART_PRECISION)
01188 num.high = sign_mask, num.low |= sign_mask << precision;
01189 else if (precision < 2 * PART_PRECISION)
01190 num.high |= sign_mask << (precision - PART_PRECISION);
01191
01192 if (n >= PART_PRECISION)
01193 {
01194 n -= PART_PRECISION;
01195 num.low = num.high;
01196 num.high = sign_mask;
01197 }
01198
01199 if (n)
01200 {
01201 num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
01202 num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
01203 }
01204 }
01205
01206 num = num_trim (num, precision);
01207 num.overflow = false;
01208 return num;
01209 }
01210
01211
01212 static cpp_num
01213 num_lshift (cpp_num num, size_t precision, size_t n)
01214 {
01215 if (n >= precision)
01216 {
01217 num.overflow = !num.unsignedp && !num_zerop (num);
01218 num.high = num.low = 0;
01219 }
01220 else
01221 {
01222 cpp_num orig, maybe_orig;
01223 size_t m = n;
01224
01225 orig = num;
01226 if (m >= PART_PRECISION)
01227 {
01228 m -= PART_PRECISION;
01229 num.high = num.low;
01230 num.low = 0;
01231 }
01232 if (m)
01233 {
01234 num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
01235 num.low <<= m;
01236 }
01237 num = num_trim (num, precision);
01238
01239 if (num.unsignedp)
01240 num.overflow = false;
01241 else
01242 {
01243 maybe_orig = num_rshift (num, precision, n);
01244 num.overflow = !num_eq (orig, maybe_orig);
01245 }
01246 }
01247
01248 return num;
01249 }
01250
01251
01252 static cpp_num
01253 num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op)
01254 {
01255 switch (op)
01256 {
01257 case CPP_UPLUS:
01258 if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
01259 cpp_error (pfile, CPP_DL_WARNING,
01260 "traditional C rejects the unary plus operator");
01261 num.overflow = false;
01262 break;
01263
01264 case CPP_UMINUS:
01265 num = num_negate (num, CPP_OPTION (pfile, precision));
01266 break;
01267
01268 case CPP_COMPL:
01269 num.high = ~num.high;
01270 num.low = ~num.low;
01271 num = num_trim (num, CPP_OPTION (pfile, precision));
01272 num.overflow = false;
01273 break;
01274
01275 default:
01276 num.low = num_zerop (num);
01277 num.high = 0;
01278 num.overflow = false;
01279 num.unsignedp = false;
01280 break;
01281 }
01282
01283 return num;
01284 }
01285
01286
01287 static cpp_num
01288 num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
01289 {
01290 cpp_num result;
01291 size_t precision = CPP_OPTION (pfile, precision);
01292 bool gte;
01293 size_t n;
01294
01295 switch (op)
01296 {
01297
01298 case CPP_LSHIFT:
01299 case CPP_RSHIFT:
01300 if (!rhs.unsignedp && !num_positive (rhs, precision))
01301 {
01302
01303 if (op == CPP_LSHIFT)
01304 op = CPP_RSHIFT;
01305 else
01306 op = CPP_LSHIFT;
01307 rhs = num_negate (rhs, precision);
01308 }
01309 if (rhs.high)
01310 n = ~0;
01311 else
01312 n = rhs.low;
01313 if (op == CPP_LSHIFT)
01314 lhs = num_lshift (lhs, precision, n);
01315 else
01316 lhs = num_rshift (lhs, precision, n);
01317 break;
01318
01319
01320 case CPP_MIN:
01321 case CPP_MAX:
01322 {
01323 bool unsignedp = lhs.unsignedp || rhs.unsignedp;
01324
01325 gte = num_greater_eq (lhs, rhs, precision);
01326 if (op == CPP_MIN)
01327 gte = !gte;
01328 if (!gte)
01329 lhs = rhs;
01330 lhs.unsignedp = unsignedp;
01331 }
01332 break;
01333
01334
01335 case CPP_MINUS:
01336 rhs = num_negate (rhs, precision);
01337 case CPP_PLUS:
01338 result.low = lhs.low + rhs.low;
01339 result.high = lhs.high + rhs.high;
01340 if (result.low < lhs.low)
01341 result.high++;
01342 result.unsignedp = lhs.unsignedp || rhs.unsignedp;
01343 result.overflow = false;
01344
01345 result = num_trim (result, precision);
01346 if (!result.unsignedp)
01347 {
01348 bool lhsp = num_positive (lhs, precision);
01349 result.overflow = (lhsp == num_positive (rhs, precision)
01350 && lhsp != num_positive (result, precision));
01351 }
01352 return result;
01353
01354
01355 default:
01356 if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99)
01357 || !pfile->state.skip_eval))
01358 cpp_error (pfile, CPP_DL_PEDWARN,
01359 "comma operator in operand of #if");
01360 lhs = rhs;
01361 break;
01362 }
01363
01364 return lhs;
01365 }
01366
01367
01368
01369 static cpp_num
01370 num_part_mul (cpp_num_part lhs, cpp_num_part rhs)
01371 {
01372 cpp_num result;
01373 cpp_num_part middle[2], temp;
01374
01375 result.low = LOW_PART (lhs) * LOW_PART (rhs);
01376 result.high = HIGH_PART (lhs) * HIGH_PART (rhs);
01377
01378 middle[0] = LOW_PART (lhs) * HIGH_PART (rhs);
01379 middle[1] = HIGH_PART (lhs) * LOW_PART (rhs);
01380
01381 temp = result.low;
01382 result.low += LOW_PART (middle[0]) << (PART_PRECISION / 2);
01383 if (result.low < temp)
01384 result.high++;
01385
01386 temp = result.low;
01387 result.low += LOW_PART (middle[1]) << (PART_PRECISION / 2);
01388 if (result.low < temp)
01389 result.high++;
01390
01391 result.high += HIGH_PART (middle[0]);
01392 result.high += HIGH_PART (middle[1]);
01393 result.unsignedp = true;
01394 result.overflow = false;
01395
01396 return result;
01397 }
01398
01399
01400 static cpp_num
01401 num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs)
01402 {
01403 cpp_num result, temp;
01404 bool unsignedp = lhs.unsignedp || rhs.unsignedp;
01405 bool overflow, negate = false;
01406 size_t precision = CPP_OPTION (pfile, precision);
01407
01408
01409 if (!unsignedp)
01410 {
01411 if (!num_positive (lhs, precision))
01412 negate = !negate, lhs = num_negate (lhs, precision);
01413 if (!num_positive (rhs, precision))
01414 negate = !negate, rhs = num_negate (rhs, precision);
01415 }
01416
01417 overflow = lhs.high && rhs.high;
01418 result = num_part_mul (lhs.low, rhs.low);
01419
01420 temp = num_part_mul (lhs.high, rhs.low);
01421 result.high += temp.low;
01422 if (temp.high)
01423 overflow = true;
01424
01425 temp = num_part_mul (lhs.low, rhs.high);
01426 result.high += temp.low;
01427 if (temp.high)
01428 overflow = true;
01429
01430 temp.low = result.low, temp.high = result.high;
01431 result = num_trim (result, precision);
01432 if (!num_eq (result, temp))
01433 overflow = true;
01434
01435 if (negate)
01436 result = num_negate (result, precision);
01437
01438 if (unsignedp)
01439 result.overflow = false;
01440 else
01441 result.overflow = overflow || (num_positive (result, precision) ^ !negate
01442 && !num_zerop (result));
01443 result.unsignedp = unsignedp;
01444
01445 return result;
01446 }
01447
01448
01449
01450 static cpp_num
01451 num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
01452 {
01453 cpp_num result, sub;
01454 cpp_num_part mask;
01455 bool unsignedp = lhs.unsignedp || rhs.unsignedp;
01456 bool negate = false, lhs_neg = false;
01457 size_t i, precision = CPP_OPTION (pfile, precision);
01458
01459
01460 if (!unsignedp)
01461 {
01462 if (!num_positive (lhs, precision))
01463 negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision);
01464 if (!num_positive (rhs, precision))
01465 negate = !negate, rhs = num_negate (rhs, precision);
01466 }
01467
01468
01469 if (rhs.high)
01470 {
01471 i = precision - 1;
01472 mask = (cpp_num_part) 1 << (i - PART_PRECISION);
01473 for (; ; i--, mask >>= 1)
01474 if (rhs.high & mask)
01475 break;
01476 }
01477 else if (rhs.low)
01478 {
01479 if (precision > PART_PRECISION)
01480 i = precision - PART_PRECISION - 1;
01481 else
01482 i = precision - 1;
01483 mask = (cpp_num_part) 1 << i;
01484 for (; ; i--, mask >>= 1)
01485 if (rhs.low & mask)
01486 break;
01487 }
01488 else
01489 {
01490 if (!pfile->state.skip_eval)
01491 cpp_error (pfile, CPP_DL_ERROR, "division by zero in #if");
01492 return lhs;
01493 }
01494
01495
01496
01497
01498
01499
01500 rhs.unsignedp = true;
01501 lhs.unsignedp = true;
01502 i = precision - i - 1;
01503 sub = num_lshift (rhs, precision, i);
01504
01505 result.high = result.low = 0;
01506 for (;;)
01507 {
01508 if (num_greater_eq (lhs, sub, precision))
01509 {
01510 lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS);
01511 if (i >= PART_PRECISION)
01512 result.high |= (cpp_num_part) 1 << (i - PART_PRECISION);
01513 else
01514 result.low |= (cpp_num_part) 1 << i;
01515 }
01516 if (i-- == 0)
01517 break;
01518 sub.low = (sub.low >> 1) | (sub.high << (PART_PRECISION - 1));
01519 sub.high >>= 1;
01520 }
01521
01522
01523 if (op == CPP_DIV)
01524 {
01525 result.unsignedp = unsignedp;
01526 result.overflow = false;
01527 if (!unsignedp)
01528 {
01529 if (negate)
01530 result = num_negate (result, precision);
01531 result.overflow = num_positive (result, precision) ^ !negate;
01532 }
01533
01534 return result;
01535 }
01536
01537
01538 lhs.unsignedp = unsignedp;
01539 lhs.overflow = false;
01540 if (lhs_neg)
01541 lhs = num_negate (lhs, precision);
01542
01543 return lhs;
01544 }