| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: lex.c,v 1.201 2024/01/27 12:14:58 rillig Exp $ */ | | 1 | /* $NetBSD: lex.c,v 1.202 2024/01/27 15:53:27 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | | 4 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. |
5 | * Copyright (c) 1994, 1995 Jochen Pohl | | 5 | * Copyright (c) 1994, 1995 Jochen Pohl |
6 | * All Rights Reserved. | | 6 | * All Rights Reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -28,27 +28,27 @@ | | | @@ -28,27 +28,27 @@ |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | | 33 | */ |
34 | | | 34 | |
35 | #if HAVE_NBTOOL_CONFIG_H | | 35 | #if HAVE_NBTOOL_CONFIG_H |
36 | #include "nbtool_config.h" | | 36 | #include "nbtool_config.h" |
37 | #endif | | 37 | #endif |
38 | | | 38 | |
39 | #include <sys/cdefs.h> | | 39 | #include <sys/cdefs.h> |
40 | #if defined(__RCSID) | | 40 | #if defined(__RCSID) |
41 | __RCSID("$NetBSD: lex.c,v 1.201 2024/01/27 12:14:58 rillig Exp $"); | | 41 | __RCSID("$NetBSD: lex.c,v 1.202 2024/01/27 15:53:27 rillig Exp $"); |
42 | #endif | | 42 | #endif |
43 | | | 43 | |
44 | #include <ctype.h> | | 44 | #include <ctype.h> |
45 | #include <errno.h> | | 45 | #include <errno.h> |
46 | #include <float.h> | | 46 | #include <float.h> |
47 | #include <limits.h> | | 47 | #include <limits.h> |
48 | #include <math.h> | | 48 | #include <math.h> |
49 | #include <stdlib.h> | | 49 | #include <stdlib.h> |
50 | #include <string.h> | | 50 | #include <string.h> |
51 | | | 51 | |
52 | #include "lint1.h" | | 52 | #include "lint1.h" |
53 | #include "cgram.h" | | 53 | #include "cgram.h" |
54 | | | 54 | |
| @@ -492,26 +492,87 @@ lex_name(const char *yytext, size_t yyle | | | @@ -492,26 +492,87 @@ lex_name(const char *yytext, size_t yyle |
492 | static bool | | 492 | static bool |
493 | is_unsigned_since_c90(tspec_t typ, uint64_t ui, int base) | | 493 | is_unsigned_since_c90(tspec_t typ, uint64_t ui, int base) |
494 | { | | 494 | { |
495 | if (!(allow_trad && allow_c90)) | | 495 | if (!(allow_trad && allow_c90)) |
496 | return false; | | 496 | return false; |
497 | if (typ == INT) { | | 497 | if (typ == INT) { |
498 | if (ui > TARG_INT_MAX && ui <= TARG_UINT_MAX && base != 10) | | 498 | if (ui > TARG_INT_MAX && ui <= TARG_UINT_MAX && base != 10) |
499 | return true; | | 499 | return true; |
500 | return ui > TARG_LONG_MAX; | | 500 | return ui > TARG_LONG_MAX; |
501 | } | | 501 | } |
502 | return typ == LONG && ui > TARG_LONG_MAX; | | 502 | return typ == LONG && ui > TARG_LONG_MAX; |
503 | } | | 503 | } |
504 | | | 504 | |
| | | 505 | static tspec_t |
| | | 506 | integer_constant_type(tspec_t typ, uint64_t ui, int base, bool warned) |
| | | 507 | { |
| | | 508 | switch (typ) { |
| | | 509 | case INT: |
| | | 510 | if (ui <= TARG_INT_MAX) { |
| | | 511 | /* ok */ |
| | | 512 | } else if (ui <= TARG_UINT_MAX && base != 10) { |
| | | 513 | typ = UINT; |
| | | 514 | } else if (ui <= TARG_LONG_MAX) { |
| | | 515 | typ = LONG; |
| | | 516 | } else { |
| | | 517 | typ = ULONG; |
| | | 518 | if (ui > TARG_ULONG_MAX && !warned) { |
| | | 519 | /* integer constant out of range */ |
| | | 520 | warning(252); |
| | | 521 | } |
| | | 522 | } |
| | | 523 | if ((typ == UINT || typ == ULONG) && !allow_c90) |
| | | 524 | typ = LONG; |
| | | 525 | break; |
| | | 526 | case UINT: |
| | | 527 | if (ui > TARG_UINT_MAX) { |
| | | 528 | typ = ULONG; |
| | | 529 | if (ui > TARG_ULONG_MAX && !warned) { |
| | | 530 | /* integer constant out of range */ |
| | | 531 | warning(252); |
| | | 532 | } |
| | | 533 | } |
| | | 534 | break; |
| | | 535 | case LONG: |
| | | 536 | if (ui > TARG_LONG_MAX && allow_c90) { |
| | | 537 | typ = ULONG; |
| | | 538 | if (ui > TARG_ULONG_MAX && !warned) { |
| | | 539 | /* integer constant out of range */ |
| | | 540 | warning(252); |
| | | 541 | } |
| | | 542 | } |
| | | 543 | break; |
| | | 544 | case ULONG: |
| | | 545 | if (ui > TARG_ULONG_MAX && !warned) { |
| | | 546 | /* integer constant out of range */ |
| | | 547 | warning(252); |
| | | 548 | } |
| | | 549 | break; |
| | | 550 | case LLONG: |
| | | 551 | if (ui > TARG_LLONG_MAX && allow_c90) |
| | | 552 | typ = ULLONG; |
| | | 553 | break; |
| | | 554 | case ULLONG: |
| | | 555 | if (ui > TARG_ULLONG_MAX && !warned) { |
| | | 556 | /* integer constant out of range */ |
| | | 557 | warning(252); |
| | | 558 | } |
| | | 559 | break; |
| | | 560 | default: |
| | | 561 | break; |
| | | 562 | } |
| | | 563 | return typ; |
| | | 564 | } |
| | | 565 | |
505 | int | | 566 | int |
506 | lex_integer_constant(const char *yytext, size_t yyleng, int base) | | 567 | lex_integer_constant(const char *yytext, size_t yyleng, int base) |
507 | { | | 568 | { |
508 | /* C11 6.4.4.1p5 */ | | 569 | /* C11 6.4.4.1p5 */ |
509 | static const tspec_t suffix_type[2][3] = { | | 570 | static const tspec_t suffix_type[2][3] = { |
510 | { INT, LONG, LLONG, }, | | 571 | { INT, LONG, LLONG, }, |
511 | { UINT, ULONG, ULLONG, } | | 572 | { UINT, ULONG, ULLONG, } |
512 | }; | | 573 | }; |
513 | | | 574 | |
514 | const char *cp = yytext; | | 575 | const char *cp = yytext; |
515 | size_t len = yyleng; | | 576 | size_t len = yyleng; |
516 | | | 577 | |
517 | /* skip 0[xX] or 0[bB] */ | | 578 | /* skip 0[xX] or 0[bB] */ |
| @@ -533,105 +594,51 @@ lex_integer_constant(const char *yytext, | | | @@ -533,105 +594,51 @@ lex_integer_constant(const char *yytext, |
533 | } | | 594 | } |
534 | if (l_suffix > 2 || u_suffix > 1) { | | 595 | if (l_suffix > 2 || u_suffix > 1) { |
535 | /* malformed integer constant */ | | 596 | /* malformed integer constant */ |
536 | warning(251); | | 597 | warning(251); |
537 | if (l_suffix > 2) | | 598 | if (l_suffix > 2) |
538 | l_suffix = 2; | | 599 | l_suffix = 2; |
539 | if (u_suffix > 1) | | 600 | if (u_suffix > 1) |
540 | u_suffix = 1; | | 601 | u_suffix = 1; |
541 | } | | 602 | } |
542 | if (!allow_c90 && u_suffix > 0) { | | 603 | if (!allow_c90 && u_suffix > 0) { |
543 | /* suffix 'U' is illegal in traditional C */ | | 604 | /* suffix 'U' is illegal in traditional C */ |
544 | warning(97); | | 605 | warning(97); |
545 | } | | 606 | } |
546 | tspec_t typ = suffix_type[u_suffix][l_suffix]; | | 607 | tspec_t ct = suffix_type[u_suffix][l_suffix]; |
547 | | | 608 | |
548 | bool warned = false; | | 609 | bool warned = false; |
549 | errno = 0; | | 610 | errno = 0; |
550 | char *eptr; | | 611 | char *eptr; |
551 | uint64_t ui = (uint64_t)strtoull(cp, &eptr, base); | | 612 | uint64_t ui = (uint64_t)strtoull(cp, &eptr, base); |
552 | lint_assert(eptr == cp + len); | | 613 | lint_assert(eptr == cp + len); |
553 | if (errno != 0) { | | 614 | if (errno != 0) { |
554 | /* integer constant out of range */ | | 615 | /* integer constant out of range */ |
555 | warning(252); | | 616 | warning(252); |
556 | warned = true; | | 617 | warned = true; |
557 | } | | 618 | } |
558 | | | 619 | |
559 | if (any_query_enabled && base == 8 && ui != 0) { | | 620 | if (any_query_enabled && base == 8 && ui != 0) { |
560 | /* octal number '%.*s' */ | | 621 | /* octal number '%.*s' */ |
561 | query_message(8, (int)len, cp); | | 622 | query_message(8, (int)len, cp); |
562 | } | | 623 | } |
563 | | | 624 | |
564 | bool ansiu = is_unsigned_since_c90(typ, ui, base); | | 625 | bool ansiu = is_unsigned_since_c90(ct, ui, base); |
565 | switch (typ) { | | | |
566 | case INT: | | | |
567 | if (ui <= TARG_INT_MAX) { | | | |
568 | /* ok */ | | | |
569 | } else if (ui <= TARG_UINT_MAX && base != 10) { | | | |
570 | typ = UINT; | | | |
571 | } else if (ui <= TARG_LONG_MAX) { | | | |
572 | typ = LONG; | | | |
573 | } else { | | | |
574 | typ = ULONG; | | | |
575 | if (ui > TARG_ULONG_MAX && !warned) { | | | |
576 | /* integer constant out of range */ | | | |
577 | warning(252); | | | |
578 | } | | | |
579 | } | | | |
580 | if ((typ == UINT || typ == ULONG) && !allow_c90) | | | |
581 | typ = LONG; | | | |
582 | break; | | | |
583 | case UINT: | | | |
584 | if (ui > TARG_UINT_MAX) { | | | |
585 | typ = ULONG; | | | |
586 | if (ui > TARG_ULONG_MAX && !warned) { | | | |
587 | /* integer constant out of range */ | | | |
588 | warning(252); | | | |
589 | } | | | |
590 | } | | | |
591 | break; | | | |
592 | case LONG: | | | |
593 | if (ui > TARG_LONG_MAX && allow_c90) { | | | |
594 | typ = ULONG; | | | |
595 | if (ui > TARG_ULONG_MAX && !warned) { | | | |
596 | /* integer constant out of range */ | | | |
597 | warning(252); | | | |
598 | } | | | |
599 | } | | | |
600 | break; | | | |
601 | case ULONG: | | | |
602 | if (ui > TARG_ULONG_MAX && !warned) { | | | |
603 | /* integer constant out of range */ | | | |
604 | warning(252); | | | |
605 | } | | | |
606 | break; | | | |
607 | case LLONG: | | | |
608 | if (ui > TARG_LLONG_MAX && allow_c90) | | | |
609 | typ = ULLONG; | | | |
610 | break; | | | |
611 | case ULLONG: | | | |
612 | if (ui > TARG_ULLONG_MAX && !warned) { | | | |
613 | /* integer constant out of range */ | | | |
614 | warning(252); | | | |
615 | } | | | |
616 | break; | | | |
617 | default: | | | |
618 | break; | | | |
619 | } | | | |
620 | | | 626 | |
621 | ui = (uint64_t)convert_integer((int64_t)ui, typ, 0); | | 627 | tspec_t t = integer_constant_type(ct, ui, base, warned); |
| | | 628 | ui = (uint64_t)convert_integer((int64_t)ui, t, 0); |
622 | | | 629 | |
623 | yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); | | 630 | yylval.y_val = xcalloc(1, sizeof(*yylval.y_val)); |
624 | yylval.y_val->v_tspec = typ; | | 631 | yylval.y_val->v_tspec = t; |
625 | yylval.y_val->v_unsigned_since_c90 = ansiu; | | 632 | yylval.y_val->v_unsigned_since_c90 = ansiu; |
626 | yylval.y_val->u.integer = (int64_t)ui; | | 633 | yylval.y_val->u.integer = (int64_t)ui; |
627 | | | 634 | |
628 | return T_CON; | | 635 | return T_CON; |
629 | } | | 636 | } |
630 | | | 637 | |
631 | /* | | 638 | /* |
632 | * Extend or truncate si to match t. If t is signed, sign-extend. | | 639 | * Extend or truncate si to match t. If t is signed, sign-extend. |
633 | * | | 640 | * |
634 | * len is the number of significant bits. If len is 0, len is set | | 641 | * len is the number of significant bits. If len is 0, len is set |
635 | * to the width of type t. | | 642 | * to the width of type t. |
636 | */ | | 643 | */ |
637 | int64_t | | 644 | int64_t |