| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tree.c,v 1.171 2021/01/17 15:06:54 rillig Exp $ */ | | 1 | /* $NetBSD: tree.c,v 1.172 2021/01/17 15:24:03 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | | 4 | * Copyright (c) 1994, 1995 Jochen Pohl |
5 | * All Rights Reserved. | | 5 | * All Rights Reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -27,27 +27,27 @@ | | | @@ -27,27 +27,27 @@ |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | | 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #if HAVE_NBTOOL_CONFIG_H | | 34 | #if HAVE_NBTOOL_CONFIG_H |
35 | #include "nbtool_config.h" | | 35 | #include "nbtool_config.h" |
36 | #endif | | 36 | #endif |
37 | | | 37 | |
38 | #include <sys/cdefs.h> | | 38 | #include <sys/cdefs.h> |
39 | #if defined(__RCSID) && !defined(lint) | | 39 | #if defined(__RCSID) && !defined(lint) |
40 | __RCSID("$NetBSD: tree.c,v 1.171 2021/01/17 15:06:54 rillig Exp $"); | | 40 | __RCSID("$NetBSD: tree.c,v 1.172 2021/01/17 15:24:03 rillig Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <float.h> | | 43 | #include <float.h> |
44 | #include <limits.h> | | 44 | #include <limits.h> |
45 | #include <math.h> | | 45 | #include <math.h> |
46 | #include <signal.h> | | 46 | #include <signal.h> |
47 | #include <stdlib.h> | | 47 | #include <stdlib.h> |
48 | #include <string.h> | | 48 | #include <string.h> |
49 | | | 49 | |
50 | #include "lint1.h" | | 50 | #include "lint1.h" |
51 | #include "cgram.h" | | 51 | #include "cgram.h" |
52 | | | 52 | |
53 | static tnode_t *new_integer_constant_node(tspec_t, int64_t); | | 53 | static tnode_t *new_integer_constant_node(tspec_t, int64_t); |
| @@ -524,34 +524,34 @@ build(op_t op, tnode_t *ln, tnode_t *rn) | | | @@ -524,34 +524,34 @@ build(op_t op, tnode_t *ln, tnode_t *rn) |
524 | * Print some warnings for comparisons of unsigned values with | | 524 | * Print some warnings for comparisons of unsigned values with |
525 | * constants lower than or equal to null. This must be done | | 525 | * constants lower than or equal to null. This must be done |
526 | * before promote() because otherwise unsigned char and unsigned | | 526 | * before promote() because otherwise unsigned char and unsigned |
527 | * short would be promoted to int. Also types are tested to be | | 527 | * short would be promoted to int. Also types are tested to be |
528 | * CHAR, which would also become int. | | 528 | * CHAR, which would also become int. |
529 | */ | | 529 | */ |
530 | if (mp->m_comparison) | | 530 | if (mp->m_comparison) |
531 | check_integer_comparison(op, ln, rn); | | 531 | check_integer_comparison(op, ln, rn); |
532 | | | 532 | |
533 | /* | | 533 | /* |
534 | * Promote the left operand if it is in a test or value context | | 534 | * Promote the left operand if it is in a test or value context |
535 | */ | | 535 | */ |
536 | if (mp->m_left_value_context || mp->m_left_test_context) | | 536 | if (mp->m_left_value_context || mp->m_left_test_context) |
537 | ln = promote(op, 0, ln); | | 537 | ln = promote(op, false, ln); |
538 | /* | | 538 | /* |
539 | * Promote the right operand, but only if it is no struct or | | 539 | * Promote the right operand, but only if it is no struct or |
540 | * union member, or if it is not to be assigned to the left operand | | 540 | * union member, or if it is not to be assigned to the left operand |
541 | */ | | 541 | */ |
542 | if (mp->m_binary && op != ARROW && op != POINT && | | 542 | if (mp->m_binary && op != ARROW && op != POINT && |
543 | op != ASSIGN && op != RETURN) { | | 543 | op != ASSIGN && op != RETURN) { |
544 | rn = promote(op, 0, rn); | | 544 | rn = promote(op, false, rn); |
545 | } | | 545 | } |
546 | | | 546 | |
547 | /* | | 547 | /* |
548 | * If the result of the operation is different for signed or | | 548 | * If the result of the operation is different for signed or |
549 | * unsigned operands and one of the operands is signed only in | | 549 | * unsigned operands and one of the operands is signed only in |
550 | * ANSI C, print a warning. | | 550 | * ANSI C, print a warning. |
551 | */ | | 551 | */ |
552 | if (mp->m_warn_if_left_unsigned_in_c90 && | | 552 | if (mp->m_warn_if_left_unsigned_in_c90 && |
553 | ln->tn_op == CON && ln->tn_val->v_ansiu) { | | 553 | ln->tn_op == CON && ln->tn_val->v_ansiu) { |
554 | /* ANSI C treats constant as unsigned, op %s */ | | 554 | /* ANSI C treats constant as unsigned, op %s */ |
555 | warning(218, mp->m_name); | | 555 | warning(218, mp->m_name); |
556 | ln->tn_val->v_ansiu = false; | | 556 | ln->tn_val->v_ansiu = false; |
557 | } | | 557 | } |
| @@ -576,27 +576,27 @@ build(op_t op, tnode_t *ln, tnode_t *rn) | | | @@ -576,27 +576,27 @@ build(op_t op, tnode_t *ln, tnode_t *rn) |
576 | /* And now create the node. */ | | 576 | /* And now create the node. */ |
577 | switch (op) { | | 577 | switch (op) { |
578 | case POINT: | | 578 | case POINT: |
579 | case ARROW: | | 579 | case ARROW: |
580 | ntn = build_struct_access(op, ln, rn); | | 580 | ntn = build_struct_access(op, ln, rn); |
581 | break; | | 581 | break; |
582 | case INCAFT: | | 582 | case INCAFT: |
583 | case DECAFT: | | 583 | case DECAFT: |
584 | case INCBEF: | | 584 | case INCBEF: |
585 | case DECBEF: | | 585 | case DECBEF: |
586 | ntn = build_prepost_incdec(op, ln); | | 586 | ntn = build_prepost_incdec(op, ln); |
587 | break; | | 587 | break; |
588 | case ADDR: | | 588 | case ADDR: |
589 | ntn = build_address(ln, 0); | | 589 | ntn = build_address(ln, false); |
590 | break; | | 590 | break; |
591 | case INDIR: | | 591 | case INDIR: |
592 | ntn = new_tnode(INDIR, ln->tn_type->t_subt, ln, NULL); | | 592 | ntn = new_tnode(INDIR, ln->tn_type->t_subt, ln, NULL); |
593 | break; | | 593 | break; |
594 | case PLUS: | | 594 | case PLUS: |
595 | case MINUS: | | 595 | case MINUS: |
596 | ntn = build_plus_minus(op, ln, rn); | | 596 | ntn = build_plus_minus(op, ln, rn); |
597 | break; | | 597 | break; |
598 | case SHL: | | 598 | case SHL: |
599 | case SHR: | | 599 | case SHR: |
600 | ntn = build_bit_shift(op, ln, rn); | | 600 | ntn = build_bit_shift(op, ln, rn); |
601 | break; | | 601 | break; |
602 | case COLON: | | 602 | case COLON: |
| @@ -694,27 +694,27 @@ cconv(tnode_t *tn) | | | @@ -694,27 +694,27 @@ cconv(tnode_t *tn) |
694 | /* %soperand of '%s' must be lvalue */ | | 694 | /* %soperand of '%s' must be lvalue */ |
695 | gnuism(114, "", modtab[ADDR].m_name); | | 695 | gnuism(114, "", modtab[ADDR].m_name); |
696 | } | | 696 | } |
697 | tn = new_tnode(ADDR, tincref(tn->tn_type->t_subt, PTR), | | 697 | tn = new_tnode(ADDR, tincref(tn->tn_type->t_subt, PTR), |
698 | tn, NULL); | | 698 | tn, NULL); |
699 | } | | 699 | } |
700 | | | 700 | |
701 | /* | | 701 | /* |
702 | * Expression of type function (function with return value of type T) | | 702 | * Expression of type function (function with return value of type T) |
703 | * in rvalue-expression (pointer to function with return value | | 703 | * in rvalue-expression (pointer to function with return value |
704 | * of type T) | | 704 | * of type T) |
705 | */ | | 705 | */ |
706 | if (tn->tn_type->t_tspec == FUNC) | | 706 | if (tn->tn_type->t_tspec == FUNC) |
707 | tn = build_address(tn, 1); | | 707 | tn = build_address(tn, true); |
708 | | | 708 | |
709 | /* lvalue to rvalue */ | | 709 | /* lvalue to rvalue */ |
710 | if (tn->tn_lvalue) { | | 710 | if (tn->tn_lvalue) { |
711 | tp = tduptyp(tn->tn_type); | | 711 | tp = tduptyp(tn->tn_type); |
712 | tp->t_const = tp->t_volatile = false; | | 712 | tp->t_const = tp->t_volatile = false; |
713 | tn = new_tnode(LOAD, tp, tn, NULL); | | 713 | tn = new_tnode(LOAD, tp, tn, NULL); |
714 | } | | 714 | } |
715 | | | 715 | |
716 | return tn; | | 716 | return tn; |
717 | } | | 717 | } |
718 | | | 718 | |
719 | static const tnode_t * | | 719 | static const tnode_t * |
720 | before_conversion(const tnode_t *tn) | | 720 | before_conversion(const tnode_t *tn) |
| @@ -838,27 +838,27 @@ static bool | | | @@ -838,27 +838,27 @@ static bool |
838 | typeok_minus(op_t op, | | 838 | typeok_minus(op_t op, |
839 | const type_t *ltp, tspec_t lt, | | 839 | const type_t *ltp, tspec_t lt, |
840 | const type_t *rtp, tspec_t rt) | | 840 | const type_t *rtp, tspec_t rt) |
841 | { | | 841 | { |
842 | /* operands have scalar types (checked above) */ | | 842 | /* operands have scalar types (checked above) */ |
843 | if (lt == PTR && (!is_integer(rt) && rt != PTR)) { | | 843 | if (lt == PTR && (!is_integer(rt) && rt != PTR)) { |
844 | warn_incompatible_types(op, lt, rt); | | 844 | warn_incompatible_types(op, lt, rt); |
845 | return false; | | 845 | return false; |
846 | } else if (rt == PTR && lt != PTR) { | | 846 | } else if (rt == PTR && lt != PTR) { |
847 | warn_incompatible_types(op, lt, rt); | | 847 | warn_incompatible_types(op, lt, rt); |
848 | return false; | | 848 | return false; |
849 | } | | 849 | } |
850 | if (lt == PTR && rt == PTR) { | | 850 | if (lt == PTR && rt == PTR) { |
851 | if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) { | | 851 | if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { |
852 | /* illegal pointer subtraction */ | | 852 | /* illegal pointer subtraction */ |
853 | error(116); | | 853 | error(116); |
854 | } | | 854 | } |
855 | } | | 855 | } |
856 | return true; | | 856 | return true; |
857 | } | | 857 | } |
858 | | | 858 | |
859 | static void | | 859 | static void |
860 | typeok_shr(const mod_t *mp, | | 860 | typeok_shr(const mod_t *mp, |
861 | const tnode_t *ln, tspec_t lt, | | 861 | const tnode_t *ln, tspec_t lt, |
862 | const tnode_t *rn, tspec_t rt) | | 862 | const tnode_t *rn, tspec_t rt) |
863 | { | | 863 | { |
864 | tspec_t olt, ort; | | 864 | tspec_t olt, ort; |
| @@ -1046,29 +1046,29 @@ typeok_colon(const mod_t *mp, | | | @@ -1046,29 +1046,29 @@ typeok_colon(const mod_t *mp, |
1046 | } | | 1046 | } |
1047 | | | 1047 | |
1048 | if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || | | 1048 | if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || |
1049 | (lst == FUNC && rst == VOID))) { | | 1049 | (lst == FUNC && rst == VOID))) { |
1050 | /* (void *)0 handled above */ | | 1050 | /* (void *)0 handled above */ |
1051 | if (sflag) | | 1051 | if (sflag) |
1052 | /* ANSI C forbids conv. of %s to %s, op %s */ | | 1052 | /* ANSI C forbids conv. of %s to %s, op %s */ |
1053 | warning(305, "function pointer", "'void *'", | | 1053 | warning(305, "function pointer", "'void *'", |
1054 | mp->m_name); | | 1054 | mp->m_name); |
1055 | return true; | | 1055 | return true; |
1056 | } | | 1056 | } |
1057 | | | 1057 | |
1058 | if (rt == PTR && lt == PTR) { | | 1058 | if (rt == PTR && lt == PTR) { |
1059 | if (eqptrtype(lstp, rstp, 1)) | | 1059 | if (eqptrtype(lstp, rstp, true)) |
1060 | return true; | | 1060 | return true; |
1061 | if (!eqtype(lstp, rstp, 1, 0, NULL)) | | 1061 | if (!eqtype(lstp, rstp, true, false, NULL)) |
1062 | warn_incompatible_pointers(mp, ltp, rtp); | | 1062 | warn_incompatible_pointers(mp, ltp, rtp); |
1063 | return true; | | 1063 | return true; |
1064 | } | | 1064 | } |
1065 | | | 1065 | |
1066 | /* incompatible types in conditional */ | | 1066 | /* incompatible types in conditional */ |
1067 | error(126); | | 1067 | error(126); |
1068 | return false; | | 1068 | return false; |
1069 | } | | 1069 | } |
1070 | | | 1070 | |
1071 | static bool | | 1071 | static bool |
1072 | typeok_assign(const mod_t *mp, const tnode_t *ln, const type_t *ltp, tspec_t lt) | | 1072 | typeok_assign(const mod_t *mp, const tnode_t *ln, const type_t *ltp, tspec_t lt) |
1073 | { | | 1073 | { |
1074 | if (!ln->tn_lvalue) { | | 1074 | if (!ln->tn_lvalue) { |
| @@ -1465,27 +1465,27 @@ check_pointer_comparison(op_t op, const | | | @@ -1465,27 +1465,27 @@ check_pointer_comparison(op_t op, const |
1465 | rt = (rtp = rn->tn_type)->t_subt->t_tspec; | | 1465 | rt = (rtp = rn->tn_type)->t_subt->t_tspec; |
1466 | | | 1466 | |
1467 | if (lt == VOID || rt == VOID) { | | 1467 | if (lt == VOID || rt == VOID) { |
1468 | if (sflag && (lt == FUNC || rt == FUNC)) { | | 1468 | if (sflag && (lt == FUNC || rt == FUNC)) { |
1469 | /* (void *)0 already handled in typeok() */ | | 1469 | /* (void *)0 already handled in typeok() */ |
1470 | *(lt == FUNC ? <s : &rts) = "function pointer"; | | 1470 | *(lt == FUNC ? <s : &rts) = "function pointer"; |
1471 | *(lt == VOID ? <s : &rts) = "'void *'"; | | 1471 | *(lt == VOID ? <s : &rts) = "'void *'"; |
1472 | /* ANSI C forbids comparison of %s with %s */ | | 1472 | /* ANSI C forbids comparison of %s with %s */ |
1473 | warning(274, lts, rts); | | 1473 | warning(274, lts, rts); |
1474 | } | | 1474 | } |
1475 | return; | | 1475 | return; |
1476 | } | | 1476 | } |
1477 | | | 1477 | |
1478 | if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) { | | 1478 | if (!eqtype(ltp->t_subt, rtp->t_subt, true, false, NULL)) { |
1479 | warn_incompatible_pointers(&modtab[op], ltp, rtp); | | 1479 | warn_incompatible_pointers(&modtab[op], ltp, rtp); |
1480 | return; | | 1480 | return; |
1481 | } | | 1481 | } |
1482 | | | 1482 | |
1483 | if (lt == FUNC && rt == FUNC) { | | 1483 | if (lt == FUNC && rt == FUNC) { |
1484 | if (sflag && op != EQ && op != NE) | | 1484 | if (sflag && op != EQ && op != NE) |
1485 | /* ANSI C forbids ordered comparisons of ... */ | | 1485 | /* ANSI C forbids ordered comparisons of ... */ |
1486 | warning(125); | | 1486 | warning(125); |
1487 | } | | 1487 | } |
1488 | } | | 1488 | } |
1489 | | | 1489 | |
1490 | /* | | 1490 | /* |
1491 | * Checks type compatibility for ASSIGN, INIT, FARG and RETURN | | 1491 | * Checks type compatibility for ASSIGN, INIT, FARG and RETURN |
| @@ -1538,27 +1538,27 @@ check_assign_types_compatible(op_t op, i | | | @@ -1538,27 +1538,27 @@ check_assign_types_compatible(op_t op, i |
1538 | case FARG: | | 1538 | case FARG: |
1539 | /* ANSI C forbids conv. of %s to %s, arg #%d */ | | 1539 | /* ANSI C forbids conv. of %s to %s, arg #%d */ |
1540 | warning(304, rts, lts, arg); | | 1540 | warning(304, rts, lts, arg); |
1541 | break; | | 1541 | break; |
1542 | default: | | 1542 | default: |
1543 | /* ANSI C forbids conv. of %s to %s, op %s */ | | 1543 | /* ANSI C forbids conv. of %s to %s, op %s */ |
1544 | warning(305, rts, lts, mp->m_name); | | 1544 | warning(305, rts, lts, mp->m_name); |
1545 | break; | | 1545 | break; |
1546 | } | | 1546 | } |
1547 | } | | 1547 | } |
1548 | } | | 1548 | } |
1549 | | | 1549 | |
1550 | if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID || | | 1550 | if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID || |
1551 | eqtype(lstp, rstp, 1, 0, NULL))) { | | 1551 | eqtype(lstp, rstp, true, false, NULL))) { |
1552 | /* compatible pointer types (qualifiers ignored) */ | | 1552 | /* compatible pointer types (qualifiers ignored) */ |
1553 | if (!tflag && | | 1553 | if (!tflag && |
1554 | ((!lstp->t_const && rstp->t_const) || | | 1554 | ((!lstp->t_const && rstp->t_const) || |
1555 | (!lstp->t_volatile && rstp->t_volatile))) { | | 1555 | (!lstp->t_volatile && rstp->t_volatile))) { |
1556 | /* left side has not all qualifiers of right */ | | 1556 | /* left side has not all qualifiers of right */ |
1557 | switch (op) { | | 1557 | switch (op) { |
1558 | case INIT: | | 1558 | case INIT: |
1559 | case RETURN: | | 1559 | case RETURN: |
1560 | /* incompatible pointer types (%s != %s) */ | | 1560 | /* incompatible pointer types (%s != %s) */ |
1561 | warning(182, type_name(lstp), type_name(rstp)); | | 1561 | warning(182, type_name(lstp), type_name(rstp)); |
1562 | break; | | 1562 | break; |
1563 | case FARG: | | 1563 | case FARG: |
1564 | /* argument has incompatible pointer type... */ | | 1564 | /* argument has incompatible pointer type... */ |
| @@ -2042,27 +2042,27 @@ check_prototype_conversion(int arg, tspe | | | @@ -2042,27 +2042,27 @@ check_prototype_conversion(int arg, tspe |
2042 | | | 2042 | |
2043 | if (!is_arithmetic(nt) || !is_arithmetic(ot)) | | 2043 | if (!is_arithmetic(nt) || !is_arithmetic(ot)) |
2044 | return; | | 2044 | return; |
2045 | | | 2045 | |
2046 | /* | | 2046 | /* |
2047 | * If the type of the formal parameter is char/short, a warning | | 2047 | * If the type of the formal parameter is char/short, a warning |
2048 | * would be useless, because functions declared the old style | | 2048 | * would be useless, because functions declared the old style |
2049 | * can't expect char/short arguments. | | 2049 | * can't expect char/short arguments. |
2050 | */ | | 2050 | */ |
2051 | if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT) | | 2051 | if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT) |
2052 | return; | | 2052 | return; |
2053 | | | 2053 | |
2054 | /* get default promotion */ | | 2054 | /* get default promotion */ |
2055 | ptn = promote(NOOP, 1, tn); | | 2055 | ptn = promote(NOOP, true, tn); |
2056 | ot = ptn->tn_type->t_tspec; | | 2056 | ot = ptn->tn_type->t_tspec; |
2057 | | | 2057 | |
2058 | /* return if types are the same with and without prototype */ | | 2058 | /* return if types are the same with and without prototype */ |
2059 | if (nt == ot || (nt == ENUM && ot == INT)) | | 2059 | if (nt == ot || (nt == ENUM && ot == INT)) |
2060 | return; | | 2060 | return; |
2061 | | | 2061 | |
2062 | if (is_floating(nt) != is_floating(ot) || | | 2062 | if (is_floating(nt) != is_floating(ot) || |
2063 | psize(nt) != psize(ot)) { | | 2063 | psize(nt) != psize(ot)) { |
2064 | /* representation and/or width change */ | | 2064 | /* representation and/or width change */ |
2065 | if (!is_integer(ot) || psize(ot) > psize(INT)) { | | 2065 | if (!is_integer(ot) || psize(ot) > psize(INT)) { |
2066 | /* conversion to '%s' due to prototype, arg #%d */ | | 2066 | /* conversion to '%s' due to prototype, arg #%d */ |
2067 | warning(259, type_name(tp), arg); | | 2067 | warning(259, type_name(tp), arg); |
2068 | } | | 2068 | } |
| @@ -2604,27 +2604,27 @@ build_struct_access(op_t op, tnode_t *ln | | | @@ -2604,27 +2604,27 @@ build_struct_access(op_t op, tnode_t *ln |
2604 | bool nolval; | | 2604 | bool nolval; |
2605 | | | 2605 | |
2606 | lint_assert(rn->tn_op == NAME); | | 2606 | lint_assert(rn->tn_op == NAME); |
2607 | lint_assert(rn->tn_sym->s_value.v_tspec == INT); | | 2607 | lint_assert(rn->tn_sym->s_value.v_tspec == INT); |
2608 | lint_assert(rn->tn_sym->s_scl == MOS || rn->tn_sym->s_scl == MOU); | | 2608 | lint_assert(rn->tn_sym->s_scl == MOS || rn->tn_sym->s_scl == MOU); |
2609 | | | 2609 | |
2610 | /* | | 2610 | /* |
2611 | * Remember if the left operand is an lvalue (structure members | | 2611 | * Remember if the left operand is an lvalue (structure members |
2612 | * are lvalues if and only if the structure itself is an lvalue). | | 2612 | * are lvalues if and only if the structure itself is an lvalue). |
2613 | */ | | 2613 | */ |
2614 | nolval = op == POINT && !ln->tn_lvalue; | | 2614 | nolval = op == POINT && !ln->tn_lvalue; |
2615 | | | 2615 | |
2616 | if (op == POINT) { | | 2616 | if (op == POINT) { |
2617 | ln = build_address(ln, 1); | | 2617 | ln = build_address(ln, true); |
2618 | } else if (ln->tn_type->t_tspec != PTR) { | | 2618 | } else if (ln->tn_type->t_tspec != PTR) { |
2619 | lint_assert(tflag); | | 2619 | lint_assert(tflag); |
2620 | lint_assert(is_integer(ln->tn_type->t_tspec)); | | 2620 | lint_assert(is_integer(ln->tn_type->t_tspec)); |
2621 | ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); | | 2621 | ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); |
2622 | } | | 2622 | } |
2623 | | | 2623 | |
2624 | #if PTRDIFF_IS_LONG | | 2624 | #if PTRDIFF_IS_LONG |
2625 | ctn = new_integer_constant_node(LONG, | | 2625 | ctn = new_integer_constant_node(LONG, |
2626 | rn->tn_sym->s_value.v_quad / CHAR_SIZE); | | 2626 | rn->tn_sym->s_value.v_quad / CHAR_SIZE); |
2627 | #else | | 2627 | #else |
2628 | ctn = new_integer_constant_node(INT, | | 2628 | ctn = new_integer_constant_node(INT, |
2629 | rn->tn_sym->s_value.v_quad / CHAR_SIZE); | | 2629 | rn->tn_sym->s_value.v_quad / CHAR_SIZE); |
2630 | #endif | | 2630 | #endif |
| @@ -3250,28 +3250,28 @@ fold_float(tnode_t *tn) | | | @@ -3250,28 +3250,28 @@ fold_float(tnode_t *tn) |
3250 | case GT: | | 3250 | case GT: |
3251 | v->v_quad = (l > r) ? 1 : 0; | | 3251 | v->v_quad = (l > r) ? 1 : 0; |
3252 | break; | | 3252 | break; |
3253 | case EQ: | | 3253 | case EQ: |
3254 | v->v_quad = (l == r) ? 1 : 0; | | 3254 | v->v_quad = (l == r) ? 1 : 0; |
3255 | break; | | 3255 | break; |
3256 | case NE: | | 3256 | case NE: |
3257 | v->v_quad = (l != r) ? 1 : 0; | | 3257 | v->v_quad = (l != r) ? 1 : 0; |
3258 | break; | | 3258 | break; |
3259 | default: | | 3259 | default: |
3260 | lint_assert(/*CONSTCOND*/false); | | 3260 | lint_assert(/*CONSTCOND*/false); |
3261 | } | | 3261 | } |
3262 | | | 3262 | |
3263 | lint_assert(fpe != 0 || isnan((double)v->v_ldbl) == false); | | 3263 | lint_assert(fpe != 0 || isnan((double)v->v_ldbl) == 0); |
3264 | if (fpe != 0 || finite((double)v->v_ldbl) == false || | | 3264 | if (fpe != 0 || finite((double)v->v_ldbl) == 0 || |
3265 | (t == FLOAT && | | 3265 | (t == FLOAT && |
3266 | (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || | | 3266 | (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || |
3267 | (t == DOUBLE && | | 3267 | (t == DOUBLE && |
3268 | (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { | | 3268 | (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { |
3269 | /* floating point overflow detected, op %s */ | | 3269 | /* floating point overflow detected, op %s */ |
3270 | warning(142, modtab[tn->tn_op].m_name); | | 3270 | warning(142, modtab[tn->tn_op].m_name); |
3271 | if (t == FLOAT) { | | 3271 | if (t == FLOAT) { |
3272 | v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; | | 3272 | v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; |
3273 | } else if (t == DOUBLE) { | | 3273 | } else if (t == DOUBLE) { |
3274 | v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; | | 3274 | v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; |
3275 | } else { | | 3275 | } else { |
3276 | v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; | | 3276 | v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; |
3277 | } | | 3277 | } |
| @@ -3624,27 +3624,27 @@ check_function_arguments(type_t *ftp, tn | | | @@ -3624,27 +3624,27 @@ check_function_arguments(type_t *ftp, tn |
3624 | arg->tn_left->tn_type->t_isenum && | | 3624 | arg->tn_left->tn_type->t_isenum && |
3625 | incompl(arg->tn_left->tn_type)) { | | 3625 | incompl(arg->tn_left->tn_type)) { |
3626 | /* argument cannot have unknown size, arg #%d */ | | 3626 | /* argument cannot have unknown size, arg #%d */ |
3627 | warning(152, n); | | 3627 | warning(152, n); |
3628 | } | | 3628 | } |
3629 | | | 3629 | |
3630 | /* class conversions (arg in value context) */ | | 3630 | /* class conversions (arg in value context) */ |
3631 | arg->tn_left = cconv(arg->tn_left); | | 3631 | arg->tn_left = cconv(arg->tn_left); |
3632 | | | 3632 | |
3633 | if (asym != NULL) { | | 3633 | if (asym != NULL) { |
3634 | arg->tn_left = check_prototype_argument( | | 3634 | arg->tn_left = check_prototype_argument( |
3635 | n, asym->s_type, arg->tn_left); | | 3635 | n, asym->s_type, arg->tn_left); |
3636 | } else { | | 3636 | } else { |
3637 | arg->tn_left = promote(NOOP, 1, arg->tn_left); | | 3637 | arg->tn_left = promote(NOOP, true, arg->tn_left); |
3638 | } | | 3638 | } |
3639 | arg->tn_type = arg->tn_left->tn_type; | | 3639 | arg->tn_type = arg->tn_left->tn_type; |
3640 | | | 3640 | |
3641 | if (asym != NULL) | | 3641 | if (asym != NULL) |
3642 | asym = asym->s_next; | | 3642 | asym = asym->s_next; |
3643 | } | | 3643 | } |
3644 | | | 3644 | |
3645 | return args; | | 3645 | return args; |
3646 | } | | 3646 | } |
3647 | | | 3647 | |
3648 | /* | | 3648 | /* |
3649 | * Compare the type of an argument with the corresponding type of a | | 3649 | * Compare the type of an argument with the corresponding type of a |
3650 | * prototype parameter. If it is a valid combination, but both types | | 3650 | * prototype parameter. If it is a valid combination, but both types |
| @@ -3676,27 +3676,27 @@ check_prototype_argument( | | | @@ -3676,27 +3676,27 @@ check_prototype_argument( |
3676 | /* | | 3676 | /* |
3677 | * Return the value of an integral constant expression. | | 3677 | * Return the value of an integral constant expression. |
3678 | * If the expression is not constant or its type is not an integer | | 3678 | * If the expression is not constant or its type is not an integer |
3679 | * type, an error message is printed. | | 3679 | * type, an error message is printed. |
3680 | */ | | 3680 | */ |
3681 | val_t * | | 3681 | val_t * |
3682 | constant(tnode_t *tn, bool required) | | 3682 | constant(tnode_t *tn, bool required) |
3683 | { | | 3683 | { |
3684 | val_t *v; | | 3684 | val_t *v; |
3685 | | | 3685 | |
3686 | if (tn != NULL) | | 3686 | if (tn != NULL) |
3687 | tn = cconv(tn); | | 3687 | tn = cconv(tn); |
3688 | if (tn != NULL) | | 3688 | if (tn != NULL) |
3689 | tn = promote(NOOP, 0, tn); | | 3689 | tn = promote(NOOP, false, tn); |
3690 | | | 3690 | |
3691 | v = xcalloc(1, sizeof (val_t)); | | 3691 | v = xcalloc(1, sizeof (val_t)); |
3692 | | | 3692 | |
3693 | if (tn == NULL) { | | 3693 | if (tn == NULL) { |
3694 | lint_assert(nerr != 0); | | 3694 | lint_assert(nerr != 0); |
3695 | if (dflag) | | 3695 | if (dflag) |
3696 | printf("constant node is null; returning 1 instead\n"); | | 3696 | printf("constant node is null; returning 1 instead\n"); |
3697 | v->v_tspec = INT; | | 3697 | v->v_tspec = INT; |
3698 | v->v_quad = 1; | | 3698 | v->v_quad = 1; |
3699 | return v; | | 3699 | return v; |
3700 | } | | 3700 | } |
3701 | | | 3701 | |
3702 | v->v_tspec = tn->tn_type->t_tspec; | | 3702 | v->v_tspec = tn->tn_type->t_tspec; |
| @@ -3739,27 +3739,27 @@ expr(tnode_t *tn, bool vctx, bool tctx, | | | @@ -3739,27 +3739,27 @@ expr(tnode_t *tn, bool vctx, bool tctx, |
3739 | { | | 3739 | { |
3740 | | | 3740 | |
3741 | lint_assert(tn != NULL || nerr != 0); | | 3741 | lint_assert(tn != NULL || nerr != 0); |
3742 | | | 3742 | |
3743 | if (tn == NULL) { | | 3743 | if (tn == NULL) { |
3744 | tfreeblk(); | | 3744 | tfreeblk(); |
3745 | return; | | 3745 | return; |
3746 | } | | 3746 | } |
3747 | | | 3747 | |
3748 | /* expr() is also called in global initialisations */ | | 3748 | /* expr() is also called in global initialisations */ |
3749 | if (dcs->d_ctx != EXTERN) | | 3749 | if (dcs->d_ctx != EXTERN) |
3750 | check_statement_reachable(); | | 3750 | check_statement_reachable(); |
3751 | | | 3751 | |
3752 | check_expr_misc(tn, vctx, tctx, !tctx, 0, 0, 0); | | 3752 | check_expr_misc(tn, vctx, tctx, !tctx, false, false, false); |
3753 | if (tn->tn_op == ASSIGN) { | | 3753 | if (tn->tn_op == ASSIGN) { |
3754 | if (hflag && tctx) | | 3754 | if (hflag && tctx) |
3755 | /* assignment in conditional context */ | | 3755 | /* assignment in conditional context */ |
3756 | warning(159); | | 3756 | warning(159); |
3757 | } else if (tn->tn_op == CON) { | | 3757 | } else if (tn->tn_op == CON) { |
3758 | if (hflag && tctx && !constcond_flag) | | 3758 | if (hflag && tctx && !constcond_flag) |
3759 | /* constant in conditional context */ | | 3759 | /* constant in conditional context */ |
3760 | warning(161); | | 3760 | warning(161); |
3761 | } | | 3761 | } |
3762 | if (!modtab[tn->tn_op].m_has_side_effect) { | | 3762 | if (!modtab[tn->tn_op].m_has_side_effect) { |
3763 | /* | | 3763 | /* |
3764 | * for left operands of COMMA this warning is already | | 3764 | * for left operands of COMMA this warning is already |
3765 | * printed | | 3765 | * printed |
| @@ -3896,32 +3896,32 @@ check_expr_misc(const tnode_t *tn, bool | | | @@ -3896,32 +3896,32 @@ check_expr_misc(const tnode_t *tn, bool |
3896 | ln = tn->tn_left; | | 3896 | ln = tn->tn_left; |
3897 | rn = tn->tn_right; | | 3897 | rn = tn->tn_right; |
3898 | mp = &modtab[op = tn->tn_op]; | | 3898 | mp = &modtab[op = tn->tn_op]; |
3899 | | | 3899 | |
3900 | switch (op) { | | 3900 | switch (op) { |
3901 | case ADDR: | | 3901 | case ADDR: |
3902 | if (ln->tn_op == NAME && (reached || rchflg)) { | | 3902 | if (ln->tn_op == NAME && (reached || rchflg)) { |
3903 | if (!szof) | | 3903 | if (!szof) |
3904 | mark_as_set(ln->tn_sym); | | 3904 | mark_as_set(ln->tn_sym); |
3905 | mark_as_used(ln->tn_sym, fcall, szof); | | 3905 | mark_as_used(ln->tn_sym, fcall, szof); |
3906 | } | | 3906 | } |
3907 | if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) | | 3907 | if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) |
3908 | /* check the range of array indices */ | | 3908 | /* check the range of array indices */ |
3909 | check_array_index(ln->tn_left, 1); | | 3909 | check_array_index(ln->tn_left, true); |
3910 | break; | | 3910 | break; |
3911 | case LOAD: | | 3911 | case LOAD: |
3912 | if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) | | 3912 | if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) |
3913 | /* check the range of array indices */ | | 3913 | /* check the range of array indices */ |
3914 | check_array_index(ln->tn_left, 0); | | 3914 | check_array_index(ln->tn_left, false); |
3915 | /* FALLTHROUGH */ | | 3915 | /* FALLTHROUGH */ |
3916 | case PUSH: | | 3916 | case PUSH: |
3917 | case INCBEF: | | 3917 | case INCBEF: |
3918 | case DECBEF: | | 3918 | case DECBEF: |
3919 | case INCAFT: | | 3919 | case INCAFT: |
3920 | case DECAFT: | | 3920 | case DECAFT: |
3921 | case ADDASS: | | 3921 | case ADDASS: |
3922 | case SUBASS: | | 3922 | case SUBASS: |
3923 | case MULASS: | | 3923 | case MULASS: |
3924 | case DIVASS: | | 3924 | case DIVASS: |
3925 | case MODASS: | | 3925 | case MODASS: |
3926 | case ANDASS: | | 3926 | case ANDASS: |
3927 | case ORASS: | | 3927 | case ORASS: |
| @@ -3937,38 +3937,38 @@ check_expr_misc(const tnode_t *tn, bool | | | @@ -3937,38 +3937,38 @@ check_expr_misc(const tnode_t *tn, bool |
3937 | * compound statements we are in. If not, we don't | | 3937 | * compound statements we are in. If not, we don't |
3938 | * print a warning. | | 3938 | * print a warning. |
3939 | */ | | 3939 | */ |
3940 | for (di = dcs; di != NULL; di = di->d_next) { | | 3940 | for (di = dcs; di != NULL; di = di->d_next) { |
3941 | if (di->d_asm) | | 3941 | if (di->d_asm) |
3942 | break; | | 3942 | break; |
3943 | } | | 3943 | } |
3944 | if (sc != EXTERN && sc != STATIC && | | 3944 | if (sc != EXTERN && sc != STATIC && |
3945 | !ln->tn_sym->s_set && !szof && di == NULL) { | | 3945 | !ln->tn_sym->s_set && !szof && di == NULL) { |
3946 | /* %s may be used before set */ | | 3946 | /* %s may be used before set */ |
3947 | warning(158, ln->tn_sym->s_name); | | 3947 | warning(158, ln->tn_sym->s_name); |
3948 | mark_as_set(ln->tn_sym); | | 3948 | mark_as_set(ln->tn_sym); |
3949 | } | | 3949 | } |
3950 | mark_as_used(ln->tn_sym, 0, 0); | | 3950 | mark_as_used(ln->tn_sym, false, false); |
3951 | } | | 3951 | } |
3952 | break; | | 3952 | break; |
3953 | case ASSIGN: | | 3953 | case ASSIGN: |
3954 | if (ln->tn_op == NAME && !szof && (reached || rchflg)) { | | 3954 | if (ln->tn_op == NAME && !szof && (reached || rchflg)) { |
3955 | mark_as_set(ln->tn_sym); | | 3955 | mark_as_set(ln->tn_sym); |
3956 | if (ln->tn_sym->s_scl == EXTERN) | | 3956 | if (ln->tn_sym->s_scl == EXTERN) |
3957 | outusg(ln->tn_sym); | | 3957 | outusg(ln->tn_sym); |
3958 | } | | 3958 | } |
3959 | if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) | | 3959 | if (ln->tn_op == INDIR && ln->tn_left->tn_op == PLUS) |
3960 | /* check the range of array indices */ | | 3960 | /* check the range of array indices */ |
3961 | check_array_index(ln->tn_left, 0); | | 3961 | check_array_index(ln->tn_left, false); |
3962 | break; | | 3962 | break; |
3963 | case CALL: | | 3963 | case CALL: |
3964 | lint_assert(ln->tn_op == ADDR); | | 3964 | lint_assert(ln->tn_op == ADDR); |
3965 | lint_assert(ln->tn_left->tn_op == NAME); | | 3965 | lint_assert(ln->tn_left->tn_op == NAME); |
3966 | if (!szof) | | 3966 | if (!szof) |
3967 | outcall(tn, vctx || tctx, rvdisc); | | 3967 | outcall(tn, vctx || tctx, rvdisc); |
3968 | break; | | 3968 | break; |
3969 | case EQ: | | 3969 | case EQ: |
3970 | if (hflag && eqwarn) | | 3970 | if (hflag && eqwarn) |
3971 | /* operator '==' found where '=' was expected */ | | 3971 | /* operator '==' found where '=' was expected */ |
3972 | warning(160); | | 3972 | warning(160); |
3973 | break; | | 3973 | break; |
3974 | case CON: | | 3974 | case CON: |
| @@ -4022,41 +4022,41 @@ check_expr_misc(const tnode_t *tn, bool | | | @@ -4022,41 +4022,41 @@ check_expr_misc(const tnode_t *tn, bool |
4022 | * values of operands of ':' are not used if the type of at least | | 4022 | * values of operands of ':' are not used if the type of at least |
4023 | * one of the operands (for gcc compatibility) is void | | 4023 | * one of the operands (for gcc compatibility) is void |
4024 | * XXX test/value context of QUEST should probably be used as | | 4024 | * XXX test/value context of QUEST should probably be used as |
4025 | * context for both operands of COLON | | 4025 | * context for both operands of COLON |
4026 | */ | | 4026 | */ |
4027 | if (op == COLON && tn->tn_type->t_tspec == VOID) | | 4027 | if (op == COLON && tn->tn_type->t_tspec == VOID) |
4028 | cvctx = ctctx = false; | | 4028 | cvctx = ctctx = false; |
4029 | nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; | | 4029 | nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; |
4030 | check_expr_misc(ln, cvctx, ctctx, mp->m_warn_if_operand_eq, op == CALL, nrvdisc, szof); | | 4030 | check_expr_misc(ln, cvctx, ctctx, mp->m_warn_if_operand_eq, op == CALL, nrvdisc, szof); |
4031 | | | 4031 | |
4032 | switch (op) { | | 4032 | switch (op) { |
4033 | case PUSH: | | 4033 | case PUSH: |
4034 | if (rn != NULL) | | 4034 | if (rn != NULL) |
4035 | check_expr_misc(rn, 0, 0, mp->m_warn_if_operand_eq, 0, 0, szof); | | 4035 | check_expr_misc(rn, false, false, mp->m_warn_if_operand_eq, false, false, szof); |
4036 | break; | | 4036 | break; |
4037 | case LOGAND: | | 4037 | case LOGAND: |
4038 | case LOGOR: | | 4038 | case LOGOR: |
4039 | check_expr_misc(rn, 0, 1, mp->m_warn_if_operand_eq, 0, 0, szof); | | 4039 | check_expr_misc(rn, false, true, mp->m_warn_if_operand_eq, false, false, szof); |
4040 | break; | | 4040 | break; |
4041 | case COLON: | | 4041 | case COLON: |
4042 | check_expr_misc(rn, cvctx, ctctx, mp->m_warn_if_operand_eq, 0, 0, szof); | | 4042 | check_expr_misc(rn, cvctx, ctctx, mp->m_warn_if_operand_eq, false, false, szof); |
4043 | break; | | 4043 | break; |
4044 | case COMMA: | | 4044 | case COMMA: |
4045 | check_expr_misc(rn, vctx, tctx, mp->m_warn_if_operand_eq, 0, 0, szof); | | 4045 | check_expr_misc(rn, vctx, tctx, mp->m_warn_if_operand_eq, false, false, szof); |
4046 | break; | | 4046 | break; |
4047 | default: | | 4047 | default: |
4048 | if (mp->m_binary) | | 4048 | if (mp->m_binary) |
4049 | check_expr_misc(rn, 1, 0, mp->m_warn_if_operand_eq, 0, 0, szof); | | 4049 | check_expr_misc(rn, true, false, mp->m_warn_if_operand_eq, false, false, szof); |
4050 | break; | | 4050 | break; |
4051 | } | | 4051 | } |
4052 | | | 4052 | |
4053 | } | | 4053 | } |
4054 | | | 4054 | |
4055 | /* | | 4055 | /* |
4056 | * Checks the range of array indices, if possible. | | 4056 | * Checks the range of array indices, if possible. |
4057 | * amper is set if only the address of the element is used. This | | 4057 | * amper is set if only the address of the element is used. This |
4058 | * means that the index is allowed to refer to the first element | | 4058 | * means that the index is allowed to refer to the first element |
4059 | * after the array. | | 4059 | * after the array. |
4060 | */ | | 4060 | */ |
4061 | static void | | 4061 | static void |
4062 | check_array_index(tnode_t *tn, bool amper) | | 4062 | check_array_index(tnode_t *tn, bool amper) |