| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: tree.c,v 1.75 2014/02/18 22:01:36 christos Exp $ */ | | 1 | /* $NetBSD: tree.c,v 1.76 2014/04/17 18:23:18 christos 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.75 2014/02/18 22:01:36 christos Exp $"); | | 40 | __RCSID("$NetBSD: tree.c,v 1.76 2014/04/17 18:23:18 christos Exp $"); |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #include <stdlib.h> | | 43 | #include <stdlib.h> |
44 | #include <string.h> | | 44 | #include <string.h> |
45 | #include <float.h> | | 45 | #include <float.h> |
46 | #include <limits.h> | | 46 | #include <limits.h> |
47 | #include <math.h> | | 47 | #include <math.h> |
48 | #include <signal.h> | | 48 | #include <signal.h> |
49 | | | 49 | |
50 | #include "lint1.h" | | 50 | #include "lint1.h" |
51 | #include "cgram.h" | | 51 | #include "cgram.h" |
52 | #include "externs1.h" | | 52 | #include "externs1.h" |
53 | | | 53 | |
| @@ -79,26 +79,65 @@ static tnode_t *plength(type_t *); | | | @@ -79,26 +79,65 @@ static tnode_t *plength(type_t *); |
79 | static tnode_t *fold(tnode_t *); | | 79 | static tnode_t *fold(tnode_t *); |
80 | static tnode_t *foldtst(tnode_t *); | | 80 | static tnode_t *foldtst(tnode_t *); |
81 | static tnode_t *foldflt(tnode_t *); | | 81 | static tnode_t *foldflt(tnode_t *); |
82 | static tnode_t *chkfarg(type_t *, tnode_t *); | | 82 | static tnode_t *chkfarg(type_t *, tnode_t *); |
83 | static tnode_t *parg(int, type_t *, tnode_t *); | | 83 | static tnode_t *parg(int, type_t *, tnode_t *); |
84 | static void nulleff(tnode_t *); | | 84 | static void nulleff(tnode_t *); |
85 | static void displexpr(tnode_t *, int); | | 85 | static void displexpr(tnode_t *, int); |
86 | static void chkaidx(tnode_t *, int); | | 86 | static void chkaidx(tnode_t *, int); |
87 | static void chkcomp(op_t, tnode_t *, tnode_t *); | | 87 | static void chkcomp(op_t, tnode_t *, tnode_t *); |
88 | static void precconf(tnode_t *); | | 88 | static void precconf(tnode_t *); |
89 | | | 89 | |
90 | extern sig_atomic_t fpe; | | 90 | extern sig_atomic_t fpe; |
91 | | | 91 | |
| | | 92 | #if 0 |
| | | 93 | static char * |
| | | 94 | dumpnode(char *buf, size_t len, tnode_t *tn) { |
| | | 95 | const char *n = getopname(tn->tn_op); |
| | | 96 | const char *s; |
| | | 97 | char tbuf[256]; |
| | | 98 | |
| | | 99 | switch (tn->tn_op) { |
| | | 100 | case NAME: |
| | | 101 | s = tn->tn_sym->s_name; |
| | | 102 | break; |
| | | 103 | case CON: |
| | | 104 | case STRING: |
| | | 105 | s = "*"; /* todo */ |
| | | 106 | break; |
| | | 107 | default: |
| | | 108 | s = NULL; |
| | | 109 | break; |
| | | 110 | } |
| | | 111 | char lb[1024]; |
| | | 112 | char rb[1024]; |
| | | 113 | |
| | | 114 | if (s == NULL && tn->tn_left != NULL) |
| | | 115 | dumpnode(lb, sizeof(lb), tn->tn_left); |
| | | 116 | else |
| | | 117 | strcpy(lb, "(null)"); |
| | | 118 | |
| | | 119 | if (s == NULL && tn->tn_right != NULL) |
| | | 120 | dumpnode(rb, sizeof(rb), tn->tn_right); |
| | | 121 | else |
| | | 122 | strcpy(rb, "(null)"); |
| | | 123 | |
| | | 124 | |
| | | 125 | snprintf(buf, len, "%s: (%s) = %s [%s, %s]", n, |
| | | 126 | tyname(tbuf, sizeof(tbuf), tn->tn_type), s, lb, rb); |
| | | 127 | return buf; |
| | | 128 | } |
| | | 129 | #endif |
| | | 130 | |
92 | /* | | 131 | /* |
93 | * Increase degree of reference. | | 132 | * Increase degree of reference. |
94 | * This is most often used to change type "T" in type "pointer to T". | | 133 | * This is most often used to change type "T" in type "pointer to T". |
95 | */ | | 134 | */ |
96 | type_t * | | 135 | type_t * |
97 | incref(type_t *tp, tspec_t t) | | 136 | incref(type_t *tp, tspec_t t) |
98 | { | | 137 | { |
99 | type_t *tp2; | | 138 | type_t *tp2; |
100 | | | 139 | |
101 | tp2 = getblk(sizeof (type_t)); | | 140 | tp2 = getblk(sizeof (type_t)); |
102 | tp2->t_tspec = t; | | 141 | tp2->t_tspec = t; |
103 | tp2->t_subt = tp; | | 142 | tp2->t_subt = tp; |
104 | return (tp2); | | 143 | return (tp2); |
| @@ -194,27 +233,27 @@ getnnode(sym_t *sym, int ntok) | | | @@ -194,27 +233,27 @@ getnnode(sym_t *sym, int ntok) |
194 | } else { | | 233 | } else { |
195 | error(99, sym->s_name); | | 234 | error(99, sym->s_name); |
196 | fixtype = 0; | | 235 | fixtype = 0; |
197 | } | | 236 | } |
198 | if (fixtype) { | | 237 | if (fixtype) { |
199 | sym->s_type = incref(gettyp(CHAR), PTR); | | 238 | sym->s_type = incref(gettyp(CHAR), PTR); |
200 | sym->s_type->t_const = 1; | | 239 | sym->s_type->t_const = 1; |
201 | } | | 240 | } |
202 | } | | 241 | } |
203 | } | | 242 | } |
204 | } | | 243 | } |
205 | | | 244 | |
206 | if (sym->s_kind != FVFT && sym->s_kind != FMOS) | | 245 | if (sym->s_kind != FVFT && sym->s_kind != FMOS) |
207 | LERROR("getnnode()"); | | 246 | LERROR("getnnode(%d)", sym->s_kind); |
208 | | | 247 | |
209 | n = getnode(); | | 248 | n = getnode(); |
210 | n->tn_type = sym->s_type; | | 249 | n->tn_type = sym->s_type; |
211 | if (sym->s_scl != ENUMCON) { | | 250 | if (sym->s_scl != ENUMCON) { |
212 | n->tn_op = NAME; | | 251 | n->tn_op = NAME; |
213 | n->tn_sym = sym; | | 252 | n->tn_sym = sym; |
214 | if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) | | 253 | if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) |
215 | n->tn_lvalue = 1; | | 254 | n->tn_lvalue = 1; |
216 | } else { | | 255 | } else { |
217 | n->tn_op = CON; | | 256 | n->tn_op = CON; |
218 | n->tn_val = tgetblk(sizeof (val_t)); | | 257 | n->tn_val = tgetblk(sizeof (val_t)); |
219 | *n->tn_val = sym->s_value; | | 258 | *n->tn_val = sym->s_value; |
220 | } | | 259 | } |
| @@ -1606,50 +1645,48 @@ balance(op_t op, tnode_t **lnp, tnode_t | | | @@ -1606,50 +1645,48 @@ balance(op_t op, tnode_t **lnp, tnode_t |
1606 | } | | 1645 | } |
1607 | | | 1646 | |
1608 | /* | | 1647 | /* |
1609 | * Insert a conversion operator, which converts the type of the node | | 1648 | * Insert a conversion operator, which converts the type of the node |
1610 | * to another given type. | | 1649 | * to another given type. |
1611 | * If op is FARG, arg is the number of the argument (used for warnings). | | 1650 | * If op is FARG, arg is the number of the argument (used for warnings). |
1612 | */ | | 1651 | */ |
1613 | tnode_t * | | 1652 | tnode_t * |
1614 | convert(op_t op, int arg, type_t *tp, tnode_t *tn) | | 1653 | convert(op_t op, int arg, type_t *tp, tnode_t *tn) |
1615 | { | | 1654 | { |
1616 | tnode_t *ntn; | | 1655 | tnode_t *ntn; |
1617 | tspec_t nt, ot, ost = NOTSPEC; | | 1656 | tspec_t nt, ot, ost = NOTSPEC; |
1618 | | | 1657 | |
1619 | if (tn->tn_lvalue) | | | |
1620 | LERROR("convert()"); | | | |
1621 | | | | |
1622 | nt = tp->t_tspec; | | 1658 | nt = tp->t_tspec; |
1623 | if ((ot = tn->tn_type->t_tspec) == PTR) | | 1659 | if ((ot = tn->tn_type->t_tspec) == PTR) |
1624 | ost = tn->tn_type->t_subt->t_tspec; | | 1660 | ost = tn->tn_type->t_subt->t_tspec; |
1625 | | | 1661 | |
1626 | if (!tflag && !sflag && op == FARG) | | 1662 | if (!tflag && !sflag && op == FARG) |
1627 | ptconv(arg, nt, ot, tp, tn); | | 1663 | ptconv(arg, nt, ot, tp, tn); |
1628 | if (isityp(nt) && isityp(ot)) { | | 1664 | if (isityp(nt) && isityp(ot)) { |
1629 | iiconv(op, arg, nt, ot, tp, tn); | | 1665 | iiconv(op, arg, nt, ot, tp, tn); |
1630 | } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) && | | 1666 | } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) && |
1631 | tn->tn_op == CON && tn->tn_val->v_quad == 0) { | | 1667 | tn->tn_op == CON && tn->tn_val->v_quad == 0) { |
1632 | /* 0, 0L and (void *)0 may be assigned to any pointer. */ | | 1668 | /* 0, 0L and (void *)0 may be assigned to any pointer. */ |
1633 | } else if (isityp(nt) && ot == PTR) { | | 1669 | } else if (isityp(nt) && ot == PTR) { |
1634 | piconv(op, nt, tp, tn); | | 1670 | piconv(op, nt, tp, tn); |
1635 | } else if (nt == PTR && ot == PTR) { | | 1671 | } else if (nt == PTR && ot == PTR) { |
1636 | ppconv(op, tn, tp); | | 1672 | ppconv(op, tn, tp); |
1637 | } | | 1673 | } |
1638 | | | 1674 | |
1639 | ntn = getnode(); | | 1675 | ntn = getnode(); |
1640 | ntn->tn_op = CVT; | | 1676 | ntn->tn_op = CVT; |
1641 | ntn->tn_type = tp; | | 1677 | ntn->tn_type = tp; |
1642 | ntn->tn_cast = op == CVT; | | 1678 | ntn->tn_cast = op == CVT; |
| | | 1679 | ntn->tn_right = NULL; |
1643 | if (tn->tn_op != CON || nt == VOID) { | | 1680 | if (tn->tn_op != CON || nt == VOID) { |
1644 | ntn->tn_left = tn; | | 1681 | ntn->tn_left = tn; |
1645 | } else { | | 1682 | } else { |
1646 | ntn->tn_op = CON; | | 1683 | ntn->tn_op = CON; |
1647 | ntn->tn_val = tgetblk(sizeof (val_t)); | | 1684 | ntn->tn_val = tgetblk(sizeof (val_t)); |
1648 | cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val); | | 1685 | cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val); |
1649 | } | | 1686 | } |
1650 | | | 1687 | |
1651 | return (ntn); | | 1688 | return (ntn); |
1652 | } | | 1689 | } |
1653 | | | 1690 | |
1654 | /* | | 1691 | /* |
1655 | * Print a warning if a prototype causes a type conversion that is | | 1692 | * Print a warning if a prototype causes a type conversion that is |
| @@ -3559,27 +3596,29 @@ chkmisc(tnode_t *tn, int vctx, int tctx, | | | @@ -3559,27 +3596,29 @@ chkmisc(tnode_t *tn, int vctx, int tctx, |
3559 | break; | | 3596 | break; |
3560 | case ASSIGN: | | 3597 | case ASSIGN: |
3561 | if (ln->tn_op == NAME && !szof && (reached || rchflg)) { | | 3598 | if (ln->tn_op == NAME && !szof && (reached || rchflg)) { |
3562 | setsflg(ln->tn_sym); | | 3599 | setsflg(ln->tn_sym); |
3563 | if (ln->tn_sym->s_scl == EXTERN) | | 3600 | if (ln->tn_sym->s_scl == EXTERN) |
3564 | outusg(ln->tn_sym); | | 3601 | outusg(ln->tn_sym); |
3565 | } | | 3602 | } |
3566 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | | 3603 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) |
3567 | /* check the range of array indices */ | | 3604 | /* check the range of array indices */ |
3568 | chkaidx(ln->tn_left, 0); | | 3605 | chkaidx(ln->tn_left, 0); |
3569 | break; | | 3606 | break; |
3570 | case CALL: | | 3607 | case CALL: |
3571 | if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) | | 3608 | if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) |
3572 | LERROR("chkmisc()"); | | 3609 | LERROR("chkmisc(op=%s != %s || %s != %s)", |
| | | 3610 | getopname(ln->tn_op), getopname(AMPER), |
| | | 3611 | getopname(ln->tn_left->tn_op), getopname(NAME)); |
3573 | if (!szof) | | 3612 | if (!szof) |
3574 | outcall(tn, vctx || tctx, rvdisc); | | 3613 | outcall(tn, vctx || tctx, rvdisc); |
3575 | break; | | 3614 | break; |
3576 | case EQ: | | 3615 | case EQ: |
3577 | /* equality operator "==" found where "=" was exp. */ | | 3616 | /* equality operator "==" found where "=" was exp. */ |
3578 | if (hflag && eqwarn) | | 3617 | if (hflag && eqwarn) |
3579 | warning(160); | | 3618 | warning(160); |
3580 | break; | | 3619 | break; |
3581 | case CON: | | 3620 | case CON: |
3582 | case NAME: | | 3621 | case NAME: |
3583 | case STRING: | | 3622 | case STRING: |
3584 | return; | | 3623 | return; |
3585 | /* LINTED206: (enumeration values not handled in switch) */ | | 3624 | /* LINTED206: (enumeration values not handled in switch) */ |