Mon Jan 4 22:41:56 2021 UTC ()
lint: finish the comments in check_precedence_confusion


(rillig)
diff -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_169.c
diff -r1.128 -r1.129 src/usr.bin/xlint/lint1/tree.c

cvs diff -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/msg_169.c (switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_169.c 2021/01/04 15:52:51 1.2
+++ src/tests/usr.bin/xlint/lint1/msg_169.c 2021/01/04 22:41:56 1.3
@@ -1,150 +1,151 @@ @@ -1,150 +1,151 @@
1/* $NetBSD: msg_169.c,v 1.2 2021/01/04 15:52:51 rillig Exp $ */ 1/* $NetBSD: msg_169.c,v 1.3 2021/01/04 22:41:56 rillig Exp $ */
2# 3 "msg_169.c" 2# 3 "msg_169.c"
3 3
4// Test for message: precedence confusion possible: parenthesize! [169] 4// Test for message: precedence confusion possible: parenthesize! [169]
5 5
6/* lint1-flags: -g -h -S -w */ 6/* lint1-flags: -g -h -S -w */
7 7
8typedef _Bool bool; 8typedef _Bool bool;
9 9
10void 10void
11confusing_shift_arith(unsigned a, unsigned b, unsigned c, unsigned char ch) 11confusing_shift_arith(unsigned a, unsigned b, unsigned c, unsigned char ch)
12{ 12{
13 unsigned con, okl, okr; 13 unsigned con, okl, okr;
14 14
15 con = a + b << c; 15 con = a + b << c;
16 okl = (a + b) << c; 16 okl = (a + b) << c;
17 okr = a + (b << c); 17 okr = a + (b << c);
18 18
19 con = a << b + c; 19 con = a << b + c;
20 okl = (a << b) + c; 20 okl = (a << b) + c;
21 okr = a << (b + c); 21 okr = a << (b + c);
22 22
23 con = a - b >> c; 23 con = a - b >> c;
24 okl = (a - b) >> c; 24 okl = (a - b) >> c;
25 okr = a - (b >> c); 25 okr = a - (b >> c);
26 26
27 con = a >> b - c; 27 con = a >> b - c;
28 okl = (a >> b) - c; 28 okl = (a >> b) - c;
29 okr = a >> (b - c); 29 okr = a >> (b - c);
30 30
31 // Parenthesizing the inner operands has no effect on the warning. 31 // Parenthesizing the inner operands has no effect on the warning.
32 con = (a) + b << c; 32 con = (a) + b << c;
33 con = a + (b) << c; 33 con = a + (b) << c;
34 con = a + b << (c); 34 con = a + b << (c);
35 35
36 // The usual arithmetic promotions have no effect on the warning. 36 // The usual arithmetic promotions have no effect on the warning.
37 con = ch + b << c; 37 con = ch + b << c;
38 con = a + ch << c; 38 con = a + ch << c;
39 con = a + b << ch; 39 con = a + b << ch;
40} 40}
41 41
42void 42void
43confusing_logical(bool a, bool b, bool c) 43confusing_logical(bool a, bool b, bool c)
44{ 44{
45 bool con, okl, okr, eql; 45 bool con, okl, okr, eql;
46 46
47 eql = a && b && c; 47 eql = a && b && c;
48 eql = a || b || c; 48 eql = a || b || c;
49 49
50 con = a && b || c; 50 con = a && b || c;
51 okl = (a && b) || c; 51 okl = (a && b) || c;
52 okr = a && (b || c); 52 okr = a && (b || c);
53 53
54 con = a || b && c; 54 con = a || b && c;
55 okl = (a || b) && c; 55 okl = (a || b) && c;
56 okr = a || (b && c); 56 okr = a || (b && c);
57} 57}
58 58
59void 59void
60confusing_bitwise(unsigned a, unsigned b, unsigned c) 60confusing_bitwise(unsigned a, unsigned b, unsigned c)
61{ 61{
62 bool con, okl, okr, eql; 62 bool con, okl, okr, eql;
63 63
64 eql = a & b & c; 64 eql = a & b & c;
65 eql = a | b | c; 65 eql = a | b | c;
66 eql = a ^ b ^ c; 66 eql = a ^ b ^ c;
67 67
68 con = a | b ^ c; 68 con = a | b ^ c;
69 okl = (a | b) ^ c; 69 okl = (a | b) ^ c;
70 okr = a | (b ^ c); 70 okr = a | (b ^ c);
71 71
72 con = a | b & c; 72 con = a | b & c;
73 okl = (a | b) & c; 73 okl = (a | b) & c;
74 okr = a | (b & c); 74 okr = a | (b & c);
75 75
76 con = a ^ b | c; 76 con = a ^ b | c;
77 okl = (a ^ b) | c; 77 okl = (a ^ b) | c;
78 okr = a ^ (b | c); 78 okr = a ^ (b | c);
79 79
80 con = a ^ b & c; 80 con = a ^ b & c;
81 okl = (a ^ b) & c; 81 okl = (a ^ b) & c;
82 okr = a ^ (b & c); 82 okr = a ^ (b & c);
83 83
84 con = a & b | c; 84 con = a & b | c;
85 okl = (a & b) ^ c; 85 okl = (a & b) ^ c;
86 okr = a & (b ^ c); 86 okr = a & (b ^ c);
87 87
88 con = a & b ^ c; 88 con = a & b ^ c;
89 okl = (a & b) ^ c; 89 okl = (a & b) ^ c;
90 okr = a & (b ^ c); 90 okr = a & (b ^ c);
91 91
92 con = a & b + c; 92 con = a & b + c;
93 okl = (a & b) + c; 93 okl = (a & b) + c;
94 okr = a & (b + c); 94 okr = a & (b + c);
95 95
96 con = a - b | c; 96 con = a - b | c;
97 okl = (a - b) | c; 97 okl = (a - b) | c;
98 okr = a - (b | c); 98 okr = a - (b | c);
99 99
100 // This looks like a binomial formula but isn't. 100 // This looks like a binomial formula but isn't.
101 con = a ^ 2 - 2 * a * b + b ^ 2; 101 con = a ^ 2 - 2 * a * b + b ^ 2;
102 102
103 // This isn't a binomial formula either since '^' means xor. 103 // This isn't a binomial formula either since '^' means xor.
104 con = (a ^ 2) - 2 * a * b + (b ^ 2); 104 con = (a ^ 2) - 2 * a * b + (b ^ 2);
105} 105}
106 106
107void 107void
108constant_expressions(void) 108constant_expressions(void)
109{ 109{
110 unsigned con; 110 unsigned con;
111 111
112 // The check for confusing precedence happens after constant folding. 112 // The check for confusing precedence happens after constant folding.
113 // Therefore the following lines do not generate warnings. 113 // Therefore the following lines do not generate warnings.
114 con = 1 & 2 | 3; 114 con = 1 & 2 | 3;
115 con = 4 << 5 + 6; 115 con = 4 << 5 + 6;
116 con = 7 ^ 8 & 9; 116 con = 7 ^ 8 & 9;
117} 117}
118 118
119void 119void
120cast_expressions(char a, char b, char c) 120cast_expressions(char a, char b, char c)
121{ 121{
122 unsigned con; 122 unsigned con;
123 123
124 // Adding casts to the leaf nodes doesn't change anything about the 124 // Adding casts to the leaf nodes doesn't change anything about the
125 // confusing precedence. 125 // confusing precedence.
126 con = (unsigned)a | (unsigned)b & (unsigned)c; 126 con = (unsigned)a | (unsigned)b & (unsigned)c;
127 con = (unsigned)a & (unsigned)b | (unsigned)c; 127 con = (unsigned)a & (unsigned)b | (unsigned)c;
128 128
129 // Adding a cast around the whole calculation doesn't change the 129 // Adding a cast around the whole calculation doesn't change the
130 // precedence as well. 130 // precedence as well.
131 con = (unsigned)(a | b & c); 131 con = (unsigned)(a | b & c);
132 132
133 // Adding a cast around an intermediate result groups the operands 133 // Adding a cast around an intermediate result groups the operands
134 // of the main node, which prevents any confusion about precedence. 134 // of the main node, which prevents any confusion about precedence.
135 con = (unsigned)a | (unsigned)(b & c); 135 con = (unsigned)a | (unsigned)(b & c);
136 con = a | (unsigned)(b & c); 136 con = a | (unsigned)(b & c);
137 con = (unsigned)(a | b) & (unsigned)c; 137 con = (unsigned)(a | b) & (unsigned)c;
138 con = (unsigned)(a | b) & c; 138 con = (unsigned)(a | b) & c;
139} 139}
140 140
141void 141void
142expected_precedence(int a, int b, int c) 142expected_precedence(int a, int b, int c)
143{ 143{
144 int ok; 144 int ok;
145 145
146 ok = a + b * c; 146 ok = a + b * c;
147} 147}
148 148
149// TODO: add a test with unsigned long instead of unsigned, to demonstrate 149// TODO: add a test with unsigned long instead of unsigned, trying to
150// that the typo in 150// demonstrate that the typo in check_precedence_confusion actually has an
 151// effect.

cvs diff -r1.128 -r1.129 src/usr.bin/xlint/lint1/tree.c (switch to unified diff)

--- src/usr.bin/xlint/lint1/tree.c 2021/01/04 22:33:47 1.128
+++ src/usr.bin/xlint/lint1/tree.c 2021/01/04 22:41:56 1.129
@@ -1,1039 +1,1039 @@ @@ -1,1039 +1,1039 @@
1/* $NetBSD: tree.c,v 1.128 2021/01/04 22:33:47 rillig Exp $ */ 1/* $NetBSD: tree.c,v 1.129 2021/01/04 22:41:56 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.
15 * 3. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project. 18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products 19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission. 20 * derived from this software without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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.128 2021/01/04 22:33:47 rillig Exp $"); 40__RCSID("$NetBSD: tree.c,v 1.129 2021/01/04 22:41:56 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
53static tnode_t *new_integer_constant_node(tspec_t, int64_t); 53static tnode_t *new_integer_constant_node(tspec_t, int64_t);
54static void check_pointer_comparison(op_t, tnode_t *, tnode_t *); 54static void check_pointer_comparison(op_t, tnode_t *, tnode_t *);
55static int check_assign_types_compatible(op_t, int, tnode_t *, tnode_t *); 55static int check_assign_types_compatible(op_t, int, tnode_t *, tnode_t *);
56static void check_bad_enum_operation(op_t, tnode_t *, tnode_t *); 56static void check_bad_enum_operation(op_t, tnode_t *, tnode_t *);
57static void check_enum_type_mismatch(op_t, int, tnode_t *, tnode_t *); 57static void check_enum_type_mismatch(op_t, int, tnode_t *, tnode_t *);
58static void check_enum_int_mismatch(op_t, int, tnode_t *, tnode_t *); 58static void check_enum_int_mismatch(op_t, int, tnode_t *, tnode_t *);
59static tnode_t *new_tnode(op_t, type_t *, tnode_t *, tnode_t *); 59static tnode_t *new_tnode(op_t, type_t *, tnode_t *, tnode_t *);
60static void balance(op_t, tnode_t **, tnode_t **); 60static void balance(op_t, tnode_t **, tnode_t **);
61static void warn_incompatible_types(op_t, tspec_t, tspec_t); 61static void warn_incompatible_types(op_t, tspec_t, tspec_t);
62static void warn_incompatible_pointers(mod_t *, type_t *, type_t *); 62static void warn_incompatible_pointers(mod_t *, type_t *, type_t *);
63static void merge_qualifiers(type_t **, type_t *, type_t *); 63static void merge_qualifiers(type_t **, type_t *, type_t *);
64static int has_constant_member(type_t *); 64static int has_constant_member(type_t *);
65static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *, 65static void check_prototype_conversion(int, tspec_t, tspec_t, type_t *,
66 tnode_t *); 66 tnode_t *);
67static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *, 67static void check_integer_conversion(op_t, int, tspec_t, tspec_t, type_t *,
68 tnode_t *); 68 tnode_t *);
69static void check_pointer_integer_conversion(op_t, tspec_t, type_t *, 69static void check_pointer_integer_conversion(op_t, tspec_t, type_t *,
70 tnode_t *); 70 tnode_t *);
71static void check_pointer_conversion(op_t, tnode_t *, type_t *); 71static void check_pointer_conversion(op_t, tnode_t *, type_t *);
72static tnode_t *build_struct_access(op_t, tnode_t *, tnode_t *); 72static tnode_t *build_struct_access(op_t, tnode_t *, tnode_t *);
73static tnode_t *build_prepost_incdec(op_t, tnode_t *); 73static tnode_t *build_prepost_incdec(op_t, tnode_t *);
74static tnode_t *build_real_imag(op_t, tnode_t *); 74static tnode_t *build_real_imag(op_t, tnode_t *);
75static tnode_t *build_ampersand(tnode_t *, int); 75static tnode_t *build_ampersand(tnode_t *, int);
76static tnode_t *build_plus_minus(op_t, tnode_t *, tnode_t *); 76static tnode_t *build_plus_minus(op_t, tnode_t *, tnode_t *);
77static tnode_t *build_bit_shift(op_t, tnode_t *, tnode_t *); 77static tnode_t *build_bit_shift(op_t, tnode_t *, tnode_t *);
78static tnode_t *build_colon(tnode_t *, tnode_t *); 78static tnode_t *build_colon(tnode_t *, tnode_t *);
79static tnode_t *build_assignment(op_t, tnode_t *, tnode_t *); 79static tnode_t *build_assignment(op_t, tnode_t *, tnode_t *);
80static tnode_t *plength(type_t *); 80static tnode_t *plength(type_t *);
81static tnode_t *fold(tnode_t *); 81static tnode_t *fold(tnode_t *);
82static tnode_t *fold_test(tnode_t *); 82static tnode_t *fold_test(tnode_t *);
83static tnode_t *fold_float(tnode_t *); 83static tnode_t *fold_float(tnode_t *);
84static tnode_t *check_function_arguments(type_t *, tnode_t *); 84static tnode_t *check_function_arguments(type_t *, tnode_t *);
85static tnode_t *check_prototype_argument(int, type_t *, tnode_t *); 85static tnode_t *check_prototype_argument(int, type_t *, tnode_t *);
86static void check_null_effect(tnode_t *); 86static void check_null_effect(tnode_t *);
87static void display_expression(tnode_t *, int); 87static void display_expression(tnode_t *, int);
88static void check_array_index(tnode_t *, int); 88static void check_array_index(tnode_t *, int);
89static void check_integer_comparison(op_t, tnode_t *, tnode_t *); 89static void check_integer_comparison(op_t, tnode_t *, tnode_t *);
90static void check_precedence_confusion(tnode_t *); 90static void check_precedence_confusion(tnode_t *);
91 91
92extern sig_atomic_t fpe; 92extern sig_atomic_t fpe;
93 93
94#ifdef DEBUG 94#ifdef DEBUG
95static void 95static void
96dprint_node(const tnode_t *tn) 96dprint_node(const tnode_t *tn)
97{ 97{
98 static int indent = 0; 98 static int indent = 0;
99 99
100 op_t op; 100 op_t op;
101 101
102 if (tn == NULL) { 102 if (tn == NULL) {
103 printf("%*s" "null\n", indent, ""); 103 printf("%*s" "null\n", indent, "");
104 return; 104 return;
105 } 105 }
106 106
107 op = tn->tn_op; 107 op = tn->tn_op;
108 printf("%*s%s: %s%s%s", 108 printf("%*s%s: %s%s%s",
109 indent, "", 109 indent, "",
110 op == CVT && !tn->tn_cast ? "convert" : 110 op == CVT && !tn->tn_cast ? "convert" :
111 op == NAME ? "name" : getopname(op), 111 op == NAME ? "name" : getopname(op),
112 type_name(tn->tn_type), tn->tn_lvalue ? " lvalue" : "", 112 type_name(tn->tn_type), tn->tn_lvalue ? " lvalue" : "",
113 tn->tn_parenthesized ? " ()" : ""); 113 tn->tn_parenthesized ? " ()" : "");
114 114
115 if (op == NAME) 115 if (op == NAME)
116 printf(" %s\n", tn->tn_sym->s_name); 116 printf(" %s\n", tn->tn_sym->s_name);
117 else if (op == CON) 117 else if (op == CON)
118 printf(" value=?\n"); 118 printf(" value=?\n");
119 else if (op == STRING) 119 else if (op == STRING)
120 printf(" length=%zu\n", tn->tn_string->st_len); 120 printf(" length=%zu\n", tn->tn_string->st_len);
121 else { 121 else {
122 printf("\n"); 122 printf("\n");
123 123
124 indent += 2; 124 indent += 2;
125 dprint_node(tn->tn_left); 125 dprint_node(tn->tn_left);
126 if (modtab[op].m_binary || tn->tn_right != NULL) 126 if (modtab[op].m_binary || tn->tn_right != NULL)
127 dprint_node(tn->tn_right); 127 dprint_node(tn->tn_right);
128 indent -= 2; 128 indent -= 2;
129 } 129 }
130} 130}
131#else 131#else
132/*ARGSUSED*/ 132/*ARGSUSED*/
133static void 133static void
134dprint_node(const tnode_t *tn) 134dprint_node(const tnode_t *tn)
135{ 135{
136} 136}
137#endif 137#endif
138 138
139/* 139/*
140 * Increase degree of reference. 140 * Increase degree of reference.
141 * This is most often used to change type "T" in type "pointer to T". 141 * This is most often used to change type "T" in type "pointer to T".
142 */ 142 */
143type_t * 143type_t *
144incref(type_t *tp, tspec_t t) 144incref(type_t *tp, tspec_t t)
145{ 145{
146 type_t *tp2; 146 type_t *tp2;
147 147
148 tp2 = getblk(sizeof (type_t)); 148 tp2 = getblk(sizeof (type_t));
149 tp2->t_tspec = t; 149 tp2->t_tspec = t;
150 tp2->t_subt = tp; 150 tp2->t_subt = tp;
151 return tp2; 151 return tp2;
152} 152}
153 153
154/* 154/*
155 * same for use in expressions 155 * same for use in expressions
156 */ 156 */
157type_t * 157type_t *
158tincref(type_t *tp, tspec_t t) 158tincref(type_t *tp, tspec_t t)
159{ 159{
160 type_t *tp2; 160 type_t *tp2;
161 161
162 tp2 = tgetblk(sizeof (type_t)); 162 tp2 = tgetblk(sizeof (type_t));
163 tp2->t_tspec = t; 163 tp2->t_tspec = t;
164 tp2->t_subt = tp; 164 tp2->t_subt = tp;
165 return tp2; 165 return tp2;
166} 166}
167 167
168/* 168/*
169 * Create a node for a constant. 169 * Create a node for a constant.
170 */ 170 */
171tnode_t * 171tnode_t *
172new_constant_node(type_t *tp, val_t *v) 172new_constant_node(type_t *tp, val_t *v)
173{ 173{
174 tnode_t *n; 174 tnode_t *n;
175 175
176 n = getnode(); 176 n = getnode();
177 n->tn_op = CON; 177 n->tn_op = CON;
178 n->tn_type = tp; 178 n->tn_type = tp;
179 n->tn_val = tgetblk(sizeof (val_t)); 179 n->tn_val = tgetblk(sizeof (val_t));
180 n->tn_val->v_tspec = tp->t_tspec; 180 n->tn_val->v_tspec = tp->t_tspec;
181 n->tn_val->v_ansiu = v->v_ansiu; 181 n->tn_val->v_ansiu = v->v_ansiu;
182 n->tn_val->v_u = v->v_u; 182 n->tn_val->v_u = v->v_u;
183 free(v); 183 free(v);
184 return n; 184 return n;
185} 185}
186 186
187static tnode_t * 187static tnode_t *
188new_integer_constant_node(tspec_t t, int64_t q) 188new_integer_constant_node(tspec_t t, int64_t q)
189{ 189{
190 tnode_t *n; 190 tnode_t *n;
191 191
192 n = getnode(); 192 n = getnode();
193 n->tn_op = CON; 193 n->tn_op = CON;
194 n->tn_type = gettyp(t); 194 n->tn_type = gettyp(t);
195 n->tn_val = tgetblk(sizeof (val_t)); 195 n->tn_val = tgetblk(sizeof (val_t));
196 n->tn_val->v_tspec = t; 196 n->tn_val->v_tspec = t;
197 n->tn_val->v_quad = q; 197 n->tn_val->v_quad = q;
198 return n; 198 return n;
199} 199}
200 200
201/* 201/*
202 * Create a node for a name (symbol table entry). 202 * Create a node for a name (symbol table entry).
203 * ntok is the token which follows the name. 203 * ntok is the token which follows the name.
204 */ 204 */
205tnode_t * 205tnode_t *
206new_name_node(sym_t *sym, int ntok) 206new_name_node(sym_t *sym, int ntok)
207{ 207{
208 tnode_t *n; 208 tnode_t *n;
209 209
210 if (sym->s_scl == NOSCL) { 210 if (sym->s_scl == NOSCL) {
211 sym->s_scl = EXTERN; 211 sym->s_scl = EXTERN;
212 sym->s_def = DECL; 212 sym->s_def = DECL;
213 if (ntok == T_LPAREN) { 213 if (ntok == T_LPAREN) {
214 if (sflag) { 214 if (sflag) {
215 /* function implicitly declared to ... */ 215 /* function implicitly declared to ... */
216 warning(215); 216 warning(215);
217 } 217 }
218 /* 218 /*
219 * XXX if tflag is set the symbol should be 219 * XXX if tflag is set the symbol should be
220 * exported to level 0 220 * exported to level 0
221 */ 221 */
222 sym->s_type = incref(sym->s_type, FUNC); 222 sym->s_type = incref(sym->s_type, FUNC);
223 } else { 223 } else {
224 if (!blklev) { 224 if (!blklev) {
225 /* %s undefined */ 225 /* %s undefined */
226 error(99, sym->s_name); 226 error(99, sym->s_name);
227 } else { 227 } else {
228 int fixtype; 228 int fixtype;
229 if (strcmp(sym->s_name, "__FUNCTION__") == 0 || 229 if (strcmp(sym->s_name, "__FUNCTION__") == 0 ||
230 strcmp(sym->s_name, "__PRETTY_FUNCTION__") 230 strcmp(sym->s_name, "__PRETTY_FUNCTION__")
231 == 0) { 231 == 0) {
232 /* __FUNCTION__/__PRETTY_FUNCTION... */ 232 /* __FUNCTION__/__PRETTY_FUNCTION... */
233 gnuism(316); 233 gnuism(316);
234 fixtype = 1; 234 fixtype = 1;
235 } else if (strcmp(sym->s_name, "__func__") == 0) { 235 } else if (strcmp(sym->s_name, "__func__") == 0) {
236 if (!Sflag) 236 if (!Sflag)
237 /* __func__ is a C9X feature */ 237 /* __func__ is a C9X feature */
238 warning(317); 238 warning(317);
239 fixtype = 1; 239 fixtype = 1;
240 } else { 240 } else {
241 /* %s undefined */ 241 /* %s undefined */
242 error(99, sym->s_name); 242 error(99, sym->s_name);
243 fixtype = 0; 243 fixtype = 0;
244 } 244 }
245 if (fixtype) { 245 if (fixtype) {
246 sym->s_type = incref(gettyp(CHAR), PTR); 246 sym->s_type = incref(gettyp(CHAR), PTR);
247 sym->s_type->t_const = 1; 247 sym->s_type->t_const = 1;
248 } 248 }
249 } 249 }
250 } 250 }
251 } 251 }
252 252
253 if (sym->s_kind != FVFT && sym->s_kind != FMEMBER) 253 if (sym->s_kind != FVFT && sym->s_kind != FMEMBER)
254 LERROR("new_name_node(%d)", sym->s_kind); 254 LERROR("new_name_node(%d)", sym->s_kind);
255 255
256 n = getnode(); 256 n = getnode();
257 n->tn_type = sym->s_type; 257 n->tn_type = sym->s_type;
258 if (sym->s_scl != ENUMCON) { 258 if (sym->s_scl != ENUMCON) {
259 n->tn_op = NAME; 259 n->tn_op = NAME;
260 n->tn_sym = sym; 260 n->tn_sym = sym;
261 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 261 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC)
262 n->tn_lvalue = 1; 262 n->tn_lvalue = 1;
263 } else { 263 } else {
264 n->tn_op = CON; 264 n->tn_op = CON;
265 n->tn_val = tgetblk(sizeof (val_t)); 265 n->tn_val = tgetblk(sizeof (val_t));
266 *n->tn_val = sym->s_value; 266 *n->tn_val = sym->s_value;
267 } 267 }
268 268
269 return n; 269 return n;
270} 270}
271 271
272tnode_t * 272tnode_t *
273new_string_node(strg_t *strg) 273new_string_node(strg_t *strg)
274{ 274{
275 size_t len; 275 size_t len;
276 tnode_t *n; 276 tnode_t *n;
277 277
278 len = strg->st_len; 278 len = strg->st_len;
279 279
280 n = getnode(); 280 n = getnode();
281 281
282 n->tn_op = STRING; 282 n->tn_op = STRING;
283 n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY); 283 n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY);
284 n->tn_type->t_dim = len + 1; 284 n->tn_type->t_dim = len + 1;
285 n->tn_lvalue = 1; 285 n->tn_lvalue = 1;
286 286
287 n->tn_string = tgetblk(sizeof (strg_t)); 287 n->tn_string = tgetblk(sizeof (strg_t));
288 n->tn_string->st_tspec = strg->st_tspec; 288 n->tn_string->st_tspec = strg->st_tspec;
289 n->tn_string->st_len = len; 289 n->tn_string->st_len = len;
290 290
291 if (strg->st_tspec == CHAR) { 291 if (strg->st_tspec == CHAR) {
292 n->tn_string->st_cp = tgetblk(len + 1); 292 n->tn_string->st_cp = tgetblk(len + 1);
293 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1); 293 (void)memcpy(n->tn_string->st_cp, strg->st_cp, len + 1);
294 free(strg->st_cp); 294 free(strg->st_cp);
295 } else { 295 } else {
296 n->tn_string->st_wcp = tgetblk((len + 1) * sizeof (wchar_t)); 296 n->tn_string->st_wcp = tgetblk((len + 1) * sizeof (wchar_t));
297 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp, 297 (void)memcpy(n->tn_string->st_wcp, strg->st_wcp,
298 (len + 1) * sizeof (wchar_t)); 298 (len + 1) * sizeof (wchar_t));
299 free(strg->st_wcp); 299 free(strg->st_wcp);
300 } 300 }
301 free(strg); 301 free(strg);
302 302
303 return n; 303 return n;
304} 304}
305 305
306/* 306/*
307 * Returns a symbol which has the same name as the msym argument and is a 307 * Returns a symbol which has the same name as the msym argument and is a
308 * member of the struct or union specified by the tn argument. 308 * member of the struct or union specified by the tn argument.
309 */ 309 */
310sym_t * 310sym_t *
311struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym) 311struct_or_union_member(tnode_t *tn, op_t op, sym_t *msym)
312{ 312{
313 str_t *str; 313 str_t *str;
314 type_t *tp; 314 type_t *tp;
315 sym_t *sym, *csym; 315 sym_t *sym, *csym;
316 int eq; 316 int eq;
317 tspec_t t; 317 tspec_t t;
318 318
319 /* 319 /*
320 * Remove the member if it was unknown until now (Which means 320 * Remove the member if it was unknown until now (Which means
321 * that no defined struct or union has a member with the same name). 321 * that no defined struct or union has a member with the same name).
322 */ 322 */
323 if (msym->s_scl == NOSCL) { 323 if (msym->s_scl == NOSCL) {
324 /* undefined struct/union member: %s */ 324 /* undefined struct/union member: %s */
325 error(101, msym->s_name); 325 error(101, msym->s_name);
326 rmsym(msym); 326 rmsym(msym);
327 msym->s_kind = FMEMBER; 327 msym->s_kind = FMEMBER;
328 msym->s_scl = MOS; 328 msym->s_scl = MOS;
329 msym->s_styp = tgetblk(sizeof (str_t)); 329 msym->s_styp = tgetblk(sizeof (str_t));
330 msym->s_styp->stag = tgetblk(sizeof (sym_t)); 330 msym->s_styp->stag = tgetblk(sizeof (sym_t));
331 msym->s_styp->stag->s_name = unnamed; 331 msym->s_styp->stag->s_name = unnamed;
332 msym->s_value.v_tspec = INT; 332 msym->s_value.v_tspec = INT;
333 return msym; 333 return msym;
334 } 334 }
335 335
336 /* Set str to the tag of which msym is expected to be a member. */ 336 /* Set str to the tag of which msym is expected to be a member. */
337 str = NULL; 337 str = NULL;
338 t = (tp = tn->tn_type)->t_tspec; 338 t = (tp = tn->tn_type)->t_tspec;
339 if (op == POINT) { 339 if (op == POINT) {
340 if (t == STRUCT || t == UNION) 340 if (t == STRUCT || t == UNION)
341 str = tp->t_str; 341 str = tp->t_str;
342 } else if (op == ARROW && t == PTR) { 342 } else if (op == ARROW && t == PTR) {
343 t = (tp = tp->t_subt)->t_tspec; 343 t = (tp = tp->t_subt)->t_tspec;
344 if (t == STRUCT || t == UNION) 344 if (t == STRUCT || t == UNION)
345 str = tp->t_str; 345 str = tp->t_str;
346 } 346 }
347 347
348 /* 348 /*
349 * If this struct/union has a member with the name of msym, return 349 * If this struct/union has a member with the name of msym, return
350 * return this it. 350 * return this it.
351 */ 351 */
352 if (str != NULL) { 352 if (str != NULL) {
353 for (sym = msym; sym != NULL; sym = sym->s_link) { 353 for (sym = msym; sym != NULL; sym = sym->s_link) {
354 if (sym->s_scl != MOS && sym->s_scl != MOU) 354 if (sym->s_scl != MOS && sym->s_scl != MOU)
355 continue; 355 continue;
356 if (sym->s_styp != str) 356 if (sym->s_styp != str)
357 continue; 357 continue;
358 if (strcmp(sym->s_name, msym->s_name) != 0) 358 if (strcmp(sym->s_name, msym->s_name) != 0)
359 continue; 359 continue;
360 return sym; 360 return sym;
361 } 361 }
362 } 362 }
363 363
364 /* 364 /*
365 * Set eq to 0 if there are struct/union members with the same name 365 * Set eq to 0 if there are struct/union members with the same name
366 * and different types and/or offsets. 366 * and different types and/or offsets.
367 */ 367 */
368 eq = 1; 368 eq = 1;
369 for (csym = msym; csym != NULL; csym = csym->s_link) { 369 for (csym = msym; csym != NULL; csym = csym->s_link) {
370 if (csym->s_scl != MOS && csym->s_scl != MOU) 370 if (csym->s_scl != MOS && csym->s_scl != MOU)
371 continue; 371 continue;
372 if (strcmp(msym->s_name, csym->s_name) != 0) 372 if (strcmp(msym->s_name, csym->s_name) != 0)
373 continue; 373 continue;
374 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { 374 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) {
375 int w; 375 int w;
376 376
377 if (sym->s_scl != MOS && sym->s_scl != MOU) 377 if (sym->s_scl != MOS && sym->s_scl != MOU)
378 continue; 378 continue;
379 if (strcmp(csym->s_name, sym->s_name) != 0) 379 if (strcmp(csym->s_name, sym->s_name) != 0)
380 continue; 380 continue;
381 if (csym->s_value.v_quad != sym->s_value.v_quad) { 381 if (csym->s_value.v_quad != sym->s_value.v_quad) {
382 eq = 0; 382 eq = 0;
383 break; 383 break;
384 } 384 }
385 w = 0; 385 w = 0;
386 eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w; 386 eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w;
387 if (!eq) 387 if (!eq)
388 break; 388 break;
389 if (csym->s_bitfield != sym->s_bitfield) { 389 if (csym->s_bitfield != sym->s_bitfield) {
390 eq = 0; 390 eq = 0;
391 break; 391 break;
392 } 392 }
393 if (csym->s_bitfield) { 393 if (csym->s_bitfield) {
394 type_t *tp1, *tp2; 394 type_t *tp1, *tp2;
395 395
396 tp1 = csym->s_type; 396 tp1 = csym->s_type;
397 tp2 = sym->s_type; 397 tp2 = sym->s_type;
398 if (tp1->t_flen != tp2->t_flen) { 398 if (tp1->t_flen != tp2->t_flen) {
399 eq = 0; 399 eq = 0;
400 break; 400 break;
401 } 401 }
402 if (tp1->t_foffs != tp2->t_foffs) { 402 if (tp1->t_foffs != tp2->t_foffs) {
403 eq = 0; 403 eq = 0;
404 break; 404 break;
405 } 405 }
406 } 406 }
407 } 407 }
408 if (!eq) 408 if (!eq)
409 break; 409 break;
410 } 410 }
411 411
412 /* 412 /*
413 * Now handle the case in which the left operand refers really 413 * Now handle the case in which the left operand refers really
414 * to a struct/union, but the right operand is not member of it. 414 * to a struct/union, but the right operand is not member of it.
415 */ 415 */
416 if (str != NULL) { 416 if (str != NULL) {
417 if (eq && tflag) { 417 if (eq && tflag) {
418 /* illegal member use: %s */ 418 /* illegal member use: %s */
419 warning(102, msym->s_name); 419 warning(102, msym->s_name);
420 } else { 420 } else {
421 /* illegal member use: %s */ 421 /* illegal member use: %s */
422 error(102, msym->s_name); 422 error(102, msym->s_name);
423 } 423 }
424 return msym; 424 return msym;
425 } 425 }
426 426
427 /* 427 /*
428 * Now the left operand of ARROW does not point to a struct/union 428 * Now the left operand of ARROW does not point to a struct/union
429 * or the left operand of POINT is no struct/union. 429 * or the left operand of POINT is no struct/union.
430 */ 430 */
431 if (eq) { 431 if (eq) {
432 if (op == POINT) { 432 if (op == POINT) {
433 if (tflag) { 433 if (tflag) {
434 /* left operand of '.' must be struct/... */ 434 /* left operand of '.' must be struct/... */
435 warning(103); 435 warning(103);
436 } else { 436 } else {
437 /* left operand of '.' must be struct/... */ 437 /* left operand of '.' must be struct/... */
438 error(103); 438 error(103);
439 } 439 }
440 } else { 440 } else {
441 /* left operand of "->" must be pointer to ... */ 441 /* left operand of "->" must be pointer to ... */
442 if (tflag && tn->tn_type->t_tspec == PTR) { 442 if (tflag && tn->tn_type->t_tspec == PTR) {
443 /* left operand of '->' must be pointer ... */ 443 /* left operand of '->' must be pointer ... */
444 warning(104, type_name(tn->tn_type)); 444 warning(104, type_name(tn->tn_type));
445 } else { 445 } else {
446 /* left operand of '->' must be pointer ... */ 446 /* left operand of '->' must be pointer ... */
447 error(104, type_name(tn->tn_type)); 447 error(104, type_name(tn->tn_type));
448 } 448 }
449 } 449 }
450 } else { 450 } else {
451 if (tflag) { 451 if (tflag) {
452 /* non-unique member requires struct/union %s */ 452 /* non-unique member requires struct/union %s */
453 error(105, op == POINT ? "object" : "pointer"); 453 error(105, op == POINT ? "object" : "pointer");
454 } else { 454 } else {
455 /* unacceptable operand of '%s' */ 455 /* unacceptable operand of '%s' */
456 error(111, modtab[op].m_name); 456 error(111, modtab[op].m_name);
457 } 457 }
458 } 458 }
459 459
460 return msym; 460 return msym;
461} 461}
462 462
463/* 463/*
464 * Create a tree node. Called for most operands except function calls, 464 * Create a tree node. Called for most operands except function calls,
465 * sizeof and casts. 465 * sizeof and casts.
466 * 466 *
467 * op operator 467 * op operator
468 * ln left operand 468 * ln left operand
469 * rn if not NULL, right operand 469 * rn if not NULL, right operand
470 */ 470 */
471tnode_t * 471tnode_t *
472build(op_t op, tnode_t *ln, tnode_t *rn) 472build(op_t op, tnode_t *ln, tnode_t *rn)
473{ 473{
474 mod_t *mp; 474 mod_t *mp;
475 tnode_t *ntn; 475 tnode_t *ntn;
476 type_t *rtp; 476 type_t *rtp;
477 477
478 mp = &modtab[op]; 478 mp = &modtab[op];
479 479
480 /* If there was an error in one of the operands, return. */ 480 /* If there was an error in one of the operands, return. */
481 if (ln == NULL || (mp->m_binary && rn == NULL)) 481 if (ln == NULL || (mp->m_binary && rn == NULL))
482 return NULL; 482 return NULL;
483 483
484 /* 484 /*
485 * Apply class conversions to the left operand, but only if its 485 * Apply class conversions to the left operand, but only if its
486 * value is needed or it is compared with null. 486 * value is needed or it is compared with null.
487 */ 487 */
488 if (mp->m_vctx || mp->m_tctx) 488 if (mp->m_vctx || mp->m_tctx)
489 ln = cconv(ln); 489 ln = cconv(ln);
490 /* 490 /*
491 * The right operand is almost always in a test or value context, 491 * The right operand is almost always in a test or value context,
492 * except if it is a struct or union member. 492 * except if it is a struct or union member.
493 */ 493 */
494 if (mp->m_binary && op != ARROW && op != POINT) 494 if (mp->m_binary && op != ARROW && op != POINT)
495 rn = cconv(rn); 495 rn = cconv(rn);
496 496
497 /* 497 /*
498 * Print some warnings for comparisons of unsigned values with 498 * Print some warnings for comparisons of unsigned values with
499 * constants lower than or equal to null. This must be done 499 * constants lower than or equal to null. This must be done
500 * before promote() because otherwise unsigned char and unsigned 500 * before promote() because otherwise unsigned char and unsigned
501 * short would be promoted to int. Also types are tested to be 501 * short would be promoted to int. Also types are tested to be
502 * CHAR, which would also become int. 502 * CHAR, which would also become int.
503 */ 503 */
504 if (mp->m_comp) 504 if (mp->m_comp)
505 check_integer_comparison(op, ln, rn); 505 check_integer_comparison(op, ln, rn);
506 506
507 /* 507 /*
508 * Promote the left operand if it is in a test or value context 508 * Promote the left operand if it is in a test or value context
509 */ 509 */
510 if (mp->m_vctx || mp->m_tctx) 510 if (mp->m_vctx || mp->m_tctx)
511 ln = promote(op, 0, ln); 511 ln = promote(op, 0, ln);
512 /* 512 /*
513 * Promote the right operand, but only if it is no struct or 513 * Promote the right operand, but only if it is no struct or
514 * union member, or if it is not to be assigned to the left operand 514 * union member, or if it is not to be assigned to the left operand
515 */ 515 */
516 if (mp->m_binary && op != ARROW && op != POINT && 516 if (mp->m_binary && op != ARROW && op != POINT &&
517 op != ASSIGN && op != RETURN) { 517 op != ASSIGN && op != RETURN) {
518 rn = promote(op, 0, rn); 518 rn = promote(op, 0, rn);
519 } 519 }
520 520
521 /* 521 /*
522 * If the result of the operation is different for signed or 522 * If the result of the operation is different for signed or
523 * unsigned operands and one of the operands is signed only in 523 * unsigned operands and one of the operands is signed only in
524 * ANSI C, print a warning. 524 * ANSI C, print a warning.
525 */ 525 */
526 if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) { 526 if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) {
527 /* ANSI C treats constant as unsigned, op %s */ 527 /* ANSI C treats constant as unsigned, op %s */
528 warning(218, mp->m_name); 528 warning(218, mp->m_name);
529 ln->tn_val->v_ansiu = 0; 529 ln->tn_val->v_ansiu = 0;
530 } 530 }
531 if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) { 531 if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) {
532 /* ANSI C treats constant as unsigned, op %s */ 532 /* ANSI C treats constant as unsigned, op %s */
533 warning(218, mp->m_name); 533 warning(218, mp->m_name);
534 rn->tn_val->v_ansiu = 0; 534 rn->tn_val->v_ansiu = 0;
535 } 535 }
536 536
537 /* Make sure both operands are of the same type */ 537 /* Make sure both operands are of the same type */
538 if (mp->m_balance || (tflag && (op == SHL || op == SHR))) 538 if (mp->m_balance || (tflag && (op == SHL || op == SHR)))
539 balance(op, &ln, &rn); 539 balance(op, &ln, &rn);
540 540
541 /* 541 /*
542 * Check types for compatibility with the operation and mutual 542 * Check types for compatibility with the operation and mutual
543 * compatibility. Return if there are serious problems. 543 * compatibility. Return if there are serious problems.
544 */ 544 */
545 if (!typeok(op, 0, ln, rn)) 545 if (!typeok(op, 0, ln, rn))
546 return NULL; 546 return NULL;
547 547
548 /* And now create the node. */ 548 /* And now create the node. */
549 switch (op) { 549 switch (op) {
550 case POINT: 550 case POINT:
551 case ARROW: 551 case ARROW:
552 ntn = build_struct_access(op, ln, rn); 552 ntn = build_struct_access(op, ln, rn);
553 break; 553 break;
554 case INCAFT: 554 case INCAFT:
555 case DECAFT: 555 case DECAFT:
556 case INCBEF: 556 case INCBEF:
557 case DECBEF: 557 case DECBEF:
558 ntn = build_prepost_incdec(op, ln); 558 ntn = build_prepost_incdec(op, ln);
559 break; 559 break;
560 case AMPER: 560 case AMPER:
561 ntn = build_ampersand(ln, 0); 561 ntn = build_ampersand(ln, 0);
562 break; 562 break;
563 case STAR: 563 case STAR:
564 ntn = new_tnode(STAR, ln->tn_type->t_subt, ln, NULL); 564 ntn = new_tnode(STAR, ln->tn_type->t_subt, ln, NULL);
565 break; 565 break;
566 case PLUS: 566 case PLUS:
567 case MINUS: 567 case MINUS:
568 ntn = build_plus_minus(op, ln, rn); 568 ntn = build_plus_minus(op, ln, rn);
569 break; 569 break;
570 case SHL: 570 case SHL:
571 case SHR: 571 case SHR:
572 ntn = build_bit_shift(op, ln, rn); 572 ntn = build_bit_shift(op, ln, rn);
573 break; 573 break;
574 case COLON: 574 case COLON:
575 ntn = build_colon(ln, rn); 575 ntn = build_colon(ln, rn);
576 break; 576 break;
577 case ASSIGN: 577 case ASSIGN:
578 case MULASS: 578 case MULASS:
579 case DIVASS: 579 case DIVASS:
580 case MODASS: 580 case MODASS:
581 case ADDASS: 581 case ADDASS:
582 case SUBASS: 582 case SUBASS:
583 case SHLASS: 583 case SHLASS:
584 case SHRASS: 584 case SHRASS:
585 case ANDASS: 585 case ANDASS:
586 case XORASS: 586 case XORASS:
587 case ORASS: 587 case ORASS:
588 case RETURN: 588 case RETURN:
589 ntn = build_assignment(op, ln, rn); 589 ntn = build_assignment(op, ln, rn);
590 break; 590 break;
591 case COMMA: 591 case COMMA:
592 case QUEST: 592 case QUEST:
593 ntn = new_tnode(op, rn->tn_type, ln, rn); 593 ntn = new_tnode(op, rn->tn_type, ln, rn);
594 break; 594 break;
595 case REAL: 595 case REAL:
596 case IMAG: 596 case IMAG:
597 ntn = build_real_imag(op, ln); 597 ntn = build_real_imag(op, ln);
598 break; 598 break;
599 default: 599 default:
600 rtp = mp->m_logical ? gettyp(INT) : ln->tn_type; 600 rtp = mp->m_logical ? gettyp(INT) : ln->tn_type;
601 lint_assert(mp->m_binary || rn == NULL); 601 lint_assert(mp->m_binary || rn == NULL);
602 ntn = new_tnode(op, rtp, ln, rn); 602 ntn = new_tnode(op, rtp, ln, rn);
603 break; 603 break;
604 } 604 }
605 605
606 /* Return if an error occurred. */ 606 /* Return if an error occurred. */
607 if (ntn == NULL) 607 if (ntn == NULL)
608 return NULL; 608 return NULL;
609 609
610 /* Print a warning if precedence confusion is possible */ 610 /* Print a warning if precedence confusion is possible */
611 if (mp->m_tpconf) 611 if (mp->m_tpconf)
612 check_precedence_confusion(ntn); 612 check_precedence_confusion(ntn);
613 613
614 /* 614 /*
615 * Print a warning if one of the operands is in a context where 615 * Print a warning if one of the operands is in a context where
616 * it is compared with null and if this operand is a constant. 616 * it is compared with null and if this operand is a constant.
617 */ 617 */
618 if (mp->m_tctx) { 618 if (mp->m_tctx) {
619 if (ln->tn_op == CON || 619 if (ln->tn_op == CON ||
620 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { 620 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) {
621 if (hflag && !constcond_flag) 621 if (hflag && !constcond_flag)
622 /* constant in conditional context */ 622 /* constant in conditional context */
623 warning(161); 623 warning(161);
624 } 624 }
625 } 625 }
626 626
627 /* Fold if the operator requires it */ 627 /* Fold if the operator requires it */
628 if (mp->m_fold) { 628 if (mp->m_fold) {
629 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 629 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) {
630 if (mp->m_tctx) { 630 if (mp->m_tctx) {
631 ntn = fold_test(ntn); 631 ntn = fold_test(ntn);
632 } else if (tspec_is_float(ntn->tn_type->t_tspec)) { 632 } else if (tspec_is_float(ntn->tn_type->t_tspec)) {
633 ntn = fold_float(ntn); 633 ntn = fold_float(ntn);
634 } else { 634 } else {
635 ntn = fold(ntn); 635 ntn = fold(ntn);
636 } 636 }
637 } else if (op == QUEST && ln->tn_op == CON) { 637 } else if (op == QUEST && ln->tn_op == CON) {
638 ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right; 638 ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right;
639 } 639 }
640 } 640 }
641 641
642 return ntn; 642 return ntn;
643} 643}
644 644
645/* 645/*
646 * Perform class conversions. 646 * Perform class conversions.
647 * 647 *
648 * Arrays of type T are converted into pointers to type T. 648 * Arrays of type T are converted into pointers to type T.
649 * Functions are converted to pointers to functions. 649 * Functions are converted to pointers to functions.
650 * Lvalues are converted to rvalues. 650 * Lvalues are converted to rvalues.
651 */ 651 */
652tnode_t * 652tnode_t *
653cconv(tnode_t *tn) 653cconv(tnode_t *tn)
654{ 654{
655 type_t *tp; 655 type_t *tp;
656 656
657 /* 657 /*
658 * Array-lvalue (array of type T) is converted into rvalue 658 * Array-lvalue (array of type T) is converted into rvalue
659 * (pointer to type T) 659 * (pointer to type T)
660 */ 660 */
661 if (tn->tn_type->t_tspec == ARRAY) { 661 if (tn->tn_type->t_tspec == ARRAY) {
662 if (!tn->tn_lvalue) { 662 if (!tn->tn_lvalue) {
663 /* XXX print correct operator */ 663 /* XXX print correct operator */
664 /* %soperand of '%s' must be lvalue */ 664 /* %soperand of '%s' must be lvalue */
665 gnuism(114, "", modtab[AMPER].m_name); 665 gnuism(114, "", modtab[AMPER].m_name);
666 } 666 }
667 tn = new_tnode(AMPER, tincref(tn->tn_type->t_subt, PTR), 667 tn = new_tnode(AMPER, tincref(tn->tn_type->t_subt, PTR),
668 tn, NULL); 668 tn, NULL);
669 } 669 }
670 670
671 /* 671 /*
672 * Expression of type function (function with return value of type T) 672 * Expression of type function (function with return value of type T)
673 * in rvalue-expression (pointer to function with return value 673 * in rvalue-expression (pointer to function with return value
674 * of type T) 674 * of type T)
675 */ 675 */
676 if (tn->tn_type->t_tspec == FUNC) 676 if (tn->tn_type->t_tspec == FUNC)
677 tn = build_ampersand(tn, 1); 677 tn = build_ampersand(tn, 1);
678 678
679 /* lvalue to rvalue */ 679 /* lvalue to rvalue */
680 if (tn->tn_lvalue) { 680 if (tn->tn_lvalue) {
681 tp = tduptyp(tn->tn_type); 681 tp = tduptyp(tn->tn_type);
682 tp->t_const = tp->t_volatile = 0; 682 tp->t_const = tp->t_volatile = 0;
683 tn = new_tnode(LOAD, tp, tn, NULL); 683 tn = new_tnode(LOAD, tp, tn, NULL);
684 } 684 }
685 685
686 return tn; 686 return tn;
687} 687}
688 688
689/* 689/*
690 * Perform most type checks. First the types are checked using 690 * Perform most type checks. First the types are checked using
691 * the information from modtab[]. After that it is done by hand for 691 * the information from modtab[]. After that it is done by hand for
692 * more complicated operators and type combinations. 692 * more complicated operators and type combinations.
693 * 693 *
694 * If the types are ok, typeok() returns 1, otherwise 0. 694 * If the types are ok, typeok() returns 1, otherwise 0.
695 */ 695 */
696int 696int
697typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) 697typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn)
698{ 698{
699 mod_t *mp; 699 mod_t *mp;
700 tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC, 700 tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC,
701 ort = NOTSPEC; 701 ort = NOTSPEC;
702 type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL; 702 type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL;
703 tnode_t *tn; 703 tnode_t *tn;
704 704
705 mp = &modtab[op]; 705 mp = &modtab[op];
706 706
707 lint_assert((ltp = ln->tn_type) != NULL); 707 lint_assert((ltp = ln->tn_type) != NULL);
708 708
709 if ((lt = ltp->t_tspec) == PTR) 709 if ((lt = ltp->t_tspec) == PTR)
710 lst = (lstp = ltp->t_subt)->t_tspec; 710 lst = (lstp = ltp->t_subt)->t_tspec;
711 if (mp->m_binary) { 711 if (mp->m_binary) {
712 lint_assert((rtp = rn->tn_type) != NULL); 712 lint_assert((rtp = rn->tn_type) != NULL);
713 if ((rt = rtp->t_tspec) == PTR) 713 if ((rt = rtp->t_tspec) == PTR)
714 rst = (rstp = rtp->t_subt)->t_tspec; 714 rst = (rstp = rtp->t_subt)->t_tspec;
715 } 715 }
716 716
717 if (mp->m_requires_integer) { 717 if (mp->m_requires_integer) {
718 if (!tspec_is_int(lt) || (mp->m_binary && !tspec_is_int(rt))) { 718 if (!tspec_is_int(lt) || (mp->m_binary && !tspec_is_int(rt))) {
719 warn_incompatible_types(op, lt, rt); 719 warn_incompatible_types(op, lt, rt);
720 return 0; 720 return 0;
721 } 721 }
722 } else if (mp->m_requires_integer_or_complex) { 722 } else if (mp->m_requires_integer_or_complex) {
723 if ((!tspec_is_int(lt) && !tspec_is_complex(lt)) || 723 if ((!tspec_is_int(lt) && !tspec_is_complex(lt)) ||
724 (mp->m_binary && 724 (mp->m_binary &&
725 (!tspec_is_int(rt) && !tspec_is_complex(rt)))) { 725 (!tspec_is_int(rt) && !tspec_is_complex(rt)))) {
726 warn_incompatible_types(op, lt, rt); 726 warn_incompatible_types(op, lt, rt);
727 return 0; 727 return 0;
728 } 728 }
729 } else if (mp->m_requires_scalar) { 729 } else if (mp->m_requires_scalar) {
730 if (!tspec_is_scalar(lt) || 730 if (!tspec_is_scalar(lt) ||
731 (mp->m_binary && !tspec_is_scalar(rt))) { 731 (mp->m_binary && !tspec_is_scalar(rt))) {
732 warn_incompatible_types(op, lt, rt); 732 warn_incompatible_types(op, lt, rt);
733 return 0; 733 return 0;
734 } 734 }
735 } else if (mp->m_requires_arith) { 735 } else if (mp->m_requires_arith) {
736 if (!tspec_is_arith(lt) || 736 if (!tspec_is_arith(lt) ||
737 (mp->m_binary && !tspec_is_arith(rt))) { 737 (mp->m_binary && !tspec_is_arith(rt))) {
738 warn_incompatible_types(op, lt, rt); 738 warn_incompatible_types(op, lt, rt);
739 return 0; 739 return 0;
740 } 740 }
741 } 741 }
742 742
743 if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) { 743 if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) {
744 /* 744 /*
745 * For these operations we need the types before promotion 745 * For these operations we need the types before promotion
746 * and balancing. 746 * and balancing.
747 */ 747 */
748 for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) 748 for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left)
749 continue; 749 continue;
750 olt = tn->tn_type->t_tspec; 750 olt = tn->tn_type->t_tspec;
751 for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) 751 for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left)
752 continue; 752 continue;
753 ort = tn->tn_type->t_tspec; 753 ort = tn->tn_type->t_tspec;
754 } 754 }
755 755
756 switch (op) { 756 switch (op) {
757 case POINT: 757 case POINT:
758 /* 758 /*
759 * Most errors required by ANSI C are reported in 759 * Most errors required by ANSI C are reported in
760 * struct_or_union_member(). 760 * struct_or_union_member().
761 * Here we only must check for totally wrong things. 761 * Here we only must check for totally wrong things.
762 */ 762 */
763 if (lt == FUNC || lt == VOID || ltp->t_bitfield || 763 if (lt == FUNC || lt == VOID || ltp->t_bitfield ||
764 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { 764 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) {
765 /* Without tflag we got already an error */ 765 /* Without tflag we got already an error */
766 if (tflag) 766 if (tflag)
767 /* unacceptable operand of '%s' */ 767 /* unacceptable operand of '%s' */
768 error(111, mp->m_name); 768 error(111, mp->m_name);
769 return 0; 769 return 0;
770 } 770 }
771 /* Now we have an object we can create a pointer to */ 771 /* Now we have an object we can create a pointer to */
772 break; 772 break;
773 case ARROW: 773 case ARROW:
774 if (lt != PTR && !(tflag && tspec_is_int(lt))) { 774 if (lt != PTR && !(tflag && tspec_is_int(lt))) {
775 /* Without tflag we got already an error */ 775 /* Without tflag we got already an error */
776 if (tflag) 776 if (tflag)
777 /* unacceptable operand of '%s' */ 777 /* unacceptable operand of '%s' */
778 error(111, mp->m_name); 778 error(111, mp->m_name);
779 return 0; 779 return 0;
780 } 780 }
781 break; 781 break;
782 case INCAFT: 782 case INCAFT:
783 case DECAFT: 783 case DECAFT:
784 case INCBEF: 784 case INCBEF:
785 case DECBEF: 785 case DECBEF:
786 /* operands have scalar types (checked above) */ 786 /* operands have scalar types (checked above) */
787 if (!ln->tn_lvalue) { 787 if (!ln->tn_lvalue) {
788 if (ln->tn_op == CVT && ln->tn_cast && 788 if (ln->tn_op == CVT && ln->tn_cast &&
789 ln->tn_left->tn_op == LOAD) { 789 ln->tn_left->tn_op == LOAD) {
790 if (ln->tn_type->t_tspec == PTR) 790 if (ln->tn_type->t_tspec == PTR)
791 break; 791 break;
792 /* a cast does not yield an lvalue */ 792 /* a cast does not yield an lvalue */
793 error(163); 793 error(163);
794 } 794 }
795 /* %soperand of '%s' must be lvalue */ 795 /* %soperand of '%s' must be lvalue */
796 error(114, "", mp->m_name); 796 error(114, "", mp->m_name);
797 return 0; 797 return 0;
798 } else if (ltp->t_const) { 798 } else if (ltp->t_const) {
799 if (!tflag) 799 if (!tflag)
800 /* %soperand of '%s' must be modifiable ... */ 800 /* %soperand of '%s' must be modifiable ... */
801 warning(115, "", mp->m_name); 801 warning(115, "", mp->m_name);
802 } 802 }
803 break; 803 break;
804 case AMPER: 804 case AMPER:
805 if (lt == ARRAY || lt == FUNC) { 805 if (lt == ARRAY || lt == FUNC) {
806 /* ok, a warning comes later (in build_ampersand()) */ 806 /* ok, a warning comes later (in build_ampersand()) */
807 } else if (!ln->tn_lvalue) { 807 } else if (!ln->tn_lvalue) {
808 if (ln->tn_op == CVT && ln->tn_cast && 808 if (ln->tn_op == CVT && ln->tn_cast &&
809 ln->tn_left->tn_op == LOAD) { 809 ln->tn_left->tn_op == LOAD) {
810 if (ln->tn_type->t_tspec == PTR) 810 if (ln->tn_type->t_tspec == PTR)
811 break; 811 break;
812 /* a cast does not yield an lvalue */ 812 /* a cast does not yield an lvalue */
813 error(163); 813 error(163);
814 } 814 }
815 /* %soperand of '%s' must be lvalue */ 815 /* %soperand of '%s' must be lvalue */
816 error(114, "", mp->m_name); 816 error(114, "", mp->m_name);
817 return 0; 817 return 0;
818 } else if (tspec_is_scalar(lt)) { 818 } else if (tspec_is_scalar(lt)) {
819 if (ltp->t_bitfield) { 819 if (ltp->t_bitfield) {
820 /* cannot take address of bit-field */ 820 /* cannot take address of bit-field */
821 error(112); 821 error(112);
822 return 0; 822 return 0;
823 } 823 }
824 } else if (lt != STRUCT && lt != UNION) { 824 } else if (lt != STRUCT && lt != UNION) {
825 /* unacceptable operand of '%s' */ 825 /* unacceptable operand of '%s' */
826 error(111, mp->m_name); 826 error(111, mp->m_name);
827 return 0; 827 return 0;
828 } 828 }
829 if (ln->tn_op == NAME && ln->tn_sym->s_reg) { 829 if (ln->tn_op == NAME && ln->tn_sym->s_reg) {
830 /* cannot take address of register %s */ 830 /* cannot take address of register %s */
831 error(113, ln->tn_sym->s_name); 831 error(113, ln->tn_sym->s_name);
832 return 0; 832 return 0;
833 } 833 }
834 break; 834 break;
835 case STAR: 835 case STAR:
836 /* until now there were no type checks for this operator */ 836 /* until now there were no type checks for this operator */
837 if (lt != PTR) { 837 if (lt != PTR) {
838 /* cannot dereference non-pointer type */ 838 /* cannot dereference non-pointer type */
839 error(96); 839 error(96);
840 return 0; 840 return 0;
841 } 841 }
842 break; 842 break;
843 case PLUS: 843 case PLUS:
844 /* operands have scalar types (checked above) */ 844 /* operands have scalar types (checked above) */
845 if ((lt == PTR && !tspec_is_int(rt)) || 845 if ((lt == PTR && !tspec_is_int(rt)) ||
846 (rt == PTR && !tspec_is_int(lt))) { 846 (rt == PTR && !tspec_is_int(lt))) {
847 warn_incompatible_types(op, lt, rt); 847 warn_incompatible_types(op, lt, rt);
848 return 0; 848 return 0;
849 } 849 }
850 break; 850 break;
851 case MINUS: 851 case MINUS:
852 /* operands have scalar types (checked above) */ 852 /* operands have scalar types (checked above) */
853 if (lt == PTR && (!tspec_is_int(rt) && rt != PTR)) { 853 if (lt == PTR && (!tspec_is_int(rt) && rt != PTR)) {
854 warn_incompatible_types(op, lt, rt); 854 warn_incompatible_types(op, lt, rt);
855 return 0; 855 return 0;
856 } else if (rt == PTR && lt != PTR) { 856 } else if (rt == PTR && lt != PTR) {
857 warn_incompatible_types(op, lt, rt); 857 warn_incompatible_types(op, lt, rt);
858 return 0; 858 return 0;
859 } 859 }
860 if (lt == PTR && rt == PTR) { 860 if (lt == PTR && rt == PTR) {
861 if (!eqtype(lstp, rstp, 1, 0, NULL)) { 861 if (!eqtype(lstp, rstp, 1, 0, NULL)) {
862 /* illegal pointer subtraction */ 862 /* illegal pointer subtraction */
863 error(116); 863 error(116);
864 } 864 }
865 } 865 }
866 break; 866 break;
867 case SHR: 867 case SHR:
868 /* operands have integer types (checked above) */ 868 /* operands have integer types (checked above) */
869 if (pflag && !tspec_is_uint(lt)) { 869 if (pflag && !tspec_is_uint(lt)) {
870 /* 870 /*
871 * The left operand is signed. This means that 871 * The left operand is signed. This means that
872 * the operation is (possibly) nonportable. 872 * the operation is (possibly) nonportable.
873 */ 873 */
874 if (ln->tn_op != CON) { 874 if (ln->tn_op != CON) {
875 /* bitop. on signed value poss. nonportable */ 875 /* bitop. on signed value poss. nonportable */
876 warning(117); 876 warning(117);
877 } else if (ln->tn_val->v_quad < 0) { 877 } else if (ln->tn_val->v_quad < 0) {
878 /* bitop. on signed value nonportable */ 878 /* bitop. on signed value nonportable */
879 warning(120); 879 warning(120);
880 } 880 }
881 } else if (!tflag && !sflag && 881 } else if (!tflag && !sflag &&
882 !tspec_is_uint(olt) && tspec_is_uint(ort)) { 882 !tspec_is_uint(olt) && tspec_is_uint(ort)) {
883 /* 883 /*
884 * The left operand would become unsigned in 884 * The left operand would become unsigned in
885 * traditional C. 885 * traditional C.
886 */ 886 */
887 if (hflag && 887 if (hflag &&
888 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 888 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
889 /* semantics of '%s' change in ANSI C; ... */ 889 /* semantics of '%s' change in ANSI C; ... */
890 warning(118, mp->m_name); 890 warning(118, mp->m_name);
891 } 891 }
892 } else if (!tflag && !sflag && 892 } else if (!tflag && !sflag &&
893 !tspec_is_uint(olt) && !tspec_is_uint(ort) && 893 !tspec_is_uint(olt) && !tspec_is_uint(ort) &&
894 psize(lt) < psize(rt)) { 894 psize(lt) < psize(rt)) {
895 /* 895 /*
896 * In traditional C the left operand would be extended, 896 * In traditional C the left operand would be extended,
897 * possibly with 1, and then shifted. 897 * possibly with 1, and then shifted.
898 */ 898 */
899 if (hflag && 899 if (hflag &&
900 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 900 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) {
901 /* semantics of '%s' change in ANSI C; ... */ 901 /* semantics of '%s' change in ANSI C; ... */
902 warning(118, mp->m_name); 902 warning(118, mp->m_name);
903 } 903 }
904 } 904 }
905 goto shift; 905 goto shift;
906 case SHL: 906 case SHL:
907 /* 907 /*
908 * ANSI C does not perform balancing for shift operations, 908 * ANSI C does not perform balancing for shift operations,
909 * but traditional C does. If the width of the right operand 909 * but traditional C does. If the width of the right operand
910 * is greater than the width of the left operand, than in 910 * is greater than the width of the left operand, than in
911 * traditional C the left operand would be extended to the 911 * traditional C the left operand would be extended to the
912 * width of the right operand. For SHL this may result in 912 * width of the right operand. For SHL this may result in
913 * different results. 913 * different results.
914 */ 914 */
915 if (psize(lt) < psize(rt)) { 915 if (psize(lt) < psize(rt)) {
916 /* 916 /*
917 * XXX If both operands are constant, make sure 917 * XXX If both operands are constant, make sure
918 * that there is really a difference between 918 * that there is really a difference between
919 * ANSI C and traditional C. 919 * ANSI C and traditional C.
920 */ 920 */
921 if (hflag) 921 if (hflag)
922 /* semantics of '%s' change in ANSI C; ... */ 922 /* semantics of '%s' change in ANSI C; ... */
923 warning(118, mp->m_name); 923 warning(118, mp->m_name);
924 } 924 }
925 shift: 925 shift:
926 if (rn->tn_op == CON) { 926 if (rn->tn_op == CON) {
927 if (!tspec_is_uint(rt) && rn->tn_val->v_quad < 0) { 927 if (!tspec_is_uint(rt) && rn->tn_val->v_quad < 0) {
928 /* negative shift */ 928 /* negative shift */
929 warning(121); 929 warning(121);
930 } else if ((uint64_t)rn->tn_val->v_quad == (uint64_t)size(lt)) { 930 } else if ((uint64_t)rn->tn_val->v_quad == (uint64_t)size(lt)) {
931 /* shift equal to size of object */ 931 /* shift equal to size of object */
932 warning(267); 932 warning(267);
933 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size(lt)) { 933 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size(lt)) {
934 /* shift greater than size of object */ 934 /* shift greater than size of object */
935 warning(122); 935 warning(122);
936 } 936 }
937 } 937 }
938 break; 938 break;
939 case EQ: 939 case EQ:
940 case NE: 940 case NE:
941 /* 941 /*
942 * Accept some things which are allowed with EQ and NE, 942 * Accept some things which are allowed with EQ and NE,
943 * but not with ordered comparisons. 943 * but not with ordered comparisons.
944 */ 944 */
945 if (lt == PTR && ((rt == PTR && rst == VOID) || 945 if (lt == PTR && ((rt == PTR && rst == VOID) ||
946 tspec_is_int(rt))) { 946 tspec_is_int(rt))) {
947 if (rn->tn_op == CON && rn->tn_val->v_quad == 0) 947 if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
948 break; 948 break;
949 } 949 }
950 if (rt == PTR && ((lt == PTR && lst == VOID) || 950 if (rt == PTR && ((lt == PTR && lst == VOID) ||
951 tspec_is_int(lt))) { 951 tspec_is_int(lt))) {
952 if (ln->tn_op == CON && ln->tn_val->v_quad == 0) 952 if (ln->tn_op == CON && ln->tn_val->v_quad == 0)
953 break; 953 break;
954 } 954 }
955 /* FALLTHROUGH */ 955 /* FALLTHROUGH */
956 case LT: 956 case LT:
957 case GT: 957 case GT:
958 case LE: 958 case LE:
959 case GE: 959 case GE:
960 if ((lt == PTR || rt == PTR) && lt != rt) { 960 if ((lt == PTR || rt == PTR) && lt != rt) {
961 if (tspec_is_int(lt) || tspec_is_int(rt)) { 961 if (tspec_is_int(lt) || tspec_is_int(rt)) {
962 const char *lx = lt == PTR ? 962 const char *lx = lt == PTR ?
963 "pointer" : "integer"; 963 "pointer" : "integer";
964 const char *rx = rt == PTR ? 964 const char *rx = rt == PTR ?
965 "pointer" : "integer"; 965 "pointer" : "integer";
966 /* illegal combination of %s (%s) and ... */ 966 /* illegal combination of %s (%s) and ... */
967 warning(123, lx, type_name(ltp), 967 warning(123, lx, type_name(ltp),
968 rx, type_name(rtp), mp->m_name); 968 rx, type_name(rtp), mp->m_name);
969 } else { 969 } else {
970 warn_incompatible_types(op, lt, rt); 970 warn_incompatible_types(op, lt, rt);
971 return 0; 971 return 0;
972 } 972 }
973 } else if (lt == PTR && rt == PTR) { 973 } else if (lt == PTR && rt == PTR) {
974 check_pointer_comparison(op, ln, rn); 974 check_pointer_comparison(op, ln, rn);
975 } 975 }
976 break; 976 break;
977 case QUEST: 977 case QUEST:
978 if (!tspec_is_scalar(lt)) { 978 if (!tspec_is_scalar(lt)) {
979 /* first operand must have scalar type, op ? : */ 979 /* first operand must have scalar type, op ? : */
980 error(170); 980 error(170);
981 return 0; 981 return 0;
982 } 982 }
983 while (rn->tn_op == CVT) 983 while (rn->tn_op == CVT)
984 rn = rn->tn_left; 984 rn = rn->tn_left;
985 lint_assert(rn->tn_op == COLON); 985 lint_assert(rn->tn_op == COLON);
986 break; 986 break;
987 case COLON: 987 case COLON:
988 if (tspec_is_arith(lt) && tspec_is_arith(rt)) 988 if (tspec_is_arith(lt) && tspec_is_arith(rt))
989 break; 989 break;
990 990
991 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) 991 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str)
992 break; 992 break;
993 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) 993 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str)
994 break; 994 break;
995 995
996 /* combination of any pointer and 0, 0L or (void *)0 is ok */ 996 /* combination of any pointer and 0, 0L or (void *)0 is ok */
997 if (lt == PTR && ((rt == PTR && rst == VOID) || 997 if (lt == PTR && ((rt == PTR && rst == VOID) ||
998 tspec_is_int(rt))) { 998 tspec_is_int(rt))) {
999 if (rn->tn_op == CON && rn->tn_val->v_quad == 0) 999 if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
1000 break; 1000 break;
1001 } 1001 }
1002 if (rt == PTR && ((lt == PTR && lst == VOID) || 1002 if (rt == PTR && ((lt == PTR && lst == VOID) ||
1003 tspec_is_int(lt))) { 1003 tspec_is_int(lt))) {
1004 if (ln->tn_op == CON && ln->tn_val->v_quad == 0) 1004 if (ln->tn_op == CON && ln->tn_val->v_quad == 0)
1005 break; 1005 break;
1006 } 1006 }
1007 1007
1008 if ((lt == PTR && tspec_is_int(rt)) || 1008 if ((lt == PTR && tspec_is_int(rt)) ||
1009 (tspec_is_int(lt) && rt == PTR)) { 1009 (tspec_is_int(lt) && rt == PTR)) {
1010 const char *lx = lt == PTR ? "pointer" : "integer"; 1010 const char *lx = lt == PTR ? "pointer" : "integer";
1011 const char *rx = rt == PTR ? "pointer" : "integer"; 1011 const char *rx = rt == PTR ? "pointer" : "integer";
1012 /* illegal combination of %s (%s) and %s (%s), op %s */ 1012 /* illegal combination of %s (%s) and %s (%s), op %s */
1013 warning(123, lx, type_name(ltp), 1013 warning(123, lx, type_name(ltp),
1014 rx, type_name(rtp), mp->m_name); 1014 rx, type_name(rtp), mp->m_name);
1015 break; 1015 break;
1016 } 1016 }
1017 1017
1018 if (lt == VOID || rt == VOID) { 1018 if (lt == VOID || rt == VOID) {
1019 if (lt != VOID || rt != VOID) 1019 if (lt != VOID || rt != VOID)
1020 /* incompatible types in conditional */ 1020 /* incompatible types in conditional */
1021 warning(126); 1021 warning(126);
1022 break; 1022 break;
1023 } 1023 }
1024 1024
1025 if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || 1025 if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) ||
1026 (lst == FUNC && rst == VOID))) { 1026 (lst == FUNC && rst == VOID))) {
1027 /* (void *)0 handled above */ 1027 /* (void *)0 handled above */
1028 if (sflag) 1028 if (sflag)
1029 /* ANSI C forbids conv. of %s to %s, op %s */ 1029 /* ANSI C forbids conv. of %s to %s, op %s */
1030 warning(305, "function pointer", "'void *'", 1030 warning(305, "function pointer", "'void *'",
1031 mp->m_name); 1031 mp->m_name);
1032 break; 1032 break;
1033 } 1033 }
1034 1034
1035 if (rt == PTR && lt == PTR) { 1035 if (rt == PTR && lt == PTR) {
1036 if (eqptrtype(lstp, rstp, 1)) 1036 if (eqptrtype(lstp, rstp, 1))
1037 break; 1037 break;
1038 if (!eqtype(lstp, rstp, 1, 0, NULL)) 1038 if (!eqtype(lstp, rstp, 1, 0, NULL))
1039 warn_incompatible_pointers(mp, ltp, rtp); 1039 warn_incompatible_pointers(mp, ltp, rtp);
@@ -3020,1108 +3020,1121 @@ tsize(type_t *tp) @@ -3020,1108 +3020,1121 @@ tsize(type_t *tp)
3020 tp = tp->t_subt; 3020 tp = tp->t_subt;
3021 } 3021 }
3022 if (elem == 0) { 3022 if (elem == 0) {
3023 if (!flex) { 3023 if (!flex) {
3024 /* cannot take size/alignment of incomplete type */ 3024 /* cannot take size/alignment of incomplete type */
3025 error(143); 3025 error(143);
3026 elem = 1; 3026 elem = 1;
3027 } 3027 }
3028 } 3028 }
3029 switch (tp->t_tspec) { 3029 switch (tp->t_tspec) {
3030 case FUNC: 3030 case FUNC:
3031 /* cannot take size/alignment of function */ 3031 /* cannot take size/alignment of function */
3032 error(144); 3032 error(144);
3033 elsz = 1; 3033 elsz = 1;
3034 break; 3034 break;
3035 case STRUCT: 3035 case STRUCT:
3036 case UNION: 3036 case UNION:
3037 if (incompl(tp)) { 3037 if (incompl(tp)) {
3038 /* cannot take size/alignment of incomplete type */ 3038 /* cannot take size/alignment of incomplete type */
3039 error(143); 3039 error(143);
3040 elsz = 1; 3040 elsz = 1;
3041 } else { 3041 } else {
3042 elsz = tp->t_str->size; 3042 elsz = tp->t_str->size;
3043 } 3043 }
3044 break; 3044 break;
3045 case ENUM: 3045 case ENUM:
3046 if (incompl(tp)) { 3046 if (incompl(tp)) {
3047 /* cannot take size/alignment of incomplete type */ 3047 /* cannot take size/alignment of incomplete type */
3048 warning(143); 3048 warning(143);
3049 } 3049 }
3050 /* FALLTHROUGH */ 3050 /* FALLTHROUGH */
3051 default: 3051 default:
3052 if (tp->t_bitfield) { 3052 if (tp->t_bitfield) {
3053 /* cannot take size/alignment of bit-field */ 3053 /* cannot take size/alignment of bit-field */
3054 error(145); 3054 error(145);
3055 } 3055 }
3056 if (tp->t_tspec == VOID) { 3056 if (tp->t_tspec == VOID) {
3057 /* cannot take size/alignment of void */ 3057 /* cannot take size/alignment of void */
3058 error(146); 3058 error(146);
3059 elsz = 1; 3059 elsz = 1;
3060 } else { 3060 } else {
3061 elsz = size(tp->t_tspec); 3061 elsz = size(tp->t_tspec);
3062 lint_assert(elsz > 0); 3062 lint_assert(elsz > 0);
3063 } 3063 }
3064 break; 3064 break;
3065 } 3065 }
3066 3066
3067 /* XXX: type conversion is too late */ 3067 /* XXX: type conversion is too late */
3068 return (int64_t)(elem * elsz); 3068 return (int64_t)(elem * elsz);
3069} 3069}
3070 3070
3071/* 3071/*
3072 */ 3072 */
3073tnode_t * 3073tnode_t *
3074build_alignof(type_t *tp) 3074build_alignof(type_t *tp)
3075{ 3075{
3076 tspec_t st; 3076 tspec_t st;
3077 3077
3078 switch (tp->t_tspec) { 3078 switch (tp->t_tspec) {
3079 case ARRAY: 3079 case ARRAY:
3080 break; 3080 break;
3081 3081
3082 case FUNC: 3082 case FUNC:
3083 /* cannot take size/alignment of function */ 3083 /* cannot take size/alignment of function */
3084 error(144); 3084 error(144);
3085 return 0; 3085 return 0;
3086 3086
3087 case STRUCT: 3087 case STRUCT:
3088 case UNION: 3088 case UNION:
3089 if (incompl(tp)) { 3089 if (incompl(tp)) {
3090 /* cannot take size/alignment of incomplete type */ 3090 /* cannot take size/alignment of incomplete type */
3091 error(143); 3091 error(143);
3092 return 0; 3092 return 0;
3093 } 3093 }
3094 break; 3094 break;
3095 case ENUM: 3095 case ENUM:
3096 break; 3096 break;
3097 default: 3097 default:
3098 if (tp->t_bitfield) { 3098 if (tp->t_bitfield) {
3099 /* cannot take size/alignment of bit-field */ 3099 /* cannot take size/alignment of bit-field */
3100 error(145); 3100 error(145);
3101 return 0; 3101 return 0;
3102 } 3102 }
3103 if (tp->t_tspec == VOID) { 3103 if (tp->t_tspec == VOID) {
3104 /* cannot take size/alignment of void */ 3104 /* cannot take size/alignment of void */
3105 error(146); 3105 error(146);
3106 return 0; 3106 return 0;
3107 } 3107 }
3108 break; 3108 break;
3109 } 3109 }
3110 3110
3111#if SIZEOF_IS_ULONG 3111#if SIZEOF_IS_ULONG
3112 st = ULONG; 3112 st = ULONG;
3113#else 3113#else
3114 st = UINT; 3114 st = UINT;
3115#endif 3115#endif
3116 3116
3117 return new_integer_constant_node(st, (int64_t)getbound(tp) / CHAR_BIT); 3117 return new_integer_constant_node(st, (int64_t)getbound(tp) / CHAR_BIT);
3118} 3118}
3119 3119
3120/* 3120/*
3121 * Type casts. 3121 * Type casts.
3122 */ 3122 */
3123tnode_t * 3123tnode_t *
3124cast(tnode_t *tn, type_t *tp) 3124cast(tnode_t *tn, type_t *tp)
3125{ 3125{
3126 tspec_t nt, ot; 3126 tspec_t nt, ot;
3127 3127
3128 if (tn == NULL) 3128 if (tn == NULL)
3129 return NULL; 3129 return NULL;
3130 3130
3131 tn = cconv(tn); 3131 tn = cconv(tn);
3132 3132
3133 nt = tp->t_tspec; 3133 nt = tp->t_tspec;
3134 ot = tn->tn_type->t_tspec; 3134 ot = tn->tn_type->t_tspec;
3135 3135
3136 if (nt == VOID) { 3136 if (nt == VOID) {
3137 /* 3137 /*
3138 * XXX ANSI C requires scalar types or void (Plauger & Brodie). 3138 * XXX ANSI C requires scalar types or void (Plauger & Brodie).
3139 * But this seams really questionable. 3139 * But this seams really questionable.
3140 */ 3140 */
3141 } else if (nt == UNION) { 3141 } else if (nt == UNION) {
3142 sym_t *m; 3142 sym_t *m;
3143 str_t *str = tp->t_str; 3143 str_t *str = tp->t_str;
3144 if (!Sflag) { 3144 if (!Sflag) {
3145 /* union cast is a C9X feature */ 3145 /* union cast is a C9X feature */
3146 error(328); 3146 error(328);
3147 return NULL; 3147 return NULL;
3148 } 3148 }
3149 for (m = str->memb; m != NULL; m = m->s_next) { 3149 for (m = str->memb; m != NULL; m = m->s_next) {
3150 if (sametype(m->s_type, tn->tn_type)) { 3150 if (sametype(m->s_type, tn->tn_type)) {
3151 tn = getnode(); 3151 tn = getnode();
3152 tn->tn_op = CVT; 3152 tn->tn_op = CVT;
3153 tn->tn_type = tp; 3153 tn->tn_type = tp;
3154 tn->tn_cast = 1; 3154 tn->tn_cast = 1;
3155 tn->tn_right = NULL; 3155 tn->tn_right = NULL;
3156 return tn; 3156 return tn;
3157 } 3157 }
3158 } 3158 }
3159 /* type '%s' is not a member of '%s' */ 3159 /* type '%s' is not a member of '%s' */
3160 error(329, type_name(tn->tn_type), type_name(tp)); 3160 error(329, type_name(tn->tn_type), type_name(tp));
3161 return NULL; 3161 return NULL;
3162 } else if (nt == STRUCT || nt == ARRAY || nt == FUNC) { 3162 } else if (nt == STRUCT || nt == ARRAY || nt == FUNC) {
3163 if (!Sflag || nt == ARRAY || nt == FUNC) { 3163 if (!Sflag || nt == ARRAY || nt == FUNC) {
3164 /* invalid cast expression */ 3164 /* invalid cast expression */
3165 error(147); 3165 error(147);
3166 return NULL; 3166 return NULL;
3167 } 3167 }
3168 } else if (ot == STRUCT || ot == UNION) { 3168 } else if (ot == STRUCT || ot == UNION) {
3169 /* invalid cast expression */ 3169 /* invalid cast expression */
3170 error(147); 3170 error(147);
3171 return NULL; 3171 return NULL;
3172 } else if (ot == VOID) { 3172 } else if (ot == VOID) {
3173 /* improper cast of void expression */ 3173 /* improper cast of void expression */
3174 error(148); 3174 error(148);
3175 return NULL; 3175 return NULL;
3176 } else if (tspec_is_int(nt) && tspec_is_scalar(ot)) { 3176 } else if (tspec_is_int(nt) && tspec_is_scalar(ot)) {
3177 /* ok */ 3177 /* ok */
3178 } else if (tspec_is_float(nt) && tspec_is_arith(ot)) { 3178 } else if (tspec_is_float(nt) && tspec_is_arith(ot)) {
3179 /* ok */ 3179 /* ok */
3180 } else if (nt == PTR && tspec_is_int(ot)) { 3180 } else if (nt == PTR && tspec_is_int(ot)) {
3181 /* ok */ 3181 /* ok */
3182 } else if (nt == PTR && ot == PTR) { 3182 } else if (nt == PTR && ot == PTR) {
3183 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { 3183 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) {
3184 if (hflag) 3184 if (hflag)
3185 /* cast discards 'const' from ... */ 3185 /* cast discards 'const' from ... */
3186 warning(275); 3186 warning(275);
3187 } 3187 }
3188 } else { 3188 } else {
3189 /* invalid cast expression */ 3189 /* invalid cast expression */
3190 error(147); 3190 error(147);
3191 return NULL; 3191 return NULL;
3192 } 3192 }
3193 3193
3194 tn = convert(CVT, 0, tp, tn); 3194 tn = convert(CVT, 0, tp, tn);
3195 tn->tn_cast = 1; 3195 tn->tn_cast = 1;
3196 3196
3197 return tn; 3197 return tn;
3198} 3198}
3199 3199
3200/* 3200/*
3201 * Create the node for a function argument. 3201 * Create the node for a function argument.
3202 * All necessary conversions and type checks are done in 3202 * All necessary conversions and type checks are done in
3203 * new_function_call_node because new_function_argument_node has no 3203 * new_function_call_node because new_function_argument_node has no
3204 * information about expected argument types. 3204 * information about expected argument types.
3205 */ 3205 */
3206tnode_t * 3206tnode_t *
3207new_function_argument_node(tnode_t *args, tnode_t *arg) 3207new_function_argument_node(tnode_t *args, tnode_t *arg)
3208{ 3208{
3209 tnode_t *ntn; 3209 tnode_t *ntn;
3210 3210
3211 /* 3211 /*
3212 * If there was a serious error in the expression for the argument, 3212 * If there was a serious error in the expression for the argument,
3213 * create a dummy argument so the positions of the remaining arguments 3213 * create a dummy argument so the positions of the remaining arguments
3214 * will not change. 3214 * will not change.
3215 */ 3215 */
3216 if (arg == NULL) 3216 if (arg == NULL)
3217 arg = new_integer_constant_node(INT, (int64_t)0); 3217 arg = new_integer_constant_node(INT, (int64_t)0);
3218 3218
3219 ntn = new_tnode(PUSH, arg->tn_type, arg, args); 3219 ntn = new_tnode(PUSH, arg->tn_type, arg, args);
3220 3220
3221 return ntn; 3221 return ntn;
3222} 3222}
3223 3223
3224/* 3224/*
3225 * Create the node for a function call. Also check types of 3225 * Create the node for a function call. Also check types of
3226 * function arguments and insert conversions, if necessary. 3226 * function arguments and insert conversions, if necessary.
3227 */ 3227 */
3228tnode_t * 3228tnode_t *
3229new_function_call_node(tnode_t *func, tnode_t *args) 3229new_function_call_node(tnode_t *func, tnode_t *args)
3230{ 3230{
3231 tnode_t *ntn; 3231 tnode_t *ntn;
3232 op_t fcop; 3232 op_t fcop;
3233 3233
3234 if (func == NULL) 3234 if (func == NULL)
3235 return NULL; 3235 return NULL;
3236 3236
3237 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { 3237 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
3238 fcop = CALL; 3238 fcop = CALL;
3239 } else { 3239 } else {
3240 fcop = ICALL; 3240 fcop = ICALL;
3241 } 3241 }
3242 3242
3243 /* 3243 /*
3244 * after cconv() func will always be a pointer to a function 3244 * after cconv() func will always be a pointer to a function
3245 * if it is a valid function designator. 3245 * if it is a valid function designator.
3246 */ 3246 */
3247 func = cconv(func); 3247 func = cconv(func);
3248 3248
3249 if (func->tn_type->t_tspec != PTR || 3249 if (func->tn_type->t_tspec != PTR ||
3250 func->tn_type->t_subt->t_tspec != FUNC) { 3250 func->tn_type->t_subt->t_tspec != FUNC) {
3251 /* illegal function (type %s) */ 3251 /* illegal function (type %s) */
3252 error(149, type_name(func->tn_type)); 3252 error(149, type_name(func->tn_type));
3253 return NULL; 3253 return NULL;
3254 } 3254 }
3255 3255
3256 args = check_function_arguments(func->tn_type->t_subt, args); 3256 args = check_function_arguments(func->tn_type->t_subt, args);
3257 3257
3258 ntn = new_tnode(fcop, func->tn_type->t_subt->t_subt, func, args); 3258 ntn = new_tnode(fcop, func->tn_type->t_subt->t_subt, func, args);
3259 3259
3260 return ntn; 3260 return ntn;
3261} 3261}
3262 3262
3263/* 3263/*
3264 * Check types of all function arguments and insert conversions, 3264 * Check types of all function arguments and insert conversions,
3265 * if necessary. 3265 * if necessary.
3266 */ 3266 */
3267static tnode_t * 3267static tnode_t *
3268check_function_arguments(type_t *ftp, tnode_t *args) 3268check_function_arguments(type_t *ftp, tnode_t *args)
3269{ 3269{
3270 tnode_t *arg; 3270 tnode_t *arg;
3271 sym_t *asym; 3271 sym_t *asym;
3272 tspec_t at; 3272 tspec_t at;
3273 int narg, npar, n, i; 3273 int narg, npar, n, i;
3274 3274
3275 /* get # of args in the prototype */ 3275 /* get # of args in the prototype */
3276 npar = 0; 3276 npar = 0;
3277 for (asym = ftp->t_args; asym != NULL; asym = asym->s_next) 3277 for (asym = ftp->t_args; asym != NULL; asym = asym->s_next)
3278 npar++; 3278 npar++;
3279 3279
3280 /* get # of args in function call */ 3280 /* get # of args in function call */
3281 narg = 0; 3281 narg = 0;
3282 for (arg = args; arg != NULL; arg = arg->tn_right) 3282 for (arg = args; arg != NULL; arg = arg->tn_right)
3283 narg++; 3283 narg++;
3284 3284
3285 asym = ftp->t_args; 3285 asym = ftp->t_args;
3286 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { 3286 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
3287 /* argument mismatch: %d arg%s passed, %d expected */ 3287 /* argument mismatch: %d arg%s passed, %d expected */
3288 error(150, narg, narg > 1 ? "s" : "", npar); 3288 error(150, narg, narg > 1 ? "s" : "", npar);
3289 asym = NULL; 3289 asym = NULL;
3290 } 3290 }
3291 3291
3292 for (n = 1; n <= narg; n++) { 3292 for (n = 1; n <= narg; n++) {
3293 3293
3294 /* 3294 /*
3295 * The rightmost argument is at the top of the argument 3295 * The rightmost argument is at the top of the argument
3296 * subtree. 3296 * subtree.
3297 */ 3297 */
3298 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 3298 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right)
3299 continue; 3299 continue;
3300 3300
3301 /* some things which are always not allowed */ 3301 /* some things which are always not allowed */
3302 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { 3302 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
3303 /* void expressions may not be arguments, arg #%d */ 3303 /* void expressions may not be arguments, arg #%d */
3304 error(151, n); 3304 error(151, n);
3305 return NULL; 3305 return NULL;
3306 } else if ((at == STRUCT || at == UNION) && 3306 } else if ((at == STRUCT || at == UNION) &&
3307 incompl(arg->tn_left->tn_type)) { 3307 incompl(arg->tn_left->tn_type)) {
3308 /* argument cannot have unknown size, arg #%d */ 3308 /* argument cannot have unknown size, arg #%d */
3309 error(152, n); 3309 error(152, n);
3310 return NULL; 3310 return NULL;
3311 } else if (tspec_is_int(at) && 3311 } else if (tspec_is_int(at) &&
3312 arg->tn_left->tn_type->t_isenum && 3312 arg->tn_left->tn_type->t_isenum &&
3313 incompl(arg->tn_left->tn_type)) { 3313 incompl(arg->tn_left->tn_type)) {
3314 /* argument cannot have unknown size, arg #%d */ 3314 /* argument cannot have unknown size, arg #%d */
3315 warning(152, n); 3315 warning(152, n);
3316 } 3316 }
3317 3317
3318 /* class conversions (arg in value context) */ 3318 /* class conversions (arg in value context) */
3319 arg->tn_left = cconv(arg->tn_left); 3319 arg->tn_left = cconv(arg->tn_left);
3320 3320
3321 if (asym != NULL) { 3321 if (asym != NULL) {
3322 arg->tn_left = check_prototype_argument( 3322 arg->tn_left = check_prototype_argument(
3323 n, asym->s_type, arg->tn_left); 3323 n, asym->s_type, arg->tn_left);
3324 } else { 3324 } else {
3325 arg->tn_left = promote(NOOP, 1, arg->tn_left); 3325 arg->tn_left = promote(NOOP, 1, arg->tn_left);
3326 } 3326 }
3327 arg->tn_type = arg->tn_left->tn_type; 3327 arg->tn_type = arg->tn_left->tn_type;
3328 3328
3329 if (asym != NULL) 3329 if (asym != NULL)
3330 asym = asym->s_next; 3330 asym = asym->s_next;
3331 } 3331 }
3332 3332
3333 return args; 3333 return args;
3334} 3334}
3335 3335
3336/* 3336/*
3337 * Compare the type of an argument with the corresponding type of a 3337 * Compare the type of an argument with the corresponding type of a
3338 * prototype parameter. If it is a valid combination, but both types 3338 * prototype parameter. If it is a valid combination, but both types
3339 * are not the same, insert a conversion to convert the argument into 3339 * are not the same, insert a conversion to convert the argument into
3340 * the type of the parameter. 3340 * the type of the parameter.
3341 */ 3341 */
3342static tnode_t * 3342static tnode_t *
3343check_prototype_argument( 3343check_prototype_argument(
3344 int n, /* pos of arg */ 3344 int n, /* pos of arg */
3345 type_t *tp, /* expected type (from prototype) */ 3345 type_t *tp, /* expected type (from prototype) */
3346 tnode_t *tn) /* argument */ 3346 tnode_t *tn) /* argument */
3347{ 3347{
3348 tnode_t *ln; 3348 tnode_t *ln;
3349 int dowarn; 3349 int dowarn;
3350 3350
3351 ln = xcalloc(1, sizeof (tnode_t)); 3351 ln = xcalloc(1, sizeof (tnode_t));
3352 ln->tn_type = tduptyp(tp); 3352 ln->tn_type = tduptyp(tp);
3353 ln->tn_type->t_const = 0; 3353 ln->tn_type->t_const = 0;
3354 ln->tn_lvalue = 1; 3354 ln->tn_lvalue = 1;
3355 if (typeok(FARG, n, ln, tn)) { 3355 if (typeok(FARG, n, ln, tn)) {
3356 if (!eqtype(tp, tn->tn_type, 1, 0, (dowarn = 0, &dowarn)) || dowarn) 3356 if (!eqtype(tp, tn->tn_type, 1, 0, (dowarn = 0, &dowarn)) || dowarn)
3357 tn = convert(FARG, n, tp, tn); 3357 tn = convert(FARG, n, tp, tn);
3358 } 3358 }
3359 free(ln); 3359 free(ln);
3360 return tn; 3360 return tn;
3361} 3361}
3362 3362
3363/* 3363/*
3364 * Return the value of an integral constant expression. 3364 * Return the value of an integral constant expression.
3365 * If the expression is not constant or its type is not an integer 3365 * If the expression is not constant or its type is not an integer
3366 * type, an error message is printed. 3366 * type, an error message is printed.
3367 */ 3367 */
3368val_t * 3368val_t *
3369constant(tnode_t *tn, int required) 3369constant(tnode_t *tn, int required)
3370{ 3370{
3371 val_t *v; 3371 val_t *v;
3372 3372
3373 if (tn != NULL) 3373 if (tn != NULL)
3374 tn = cconv(tn); 3374 tn = cconv(tn);
3375 if (tn != NULL) 3375 if (tn != NULL)
3376 tn = promote(NOOP, 0, tn); 3376 tn = promote(NOOP, 0, tn);
3377 3377
3378 v = xcalloc(1, sizeof (val_t)); 3378 v = xcalloc(1, sizeof (val_t));
3379 3379
3380 if (tn == NULL) { 3380 if (tn == NULL) {
3381 lint_assert(nerr != 0); 3381 lint_assert(nerr != 0);
3382 v->v_tspec = INT; 3382 v->v_tspec = INT;
3383 v->v_quad = 1; 3383 v->v_quad = 1;
3384 return v; 3384 return v;
3385 } 3385 }
3386 3386
3387 v->v_tspec = tn->tn_type->t_tspec; 3387 v->v_tspec = tn->tn_type->t_tspec;
3388 3388
3389 if (tn->tn_op == CON) { 3389 if (tn->tn_op == CON) {
3390 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec); 3390 lint_assert(tn->tn_type->t_tspec == tn->tn_val->v_tspec);
3391 if (tspec_is_int(tn->tn_val->v_tspec)) { 3391 if (tspec_is_int(tn->tn_val->v_tspec)) {
3392 v->v_ansiu = tn->tn_val->v_ansiu; 3392 v->v_ansiu = tn->tn_val->v_ansiu;
3393 v->v_quad = tn->tn_val->v_quad; 3393 v->v_quad = tn->tn_val->v_quad;
3394 return v; 3394 return v;
3395 } 3395 }
3396 v->v_quad = tn->tn_val->v_ldbl; 3396 v->v_quad = tn->tn_val->v_ldbl;
3397 } else { 3397 } else {
3398 v->v_quad = 1; 3398 v->v_quad = 1;
3399 } 3399 }
3400 3400
3401 if (required) 3401 if (required)
3402 /* integral constant expression expected */ 3402 /* integral constant expression expected */
3403 error(55); 3403 error(55);
3404 else 3404 else
3405 /* variable array dimension is a C99/GCC extension */ 3405 /* variable array dimension is a C99/GCC extension */
3406 c99ism(318); 3406 c99ism(318);
3407 3407
3408 if (!tspec_is_int(v->v_tspec)) 3408 if (!tspec_is_int(v->v_tspec))
3409 v->v_tspec = INT; 3409 v->v_tspec = INT;
3410 3410
3411 return v; 3411 return v;
3412} 3412}
3413 3413
3414/* 3414/*
3415 * Perform some tests on expressions which can't be done in build() and 3415 * Perform some tests on expressions which can't be done in build() and
3416 * functions called by build(). These tests must be done here because 3416 * functions called by build(). These tests must be done here because
3417 * we need some information about the context in which the operations 3417 * we need some information about the context in which the operations
3418 * are performed. 3418 * are performed.
3419 * After all tests are performed, expr() frees the memory which is used 3419 * After all tests are performed, expr() frees the memory which is used
3420 * for the expression. 3420 * for the expression.
3421 */ 3421 */
3422void 3422void
3423expr(tnode_t *tn, int vctx, int tctx, int dofreeblk) 3423expr(tnode_t *tn, int vctx, int tctx, int dofreeblk)
3424{ 3424{
3425 3425
3426 lint_assert(tn != NULL || nerr != 0); 3426 lint_assert(tn != NULL || nerr != 0);
3427 3427
3428 if (tn == NULL) { 3428 if (tn == NULL) {
3429 tfreeblk(); 3429 tfreeblk();
3430 return; 3430 return;
3431 } 3431 }
3432 3432
3433 /* expr() is also called in global initialisations */ 3433 /* expr() is also called in global initialisations */
3434 if (dcs->d_ctx != EXTERN) 3434 if (dcs->d_ctx != EXTERN)
3435 check_statement_reachable(); 3435 check_statement_reachable();
3436 3436
3437 check_expr_misc(tn, vctx, tctx, !tctx, 0, 0, 0); 3437 check_expr_misc(tn, vctx, tctx, !tctx, 0, 0, 0);
3438 if (tn->tn_op == ASSIGN) { 3438 if (tn->tn_op == ASSIGN) {
3439 if (hflag && tctx) 3439 if (hflag && tctx)
3440 /* assignment in conditional context */ 3440 /* assignment in conditional context */
3441 warning(159); 3441 warning(159);
3442 } else if (tn->tn_op == CON) { 3442 } else if (tn->tn_op == CON) {
3443 if (hflag && tctx && !constcond_flag) 3443 if (hflag && tctx && !constcond_flag)
3444 /* constant in conditional context */ 3444 /* constant in conditional context */
3445 warning(161); 3445 warning(161);
3446 } 3446 }
3447 if (!modtab[tn->tn_op].m_sideeff) { 3447 if (!modtab[tn->tn_op].m_sideeff) {
3448 /* 3448 /*
3449 * for left operands of COMMA this warning is already 3449 * for left operands of COMMA this warning is already
3450 * printed 3450 * printed
3451 */ 3451 */
3452 if (tn->tn_op != COMMA && !vctx && !tctx) 3452 if (tn->tn_op != COMMA && !vctx && !tctx)
3453 check_null_effect(tn); 3453 check_null_effect(tn);
3454 } 3454 }
3455 if (dflag) 3455 if (dflag)
3456 display_expression(tn, 0); 3456 display_expression(tn, 0);
3457 3457
3458 /* free the tree memory */ 3458 /* free the tree memory */
3459 if (dofreeblk) 3459 if (dofreeblk)
3460 tfreeblk(); 3460 tfreeblk();
3461} 3461}
3462 3462
3463static void 3463static void
3464check_null_effect(tnode_t *tn) 3464check_null_effect(tnode_t *tn)
3465{ 3465{
3466 3466
3467 if (!hflag) 3467 if (!hflag)
3468 return; 3468 return;
3469 3469
3470 while (!modtab[tn->tn_op].m_sideeff) { 3470 while (!modtab[tn->tn_op].m_sideeff) {
3471 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { 3471 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) {
3472 tn = tn->tn_left; 3472 tn = tn->tn_left;
3473 } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { 3473 } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) {
3474 /* 3474 /*
3475 * && and || have a side effect if the right operand 3475 * && and || have a side effect if the right operand
3476 * has a side effect. 3476 * has a side effect.
3477 */ 3477 */
3478 tn = tn->tn_right; 3478 tn = tn->tn_right;
3479 } else if (tn->tn_op == QUEST) { 3479 } else if (tn->tn_op == QUEST) {
3480 /* 3480 /*
3481 * ? has a side effect if at least one of its right 3481 * ? has a side effect if at least one of its right
3482 * operands has a side effect 3482 * operands has a side effect
3483 */ 3483 */
3484 tn = tn->tn_right; 3484 tn = tn->tn_right;
3485 } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { 3485 } else if (tn->tn_op == COLON || tn->tn_op == COMMA) {
3486 /* 3486 /*
3487 * : has a side effect if at least one of its operands 3487 * : has a side effect if at least one of its operands
3488 * has a side effect 3488 * has a side effect
3489 */ 3489 */
3490 if (modtab[tn->tn_left->tn_op].m_sideeff) { 3490 if (modtab[tn->tn_left->tn_op].m_sideeff) {
3491 tn = tn->tn_left; 3491 tn = tn->tn_left;
3492 } else if (modtab[tn->tn_right->tn_op].m_sideeff) { 3492 } else if (modtab[tn->tn_right->tn_op].m_sideeff) {
3493 tn = tn->tn_right; 3493 tn = tn->tn_right;
3494 } else { 3494 } else {
3495 break; 3495 break;
3496 } 3496 }
3497 } else { 3497 } else {
3498 break; 3498 break;
3499 } 3499 }
3500 } 3500 }
3501 if (!modtab[tn->tn_op].m_sideeff) 3501 if (!modtab[tn->tn_op].m_sideeff)
3502 /* expression has null effect */ 3502 /* expression has null effect */
3503 warning(129); 3503 warning(129);
3504} 3504}
3505 3505
3506/* 3506/*
3507 * Dump an expression to stdout 3507 * Dump an expression to stdout
3508 * only used for debugging 3508 * only used for debugging
3509 */ 3509 */
3510static void 3510static void
3511display_expression(tnode_t *tn, int offs) 3511display_expression(tnode_t *tn, int offs)
3512{ 3512{
3513 uint64_t uq; 3513 uint64_t uq;
3514 3514
3515 if (tn == NULL) { 3515 if (tn == NULL) {
3516 (void)printf("%*s%s\n", offs, "", "NULL"); 3516 (void)printf("%*s%s\n", offs, "", "NULL");
3517 return; 3517 return;
3518 } 3518 }
3519 (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); 3519 (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name);
3520 3520
3521 if (tn->tn_op == NAME) { 3521 if (tn->tn_op == NAME) {
3522 (void)printf("%s: %s ", 3522 (void)printf("%s: %s ",
3523 tn->tn_sym->s_name, 3523 tn->tn_sym->s_name,
3524 storage_class_name(tn->tn_sym->s_scl)); 3524 storage_class_name(tn->tn_sym->s_scl));
3525 } else if (tn->tn_op == CON && tspec_is_float(tn->tn_type->t_tspec)) { 3525 } else if (tn->tn_op == CON && tspec_is_float(tn->tn_type->t_tspec)) {
3526 (void)printf("%#g ", (double)tn->tn_val->v_ldbl); 3526 (void)printf("%#g ", (double)tn->tn_val->v_ldbl);
3527 } else if (tn->tn_op == CON && tspec_is_int(tn->tn_type->t_tspec)) { 3527 } else if (tn->tn_op == CON && tspec_is_int(tn->tn_type->t_tspec)) {
3528 uq = tn->tn_val->v_quad; 3528 uq = tn->tn_val->v_quad;
3529 (void)printf("0x %08lx %08lx ", 3529 (void)printf("0x %08lx %08lx ",
3530 (long)(uq >> 32) & 0xffffffffl, 3530 (long)(uq >> 32) & 0xffffffffl,
3531 (long)uq & 0xffffffffl); 3531 (long)uq & 0xffffffffl);
3532 } else if (tn->tn_op == CON) { 3532 } else if (tn->tn_op == CON) {
3533 lint_assert(tn->tn_type->t_tspec == PTR); 3533 lint_assert(tn->tn_type->t_tspec == PTR);
3534 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), 3534 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4),
3535 (u_long)tn->tn_val->v_quad); 3535 (u_long)tn->tn_val->v_quad);
3536 } else if (tn->tn_op == STRING) { 3536 } else if (tn->tn_op == STRING) {
3537 if (tn->tn_string->st_tspec == CHAR) { 3537 if (tn->tn_string->st_tspec == CHAR) {
3538 (void)printf("\"%s\"", tn->tn_string->st_cp); 3538 (void)printf("\"%s\"", tn->tn_string->st_cp);
3539 } else { 3539 } else {
3540 char *s; 3540 char *s;
3541 size_t n; 3541 size_t n;
3542 n = MB_CUR_MAX * (tn->tn_string->st_len + 1); 3542 n = MB_CUR_MAX * (tn->tn_string->st_len + 1);
3543 s = xmalloc(n); 3543 s = xmalloc(n);
3544 (void)wcstombs(s, tn->tn_string->st_wcp, n); 3544 (void)wcstombs(s, tn->tn_string->st_wcp, n);
3545 (void)printf("L\"%s\"", s); 3545 (void)printf("L\"%s\"", s);
3546 free(s); 3546 free(s);
3547 } 3547 }
3548 (void)printf(" "); 3548 (void)printf(" ");
3549 } else if (tn->tn_op == FSEL) { 3549 } else if (tn->tn_op == FSEL) {
3550 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, 3550 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs,
3551 tn->tn_type->t_flen); 3551 tn->tn_type->t_flen);
3552 } 3552 }
3553 (void)printf("%s\n", ttos(tn->tn_type)); 3553 (void)printf("%s\n", ttos(tn->tn_type));
3554 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) 3554 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING)
3555 return; 3555 return;
3556 display_expression(tn->tn_left, offs + 2); 3556 display_expression(tn->tn_left, offs + 2);
3557 if (modtab[tn->tn_op].m_binary || 3557 if (modtab[tn->tn_op].m_binary ||
3558 (tn->tn_op == PUSH && tn->tn_right != NULL)) { 3558 (tn->tn_op == PUSH && tn->tn_right != NULL)) {
3559 display_expression(tn->tn_right, offs + 2); 3559 display_expression(tn->tn_right, offs + 2);
3560 } 3560 }
3561} 3561}
3562 3562
3563/* 3563/*
3564 * Called by expr() to recursively perform some tests. 3564 * Called by expr() to recursively perform some tests.
3565 */ 3565 */
3566/* ARGSUSED */ 3566/* ARGSUSED */
3567void 3567void
3568check_expr_misc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, 3568check_expr_misc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc,
3569 int szof) 3569 int szof)
3570{ 3570{
3571 tnode_t *ln, *rn; 3571 tnode_t *ln, *rn;
3572 mod_t *mp; 3572 mod_t *mp;
3573 int nrvdisc, cvctx, ctctx; 3573 int nrvdisc, cvctx, ctctx;
3574 op_t op; 3574 op_t op;
3575 scl_t sc; 3575 scl_t sc;
3576 dinfo_t *di; 3576 dinfo_t *di;
3577 3577
3578 if (tn == NULL) 3578 if (tn == NULL)
3579 return; 3579 return;
3580 3580
3581 ln = tn->tn_left; 3581 ln = tn->tn_left;
3582 rn = tn->tn_right; 3582 rn = tn->tn_right;
3583 mp = &modtab[op = tn->tn_op]; 3583 mp = &modtab[op = tn->tn_op];
3584 3584
3585 switch (op) { 3585 switch (op) {
3586 case AMPER: 3586 case AMPER:
3587 if (ln->tn_op == NAME && (reached || rchflg)) { 3587 if (ln->tn_op == NAME && (reached || rchflg)) {
3588 if (!szof) 3588 if (!szof)
3589 mark_as_set(ln->tn_sym); 3589 mark_as_set(ln->tn_sym);
3590 mark_as_used(ln->tn_sym, fcall, szof); 3590 mark_as_used(ln->tn_sym, fcall, szof);
3591 } 3591 }
3592 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3592 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3593 /* check the range of array indices */ 3593 /* check the range of array indices */
3594 check_array_index(ln->tn_left, 1); 3594 check_array_index(ln->tn_left, 1);
3595 break; 3595 break;
3596 case LOAD: 3596 case LOAD:
3597 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3597 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3598 /* check the range of array indices */ 3598 /* check the range of array indices */
3599 check_array_index(ln->tn_left, 0); 3599 check_array_index(ln->tn_left, 0);
3600 /* FALLTHROUGH */ 3600 /* FALLTHROUGH */
3601 case PUSH: 3601 case PUSH:
3602 case INCBEF: 3602 case INCBEF:
3603 case DECBEF: 3603 case DECBEF:
3604 case INCAFT: 3604 case INCAFT:
3605 case DECAFT: 3605 case DECAFT:
3606 case ADDASS: 3606 case ADDASS:
3607 case SUBASS: 3607 case SUBASS:
3608 case MULASS: 3608 case MULASS:
3609 case DIVASS: 3609 case DIVASS:
3610 case MODASS: 3610 case MODASS:
3611 case ANDASS: 3611 case ANDASS:
3612 case ORASS: 3612 case ORASS:
3613 case XORASS: 3613 case XORASS:
3614 case SHLASS: 3614 case SHLASS:
3615 case SHRASS: 3615 case SHRASS:
3616 case REAL: 3616 case REAL:
3617 case IMAG: 3617 case IMAG:
3618 if (ln->tn_op == NAME && (reached || rchflg)) { 3618 if (ln->tn_op == NAME && (reached || rchflg)) {
3619 sc = ln->tn_sym->s_scl; 3619 sc = ln->tn_sym->s_scl;
3620 /* 3620 /*
3621 * Look if there was a asm statement in one of the 3621 * Look if there was a asm statement in one of the
3622 * compound statements we are in. If not, we don't 3622 * compound statements we are in. If not, we don't
3623 * print a warning. 3623 * print a warning.
3624 */ 3624 */
3625 for (di = dcs; di != NULL; di = di->d_next) { 3625 for (di = dcs; di != NULL; di = di->d_next) {
3626 if (di->d_asm) 3626 if (di->d_asm)
3627 break; 3627 break;
3628 } 3628 }
3629 if (sc != EXTERN && sc != STATIC && 3629 if (sc != EXTERN && sc != STATIC &&
3630 !ln->tn_sym->s_set && !szof && di == NULL) { 3630 !ln->tn_sym->s_set && !szof && di == NULL) {
3631 /* %s may be used before set */ 3631 /* %s may be used before set */
3632 warning(158, ln->tn_sym->s_name); 3632 warning(158, ln->tn_sym->s_name);
3633 mark_as_set(ln->tn_sym); 3633 mark_as_set(ln->tn_sym);
3634 } 3634 }
3635 mark_as_used(ln->tn_sym, 0, 0); 3635 mark_as_used(ln->tn_sym, 0, 0);
3636 } 3636 }
3637 break; 3637 break;
3638 case ASSIGN: 3638 case ASSIGN:
3639 if (ln->tn_op == NAME && !szof && (reached || rchflg)) { 3639 if (ln->tn_op == NAME && !szof && (reached || rchflg)) {
3640 mark_as_set(ln->tn_sym); 3640 mark_as_set(ln->tn_sym);
3641 if (ln->tn_sym->s_scl == EXTERN) 3641 if (ln->tn_sym->s_scl == EXTERN)
3642 outusg(ln->tn_sym); 3642 outusg(ln->tn_sym);
3643 } 3643 }
3644 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3644 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3645 /* check the range of array indices */ 3645 /* check the range of array indices */
3646 check_array_index(ln->tn_left, 0); 3646 check_array_index(ln->tn_left, 0);
3647 break; 3647 break;
3648 case CALL: 3648 case CALL:
3649 lint_assert(ln->tn_op == AMPER); 3649 lint_assert(ln->tn_op == AMPER);
3650 lint_assert(ln->tn_left->tn_op == NAME); 3650 lint_assert(ln->tn_left->tn_op == NAME);
3651 if (!szof) 3651 if (!szof)
3652 outcall(tn, vctx || tctx, rvdisc); 3652 outcall(tn, vctx || tctx, rvdisc);
3653 break; 3653 break;
3654 case EQ: 3654 case EQ:
3655 if (hflag && eqwarn) 3655 if (hflag && eqwarn)
3656 /* operator '==' found where '=' was expected */ 3656 /* operator '==' found where '=' was expected */
3657 warning(160); 3657 warning(160);
3658 break; 3658 break;
3659 case CON: 3659 case CON:
3660 case NAME: 3660 case NAME:
3661 case STRING: 3661 case STRING:
3662 return; 3662 return;
3663 /* LINTED206: (enumeration values not handled in switch) */ 3663 /* LINTED206: (enumeration values not handled in switch) */
3664 case OR: 3664 case OR:
3665 case XOR: 3665 case XOR:
3666 case NE: 3666 case NE:
3667 case GE: 3667 case GE:
3668 case GT: 3668 case GT:
3669 case LE: 3669 case LE:
3670 case LT: 3670 case LT:
3671 case SHR: 3671 case SHR:
3672 case SHL: 3672 case SHL:
3673 case MINUS: 3673 case MINUS:
3674 case PLUS: 3674 case PLUS:
3675 case MOD: 3675 case MOD:
3676 case DIV: 3676 case DIV:
3677 case MULT: 3677 case MULT:
3678 case STAR: 3678 case STAR:
3679 case UMINUS: 3679 case UMINUS:
3680 case UPLUS: 3680 case UPLUS:
3681 case DEC: 3681 case DEC:
3682 case INC: 3682 case INC:
3683 case COMPL: 3683 case COMPL:
3684 case NOT: 3684 case NOT:
3685 case POINT: 3685 case POINT:
3686 case ARROW: 3686 case ARROW:
3687 case NOOP: 3687 case NOOP:
3688 case AND: 3688 case AND:
3689 case FARG: 3689 case FARG:
3690 case CASE: 3690 case CASE:
3691 case INIT: 3691 case INIT:
3692 case RETURN: 3692 case RETURN:
3693 case ICALL: 3693 case ICALL:
3694 case CVT: 3694 case CVT:
3695 case COMMA: 3695 case COMMA:
3696 case FSEL: 3696 case FSEL:
3697 case COLON: 3697 case COLON:
3698 case QUEST: 3698 case QUEST:
3699 case LOGOR: 3699 case LOGOR:
3700 case LOGAND: 3700 case LOGAND:
3701 break; 3701 break;
3702 } 3702 }
3703 3703
3704 cvctx = mp->m_vctx; 3704 cvctx = mp->m_vctx;
3705 ctctx = mp->m_tctx; 3705 ctctx = mp->m_tctx;
3706 /* 3706 /*
3707 * values of operands of ':' are not used if the type of at least 3707 * values of operands of ':' are not used if the type of at least
3708 * one of the operands (for gcc compatibility) is void 3708 * one of the operands (for gcc compatibility) is void
3709 * XXX test/value context of QUEST should probably be used as 3709 * XXX test/value context of QUEST should probably be used as
3710 * context for both operands of COLON 3710 * context for both operands of COLON
3711 */ 3711 */
3712 if (op == COLON && tn->tn_type->t_tspec == VOID) 3712 if (op == COLON && tn->tn_type->t_tspec == VOID)
3713 cvctx = ctctx = 0; 3713 cvctx = ctctx = 0;
3714 nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; 3714 nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID;
3715 check_expr_misc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); 3715 check_expr_misc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof);
3716 3716
3717 switch (op) { 3717 switch (op) {
3718 case PUSH: 3718 case PUSH:
3719 if (rn != NULL) 3719 if (rn != NULL)
3720 check_expr_misc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); 3720 check_expr_misc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof);
3721 break; 3721 break;
3722 case LOGAND: 3722 case LOGAND:
3723 case LOGOR: 3723 case LOGOR:
3724 check_expr_misc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); 3724 check_expr_misc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof);
3725 break; 3725 break;
3726 case COLON: 3726 case COLON:
3727 check_expr_misc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); 3727 check_expr_misc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof);
3728 break; 3728 break;
3729 case COMMA: 3729 case COMMA:
3730 check_expr_misc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); 3730 check_expr_misc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof);
3731 break; 3731 break;
3732 default: 3732 default:
3733 if (mp->m_binary) 3733 if (mp->m_binary)
3734 check_expr_misc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); 3734 check_expr_misc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof);
3735 break; 3735 break;
3736 } 3736 }
3737 3737
3738} 3738}
3739 3739
3740/* 3740/*
3741 * Checks the range of array indices, if possible. 3741 * Checks the range of array indices, if possible.
3742 * amper is set if only the address of the element is used. This 3742 * amper is set if only the address of the element is used. This
3743 * means that the index is allowed to refer to the first element 3743 * means that the index is allowed to refer to the first element
3744 * after the array. 3744 * after the array.
3745 */ 3745 */
3746static void 3746static void
3747check_array_index(tnode_t *tn, int amper) 3747check_array_index(tnode_t *tn, int amper)
3748{ 3748{
3749 int dim; 3749 int dim;
3750 tnode_t *ln, *rn; 3750 tnode_t *ln, *rn;
3751 int elsz; 3751 int elsz;
3752 int64_t con; 3752 int64_t con;
3753 3753
3754 ln = tn->tn_left; 3754 ln = tn->tn_left;
3755 rn = tn->tn_right; 3755 rn = tn->tn_right;
3756 3756
3757 /* We can only check constant indices. */ 3757 /* We can only check constant indices. */
3758 if (rn->tn_op != CON) 3758 if (rn->tn_op != CON)
3759 return; 3759 return;
3760 3760
3761 /* Return if the left node does not stem from an array. */ 3761 /* Return if the left node does not stem from an array. */
3762 if (ln->tn_op != AMPER) 3762 if (ln->tn_op != AMPER)
3763 return; 3763 return;
3764 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) 3764 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
3765 return; 3765 return;
3766 if (ln->tn_left->tn_type->t_tspec != ARRAY) 3766 if (ln->tn_left->tn_type->t_tspec != ARRAY)
3767 return; 3767 return;
3768 3768
3769 /* 3769 /*
3770 * For incomplete array types, we can print a warning only if 3770 * For incomplete array types, we can print a warning only if
3771 * the index is negative. 3771 * the index is negative.
3772 */ 3772 */
3773 if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) 3773 if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
3774 return; 3774 return;
3775 3775
3776 /* Get the size of one array element */ 3776 /* Get the size of one array element */
3777 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) 3777 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0)
3778 return; 3778 return;
3779 elsz /= CHAR_BIT; 3779 elsz /= CHAR_BIT;
3780 3780
3781 /* Change the unit of the index from bytes to element size. */ 3781 /* Change the unit of the index from bytes to element size. */
3782 if (tspec_is_uint(rn->tn_type->t_tspec)) { 3782 if (tspec_is_uint(rn->tn_type->t_tspec)) {
3783 con = (uint64_t)rn->tn_val->v_quad / elsz; 3783 con = (uint64_t)rn->tn_val->v_quad / elsz;
3784 } else { 3784 } else {
3785 con = rn->tn_val->v_quad / elsz; 3785 con = rn->tn_val->v_quad / elsz;
3786 } 3786 }
3787 3787
3788 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); 3788 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
3789 3789
3790 if (!tspec_is_uint(rn->tn_type->t_tspec) && con < 0) { 3790 if (!tspec_is_uint(rn->tn_type->t_tspec) && con < 0) {
3791 /* array subscript cannot be negative: %ld */ 3791 /* array subscript cannot be negative: %ld */
3792 warning(167, (long)con); 3792 warning(167, (long)con);
3793 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { 3793 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) {
3794 /* array subscript cannot be > %d: %ld */ 3794 /* array subscript cannot be > %d: %ld */
3795 warning(168, dim - 1, (long)con); 3795 warning(168, dim - 1, (long)con);
3796 } 3796 }
3797} 3797}
3798 3798
3799/* 3799/*
3800 * Check for ordered comparisons of unsigned values with 0. 3800 * Check for ordered comparisons of unsigned values with 0.
3801 */ 3801 */
3802static void 3802static void
3803check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn) 3803check_integer_comparison(op_t op, tnode_t *ln, tnode_t *rn)
3804{ 3804{
3805 tspec_t lt, rt; 3805 tspec_t lt, rt;
3806 mod_t *mp; 3806 mod_t *mp;
3807 3807
3808 lt = ln->tn_type->t_tspec; 3808 lt = ln->tn_type->t_tspec;
3809 rt = rn->tn_type->t_tspec; 3809 rt = rn->tn_type->t_tspec;
3810 mp = &modtab[op]; 3810 mp = &modtab[op];
3811 3811
3812 if (ln->tn_op != CON && rn->tn_op != CON) 3812 if (ln->tn_op != CON && rn->tn_op != CON)
3813 return; 3813 return;
3814 3814
3815 if (!tspec_is_int(lt) || !tspec_is_int(rt)) 3815 if (!tspec_is_int(lt) || !tspec_is_int(rt))
3816 return; 3816 return;
3817 3817
3818 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && 3818 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
3819 (rn->tn_val->v_quad < 0 || 3819 (rn->tn_val->v_quad < 0 ||
3820 rn->tn_val->v_quad > (int)~(~0U << (CHAR_BIT - 1)))) { 3820 rn->tn_val->v_quad > (int)~(~0U << (CHAR_BIT - 1)))) {
3821 /* nonportable character comparison, op %s */ 3821 /* nonportable character comparison, op %s */
3822 warning(230, mp->m_name); 3822 warning(230, mp->m_name);
3823 return; 3823 return;
3824 } 3824 }
3825 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && 3825 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
3826 (ln->tn_val->v_quad < 0 || 3826 (ln->tn_val->v_quad < 0 ||
3827 ln->tn_val->v_quad > (int)~(~0U << (CHAR_BIT - 1)))) { 3827 ln->tn_val->v_quad > (int)~(~0U << (CHAR_BIT - 1)))) {
3828 /* nonportable character comparison, op %s */ 3828 /* nonportable character comparison, op %s */
3829 warning(230, mp->m_name); 3829 warning(230, mp->m_name);
3830 return; 3830 return;
3831 } 3831 }
3832 if (tspec_is_uint(lt) && !tspec_is_uint(rt) && 3832 if (tspec_is_uint(lt) && !tspec_is_uint(rt) &&
3833 rn->tn_op == CON && rn->tn_val->v_quad <= 0) { 3833 rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
3834 if (rn->tn_val->v_quad < 0) { 3834 if (rn->tn_val->v_quad < 0) {
3835 /* comparison of %s with %s, op %s */ 3835 /* comparison of %s with %s, op %s */
3836 warning(162, type_name(ln->tn_type), 3836 warning(162, type_name(ln->tn_type),
3837 "negative constant", mp->m_name); 3837 "negative constant", mp->m_name);
3838 } else if (op == LT || op == GE || (hflag && op == LE)) { 3838 } else if (op == LT || op == GE || (hflag && op == LE)) {
3839 /* comparison of %s with %s, op %s */ 3839 /* comparison of %s with %s, op %s */
3840 warning(162, type_name(ln->tn_type), "0", mp->m_name); 3840 warning(162, type_name(ln->tn_type), "0", mp->m_name);
3841 } 3841 }
3842 return; 3842 return;
3843 } 3843 }
3844 if (tspec_is_uint(rt) && !tspec_is_uint(lt) && 3844 if (tspec_is_uint(rt) && !tspec_is_uint(lt) &&
3845 ln->tn_op == CON && ln->tn_val->v_quad <= 0) { 3845 ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
3846 if (ln->tn_val->v_quad < 0) { 3846 if (ln->tn_val->v_quad < 0) {
3847 /* comparison of %s with %s, op %s */ 3847 /* comparison of %s with %s, op %s */
3848 warning(162, "negative constant", 3848 warning(162, "negative constant",
3849 type_name(rn->tn_type), mp->m_name); 3849 type_name(rn->tn_type), mp->m_name);
3850 } else if (op == GT || op == LE || (hflag && op == GE)) { 3850 } else if (op == GT || op == LE || (hflag && op == GE)) {
3851 /* comparison of %s with %s, op %s */ 3851 /* comparison of %s with %s, op %s */
3852 warning(162, "0", type_name(rn->tn_type), mp->m_name); 3852 warning(162, "0", type_name(rn->tn_type), mp->m_name);
3853 } 3853 }
3854 return; 3854 return;
3855 } 3855 }
3856} 3856}
3857 3857
3858/* 3858/*
3859 * Takes an expression an returns 0 if this expression can be used 3859 * Takes an expression an returns 0 if this expression can be used
3860 * for static initialisation, otherwise -1. 3860 * for static initialisation, otherwise -1.
3861 * 3861 *
3862 * Constant initialisation expressions must be constant or an address 3862 * Constant initialisation expressions must be constant or an address
3863 * of a static object with an optional offset. In the first case, 3863 * of a static object with an optional offset. In the first case,
3864 * the result is returned in *offsp. In the second case, the static 3864 * the result is returned in *offsp. In the second case, the static
3865 * object is returned in *symp and the offset in *offsp. 3865 * object is returned in *symp and the offset in *offsp.
3866 * 3866 *
3867 * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and 3867 * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and
3868 * CON. Type conversions are allowed if they do not change binary 3868 * CON. Type conversions are allowed if they do not change binary
3869 * representation (including width). 3869 * representation (including width).
3870 */ 3870 */
3871int 3871int
3872conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) 3872conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp)
3873{ 3873{
3874 sym_t *sym; 3874 sym_t *sym;
3875 ptrdiff_t offs1, offs2; 3875 ptrdiff_t offs1, offs2;
3876 tspec_t t, ot; 3876 tspec_t t, ot;
3877 3877
3878 switch (tn->tn_op) { 3878 switch (tn->tn_op) {
3879 case MINUS: 3879 case MINUS:
3880 if (tn->tn_right->tn_op == CVT) 3880 if (tn->tn_right->tn_op == CVT)
3881 return conaddr(tn->tn_right, symp, offsp); 3881 return conaddr(tn->tn_right, symp, offsp);
3882 else if (tn->tn_right->tn_op != CON) 3882 else if (tn->tn_right->tn_op != CON)
3883 return -1; 3883 return -1;
3884 /* FALLTHROUGH */ 3884 /* FALLTHROUGH */
3885 case PLUS: 3885 case PLUS:
3886 offs1 = offs2 = 0; 3886 offs1 = offs2 = 0;
3887 if (tn->tn_left->tn_op == CON) { 3887 if (tn->tn_left->tn_op == CON) {
3888 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; 3888 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
3889 if (conaddr(tn->tn_right, &sym, &offs2) == -1) 3889 if (conaddr(tn->tn_right, &sym, &offs2) == -1)
3890 return -1; 3890 return -1;
3891 } else if (tn->tn_right->tn_op == CON) { 3891 } else if (tn->tn_right->tn_op == CON) {
3892 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; 3892 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad;
3893 if (tn->tn_op == MINUS) 3893 if (tn->tn_op == MINUS)
3894 offs2 = -offs2; 3894 offs2 = -offs2;
3895 if (conaddr(tn->tn_left, &sym, &offs1) == -1) 3895 if (conaddr(tn->tn_left, &sym, &offs1) == -1)
3896 return -1; 3896 return -1;
3897 } else { 3897 } else {
3898 return -1; 3898 return -1;
3899 } 3899 }
3900 *symp = sym; 3900 *symp = sym;
3901 *offsp = offs1 + offs2; 3901 *offsp = offs1 + offs2;
3902 break; 3902 break;
3903 case AMPER: 3903 case AMPER:
3904 if (tn->tn_left->tn_op == NAME) { 3904 if (tn->tn_left->tn_op == NAME) {
3905 *symp = tn->tn_left->tn_sym; 3905 *symp = tn->tn_left->tn_sym;
3906 *offsp = 0; 3906 *offsp = 0;
3907 } else if (tn->tn_left->tn_op == STRING) { 3907 } else if (tn->tn_left->tn_op == STRING) {
3908 /* 3908 /*
3909 * If this would be the front end of a compiler we 3909 * If this would be the front end of a compiler we
3910 * would return a label instead of 0. 3910 * would return a label instead of 0.
3911 */ 3911 */
3912 *offsp = 0; 3912 *offsp = 0;
3913 } 3913 }
3914 break; 3914 break;
3915 case CVT: 3915 case CVT:
3916 t = tn->tn_type->t_tspec; 3916 t = tn->tn_type->t_tspec;
3917 ot = tn->tn_left->tn_type->t_tspec; 3917 ot = tn->tn_left->tn_type->t_tspec;
3918 if ((!tspec_is_int(t) && t != PTR) || 3918 if ((!tspec_is_int(t) && t != PTR) ||
3919 (!tspec_is_int(ot) && ot != PTR)) { 3919 (!tspec_is_int(ot) && ot != PTR)) {
3920 return -1; 3920 return -1;
3921 } 3921 }
3922#ifdef notdef 3922#ifdef notdef
3923 /* 3923 /*
3924 * consider: 3924 * consider:
3925 * struct foo { 3925 * struct foo {
3926 * unsigned char a; 3926 * unsigned char a;
3927 * } f = { 3927 * } f = {
3928 * (u_char)(u_long)(&(((struct foo *)0)->a)) 3928 * (u_char)(u_long)(&(((struct foo *)0)->a))
3929 * }; 3929 * };
3930 * since psize(u_long) != psize(u_char) this fails. 3930 * since psize(u_long) != psize(u_char) this fails.
3931 */ 3931 */
3932 else if (psize(t) != psize(ot)) 3932 else if (psize(t) != psize(ot))
3933 return -1; 3933 return -1;
3934#endif 3934#endif
3935 if (conaddr(tn->tn_left, symp, offsp) == -1) 3935 if (conaddr(tn->tn_left, symp, offsp) == -1)
3936 return -1; 3936 return -1;
3937 break; 3937 break;
3938 default: 3938 default:
3939 return -1; 3939 return -1;
3940 } 3940 }
3941 return 0; 3941 return 0;
3942} 3942}
3943 3943
3944/* 3944/*
3945 * Concatenate two string constants. 3945 * Concatenate two string constants.
3946 */ 3946 */
3947strg_t * 3947strg_t *
3948cat_strings(strg_t *strg1, strg_t *strg2) 3948cat_strings(strg_t *strg1, strg_t *strg2)
3949{ 3949{
3950 size_t len1, len2, len; 3950 size_t len1, len2, len;
3951 3951
3952 if (strg1->st_tspec != strg2->st_tspec) { 3952 if (strg1->st_tspec != strg2->st_tspec) {
3953 /* cannot concatenate wide and regular string literals */ 3953 /* cannot concatenate wide and regular string literals */
3954 error(292); 3954 error(292);
3955 return strg1; 3955 return strg1;
3956 } 3956 }
3957 3957
3958 len1 = strg1->st_len; 3958 len1 = strg1->st_len;
3959 len2 = strg2->st_len + 1; /* + NUL */ 3959 len2 = strg2->st_len + 1; /* + NUL */
3960 len = len1 + len2; 3960 len = len1 + len2;
3961 3961
3962#define COPY(F) \ 3962#define COPY(F) \
3963 do { \ 3963 do { \
3964 strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \ 3964 strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \
3965 (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \ 3965 (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \
3966 free(strg2->F); \ 3966 free(strg2->F); \
3967 } while (/*CONSTCOND*/0) 3967 } while (/*CONSTCOND*/0)
3968 3968
3969 if (strg1->st_tspec == CHAR) 3969 if (strg1->st_tspec == CHAR)
3970 COPY(st_cp); 3970 COPY(st_cp);
3971 else 3971 else
3972 COPY(st_wcp); 3972 COPY(st_wcp);
3973 3973
3974 strg1->st_len = len - 1; /* - NUL */ 3974 strg1->st_len = len - 1; /* - NUL */
3975 free(strg2); 3975 free(strg2);
3976 3976
3977 return strg1; 3977 return strg1;
3978} 3978}
3979 3979
3980/* 3980/*
3981 * Print a warning if the given node has operands which should be 3981 * Print a warning if the given node has operands which should be
3982 * parenthesized. 3982 * parenthesized.
3983 * 3983 *
3984 * XXX Does not work if an operand is a constant expression. Constant 3984 * XXX Does not work if an operand is a constant expression. Constant
3985 * expressions are already folded. 3985 * expressions are already folded.
3986 */ 3986 */
3987static void 3987static void
3988check_precedence_confusion(tnode_t *tn) 3988check_precedence_confusion(tnode_t *tn)
3989{ 3989{
3990 tnode_t *ln, *rn; 3990 tnode_t *ln, *rn;
3991 op_t lop, rop = NOOP; 3991 op_t lop, rop = NOOP;
3992 int lparn, rparn = 0; 3992 int lparn, rparn = 0;
3993 mod_t *mp; 3993 mod_t *mp;
3994 int dowarn; 3994 int dowarn;
3995 3995
3996 if (!hflag) 3996 if (!hflag)
3997 return; 3997 return;
3998 3998
3999 mp = &modtab[tn->tn_op]; 3999 mp = &modtab[tn->tn_op];
4000 4000
4001 lparn = 0; 4001 lparn = 0;
4002 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) 4002 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
4003 lparn |= ln->tn_parenthesized; 4003 lparn |= ln->tn_parenthesized;
4004 lparn |= ln->tn_parenthesized; 4004 lparn |= ln->tn_parenthesized;
4005 lop = ln->tn_op; 4005 lop = ln->tn_op;
4006 4006
4007 dprint_node(tn); 4007 dprint_node(tn);
4008 4008
4009 if (mp->m_binary) { 4009 if (mp->m_binary) {
4010 rparn = 0; 4010 rparn = 0;
4011 /* 4011 /*
4012 * FIXME: There is a typo "tn->tn_op == CVT", which should 4012 * FIXME: There is a typo "tn->tn_op == CVT", which should
4013 * rather be "rn->tn_op". Since tn must be a binary operator, 4013 * rather be "rn->tn_op". Since tn must be a binary operator,
4014 * it can never be CVT. 4014 * it can never be CVT.
4015 * 4015 *
4016 * Before fixing this though, there should be a unit test 4016 * Before fixing this though, there should be a unit test
4017 * that demonstrates an actual change in behavior when this 4017 * that demonstrates an actual change in behavior when this
4018 * bug gets fixed. 4018 * bug gets fixed.
 4019 *
 4020 * Right now, the condition is always false. To make it true
 4021 * after fixing the typo, the right-hand operand must be an
 4022 * explicit cast or an implicit conversion that is
 4023 * parenthesized. For the right-hand operand itself, this
 4024 * would already be done using the line below the loop.
 4025 *
 4026 * To make a difference, the right-hand operand must not be
 4027 * parenthesized, but its indirect cast or conversion must be.
 4028 *
 4029 * An implicit conversion is never parenthesized. Therefore
 4030 * this must be a cast that is later converted, to build a
 4031 * chain.
4019 */ 4032 */
4020 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) 4033 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left)
4021 rparn |= rn->tn_parenthesized; 4034 rparn |= rn->tn_parenthesized;
4022 rparn |= rn->tn_parenthesized; 4035 rparn |= rn->tn_parenthesized;
4023 rop = rn->tn_op; 4036 rop = rn->tn_op;
4024 } 4037 }
4025 4038
4026 dowarn = 0; 4039 dowarn = 0;
4027 4040
4028 switch (tn->tn_op) { 4041 switch (tn->tn_op) {
4029 case SHL: 4042 case SHL:
4030 case SHR: 4043 case SHR:
4031 if (!lparn && (lop == PLUS || lop == MINUS)) { 4044 if (!lparn && (lop == PLUS || lop == MINUS)) {
4032 dowarn = 1; 4045 dowarn = 1;
4033 } else if (!rparn && (rop == PLUS || rop == MINUS)) { 4046 } else if (!rparn && (rop == PLUS || rop == MINUS)) {
4034 dowarn = 1; 4047 dowarn = 1;
4035 } 4048 }
4036 break; 4049 break;
4037 case LOGOR: 4050 case LOGOR:
4038 if (!lparn && lop == LOGAND) { 4051 if (!lparn && lop == LOGAND) {
4039 dowarn = 1; 4052 dowarn = 1;
4040 } else if (!rparn && rop == LOGAND) { 4053 } else if (!rparn && rop == LOGAND) {
4041 dowarn = 1; 4054 dowarn = 1;
4042 } 4055 }
4043 break; 4056 break;
4044 case AND: 4057 case AND:
4045 case XOR: 4058 case XOR:
4046 case OR: 4059 case OR:
4047 if (!lparn && lop != tn->tn_op) { 4060 if (!lparn && lop != tn->tn_op) {
4048 if (lop == PLUS || lop == MINUS) { 4061 if (lop == PLUS || lop == MINUS) {
4049 dowarn = 1; 4062 dowarn = 1;
4050 } else if (lop == AND || lop == XOR) { 4063 } else if (lop == AND || lop == XOR) {
4051 dowarn = 1; 4064 dowarn = 1;
4052 } 4065 }
4053 } 4066 }
4054 if (!dowarn && !rparn && rop != tn->tn_op) { 4067 if (!dowarn && !rparn && rop != tn->tn_op) {
4055 if (rop == PLUS || rop == MINUS) { 4068 if (rop == PLUS || rop == MINUS) {
4056 dowarn = 1; 4069 dowarn = 1;
4057 } else if (rop == AND || rop == XOR) { 4070 } else if (rop == AND || rop == XOR) {
4058 dowarn = 1; 4071 dowarn = 1;
4059 } 4072 }
4060 } 4073 }
4061 break; 4074 break;
4062 /* LINTED206: (enumeration values not handled in switch) */ 4075 /* LINTED206: (enumeration values not handled in switch) */
4063 case DECAFT: 4076 case DECAFT:
4064 case XORASS: 4077 case XORASS:
4065 case SHLASS: 4078 case SHLASS:
4066 case NOOP: 4079 case NOOP:
4067 case ARROW: 4080 case ARROW:
4068 case ORASS: 4081 case ORASS:
4069 case POINT: 4082 case POINT:
4070 case NAME: 4083 case NAME:
4071 case NOT: 4084 case NOT:
4072 case COMPL: 4085 case COMPL:
4073 case CON: 4086 case CON:
4074 case INC: 4087 case INC:
4075 case STRING: 4088 case STRING:
4076 case DEC: 4089 case DEC:
4077 case INCBEF: 4090 case INCBEF:
4078 case DECBEF: 4091 case DECBEF:
4079 case INCAFT: 4092 case INCAFT:
4080 case FSEL: 4093 case FSEL:
4081 case CALL: 4094 case CALL:
4082 case COMMA: 4095 case COMMA:
4083 case CVT: 4096 case CVT:
4084 case ICALL: 4097 case ICALL:
4085 case LOAD: 4098 case LOAD:
4086 case PUSH: 4099 case PUSH:
4087 case RETURN: 4100 case RETURN:
4088 case INIT: 4101 case INIT:
4089 case CASE: 4102 case CASE:
4090 case FARG: 4103 case FARG:
4091 case SUBASS: 4104 case SUBASS:
4092 case ADDASS: 4105 case ADDASS:
4093 case MODASS: 4106 case MODASS:
4094 case DIVASS: 4107 case DIVASS:
4095 case MULASS: 4108 case MULASS:
4096 case ASSIGN: 4109 case ASSIGN:
4097 case COLON: 4110 case COLON:
4098 case QUEST: 4111 case QUEST:
4099 case LOGAND: 4112 case LOGAND:
4100 case NE: 4113 case NE:
4101 case EQ: 4114 case EQ:
4102 case GE: 4115 case GE:
4103 case GT: 4116 case GT:
4104 case LE: 4117 case LE:
4105 case LT: 4118 case LT:
4106 case MINUS: 4119 case MINUS:
4107 case PLUS: 4120 case PLUS:
4108 case MOD: 4121 case MOD:
4109 case DIV: 4122 case DIV:
4110 case MULT: 4123 case MULT:
4111 case AMPER: 4124 case AMPER:
4112 case STAR: 4125 case STAR:
4113 case UMINUS: 4126 case UMINUS:
4114 case SHRASS: 4127 case SHRASS:
4115 case UPLUS: 4128 case UPLUS:
4116 case ANDASS: 4129 case ANDASS:
4117 case REAL: 4130 case REAL:
4118 case IMAG: 4131 case IMAG:
4119 break; 4132 break;
4120 } 4133 }
4121 4134
4122 if (dowarn) { 4135 if (dowarn) {
4123 /* precedence confusion possible: parenthesize! */ 4136 /* precedence confusion possible: parenthesize! */
4124 warning(169); 4137 warning(169);
4125 } 4138 }
4126 4139
4127} 4140}