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