add __extension__ and typeofdiff -r1.57 -r1.58 src/usr.bin/xlint/lint1/cgram.y
(christos)
--- src/usr.bin/xlint/lint1/cgram.y 2014/02/04 08:08:59 1.57
+++ src/usr.bin/xlint/lint1/cgram.y 2014/02/18 22:01:36 1.58
@@ -1,1964 +1,1972 @@ | @@ -1,1964 +1,1972 @@ | |||
1 | %{ | 1 | %{ | |
2 | /* $NetBSD: cgram.y,v 1.57 2014/02/04 08:08:59 njoly Exp $ */ | 2 | /* $NetBSD: cgram.y,v 1.58 2014/02/18 22:01:36 christos Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | 5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | |
6 | * Copyright (c) 1994, 1995 Jochen Pohl | 6 | * Copyright (c) 1994, 1995 Jochen Pohl | |
7 | * All Rights Reserved. | 7 | * All Rights Reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. | |
17 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software | |
18 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: | |
19 | * This product includes software developed by Jochen Pohl for | 19 | * This product includes software developed by Jochen Pohl for | |
20 | * The NetBSD Project. | 20 | * The NetBSD Project. | |
21 | * 4. The name of the author may not be used to endorse or promote products | 21 | * 4. The name of the author may not be used to endorse or promote products | |
22 | * derived from this software without specific prior written permission. | 22 | * derived from this software without specific prior written permission. | |
23 | * | 23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | #if defined(__RCSID) && !defined(lint) | 37 | #if defined(__RCSID) && !defined(lint) | |
38 | __RCSID("$NetBSD: cgram.y,v 1.57 2014/02/04 08:08:59 njoly Exp $"); | 38 | __RCSID("$NetBSD: cgram.y,v 1.58 2014/02/18 22:01:36 christos Exp $"); | |
39 | #endif | 39 | #endif | |
40 | 40 | |||
41 | #include <stdlib.h> | 41 | #include <stdlib.h> | |
42 | #include <string.h> | 42 | #include <string.h> | |
43 | #include <limits.h> | 43 | #include <limits.h> | |
44 | 44 | |||
45 | #include "lint1.h" | 45 | #include "lint1.h" | |
46 | 46 | |||
47 | extern char *yytext; | 47 | extern char *yytext; | |
48 | /* | 48 | /* | |
49 | * Contains the level of current declaration. 0 is extern. | 49 | * Contains the level of current declaration. 0 is extern. | |
50 | * Used for symbol table entries. | 50 | * Used for symbol table entries. | |
51 | */ | 51 | */ | |
52 | int blklev; | 52 | int blklev; | |
53 | 53 | |||
54 | /* | 54 | /* | |
55 | * level for memory allocation. Normaly the same as blklev. | 55 | * level for memory allocation. Normaly the same as blklev. | |
56 | * An exception is the declaration of arguments in prototypes. Memory | 56 | * An exception is the declaration of arguments in prototypes. Memory | |
57 | * for these can't be freed after the declaration, but symbols must | 57 | * for these can't be freed after the declaration, but symbols must | |
58 | * be removed from the symbol table after the declaration. | 58 | * be removed from the symbol table after the declaration. | |
59 | */ | 59 | */ | |
60 | int mblklev; | 60 | int mblklev; | |
61 | 61 | |||
62 | /* | 62 | /* | |
63 | * Save the no-warns state and restore it to avoid the problem where | 63 | * Save the no-warns state and restore it to avoid the problem where | |
64 | * if (expr) { stmt } / * NOLINT * / stmt; | 64 | * if (expr) { stmt } / * NOLINT * / stmt; | |
65 | */ | 65 | */ | |
66 | static int olwarn = LWARN_BAD; | 66 | static int olwarn = LWARN_BAD; | |
67 | 67 | |||
68 | static int toicon(tnode_t *, int); | 68 | static int toicon(tnode_t *, int); | |
69 | static void idecl(sym_t *, int, sbuf_t *); | 69 | static void idecl(sym_t *, int, sbuf_t *); | |
70 | static void ignuptorp(void); | 70 | static void ignuptorp(void); | |
71 | 71 | |||
72 | #ifdef DEBUG | 72 | #ifdef DEBUG | |
73 | static inline void CLRWFLGS(const char *file, size_t line); | 73 | static inline void CLRWFLGS(const char *file, size_t line); | |
74 | static inline void CLRWFLGS(const char *file, size_t line) | 74 | static inline void CLRWFLGS(const char *file, size_t line) | |
75 | { | 75 | { | |
76 | printf("%s, %d: clear flags %s %zu\n", curr_pos.p_file, | 76 | printf("%s, %d: clear flags %s %zu\n", curr_pos.p_file, | |
77 | curr_pos.p_line, file, line); | 77 | curr_pos.p_line, file, line); | |
78 | clrwflgs(); | 78 | clrwflgs(); | |
79 | olwarn = LWARN_BAD; | 79 | olwarn = LWARN_BAD; | |
80 | } | 80 | } | |
81 | 81 | |||
82 | static inline void SAVE(const char *file, size_t line); | 82 | static inline void SAVE(const char *file, size_t line); | |
83 | static inline void SAVE(const char *file, size_t line) | 83 | static inline void SAVE(const char *file, size_t line) | |
84 | { | 84 | { | |
85 | if (olwarn != LWARN_BAD) | 85 | if (olwarn != LWARN_BAD) | |
86 | abort(); | 86 | abort(); | |
87 | printf("%s, %d: save flags %s %zu = %d\n", curr_pos.p_file, | 87 | printf("%s, %d: save flags %s %zu = %d\n", curr_pos.p_file, | |
88 | curr_pos.p_line, file, line, lwarn); | 88 | curr_pos.p_line, file, line, lwarn); | |
89 | olwarn = lwarn; | 89 | olwarn = lwarn; | |
90 | } | 90 | } | |
91 | 91 | |||
92 | static inline void RESTORE(const char *file, size_t line); | 92 | static inline void RESTORE(const char *file, size_t line); | |
93 | static inline void RESTORE(const char *file, size_t line) | 93 | static inline void RESTORE(const char *file, size_t line) | |
94 | { | 94 | { | |
95 | if (olwarn != LWARN_BAD) { | 95 | if (olwarn != LWARN_BAD) { | |
96 | lwarn = olwarn; | 96 | lwarn = olwarn; | |
97 | printf("%s, %d: restore flags %s %zu = %d\n", curr_pos.p_file, | 97 | printf("%s, %d: restore flags %s %zu = %d\n", curr_pos.p_file, | |
98 | curr_pos.p_line, file, line, lwarn); | 98 | curr_pos.p_line, file, line, lwarn); | |
99 | olwarn = LWARN_BAD; | 99 | olwarn = LWARN_BAD; | |
100 | } else | 100 | } else | |
101 | CLRWFLGS(file, line); | 101 | CLRWFLGS(file, line); | |
102 | } | 102 | } | |
103 | #else | 103 | #else | |
104 | #define CLRWFLGS(f, l) clrwflgs(), olwarn = LWARN_BAD | 104 | #define CLRWFLGS(f, l) clrwflgs(), olwarn = LWARN_BAD | |
105 | #define SAVE(f, l) olwarn = lwarn | 105 | #define SAVE(f, l) olwarn = lwarn | |
106 | #define RESTORE(f, l) (void)(olwarn == LWARN_BAD ? (clrwflgs(), 0) : (lwarn = olwarn)) | 106 | #define RESTORE(f, l) (void)(olwarn == LWARN_BAD ? (clrwflgs(), 0) : (lwarn = olwarn)) | |
107 | #endif | 107 | #endif | |
108 | %} | 108 | %} | |
109 | 109 | |||
110 | %expect 5 | 110 | %expect 5 | |
111 | 111 | |||
112 | %union { | 112 | %union { | |
113 | int y_int; | 113 | int y_int; | |
114 | val_t *y_val; | 114 | val_t *y_val; | |
115 | sbuf_t *y_sb; | 115 | sbuf_t *y_sb; | |
116 | sym_t *y_sym; | 116 | sym_t *y_sym; | |
117 | op_t y_op; | 117 | op_t y_op; | |
118 | scl_t y_scl; | 118 | scl_t y_scl; | |
119 | tspec_t y_tspec; | 119 | tspec_t y_tspec; | |
120 | tqual_t y_tqual; | 120 | tqual_t y_tqual; | |
121 | type_t *y_type; | 121 | type_t *y_type; | |
122 | tnode_t *y_tnode; | 122 | tnode_t *y_tnode; | |
123 | range_t y_range; | 123 | range_t y_range; | |
124 | strg_t *y_strg; | 124 | strg_t *y_strg; | |
125 | pqinf_t *y_pqinf; | 125 | pqinf_t *y_pqinf; | |
126 | }; | 126 | }; | |
127 | 127 | |||
128 | %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN | 128 | %token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN | |
129 | %token <y_op> T_STROP | 129 | %token <y_op> T_STROP | |
130 | %token <y_op> T_UNOP | 130 | %token <y_op> T_UNOP | |
131 | %token <y_op> T_INCDEC | 131 | %token <y_op> T_INCDEC | |
132 | %token T_SIZEOF | 132 | %token T_SIZEOF | |
133 | %token T_TYPEOF | |||
134 | %token T_EXTENSION | |||
133 | %token T_ALIGNOF | 135 | %token T_ALIGNOF | |
134 | %token <y_op> T_MULT | 136 | %token <y_op> T_MULT | |
135 | %token <y_op> T_DIVOP | 137 | %token <y_op> T_DIVOP | |
136 | %token <y_op> T_ADDOP | 138 | %token <y_op> T_ADDOP | |
137 | %token <y_op> T_SHFTOP | 139 | %token <y_op> T_SHFTOP | |
138 | %token <y_op> T_RELOP | 140 | %token <y_op> T_RELOP | |
139 | %token <y_op> T_EQOP | 141 | %token <y_op> T_EQOP | |
140 | %token <y_op> T_AND | 142 | %token <y_op> T_AND | |
141 | %token <y_op> T_XOR | 143 | %token <y_op> T_XOR | |
142 | %token <y_op> T_OR | 144 | %token <y_op> T_OR | |
143 | %token <y_op> T_LOGAND | 145 | %token <y_op> T_LOGAND | |
144 | %token <y_op> T_LOGOR | 146 | %token <y_op> T_LOGOR | |
145 | %token T_QUEST | 147 | %token T_QUEST | |
146 | %token T_COLON | 148 | %token T_COLON | |
147 | %token <y_op> T_ASSIGN | 149 | %token <y_op> T_ASSIGN | |
148 | %token <y_op> T_OPASS | 150 | %token <y_op> T_OPASS | |
149 | %token T_COMMA | 151 | %token T_COMMA | |
150 | %token T_SEMI | 152 | %token T_SEMI | |
151 | %token T_ELLIPSE | 153 | %token T_ELLIPSE | |
152 | %token T_REAL | 154 | %token T_REAL | |
153 | %token T_IMAG | 155 | %token T_IMAG | |
154 | 156 | |||
155 | /* storage classes (extern, static, auto, register and typedef) */ | 157 | /* storage classes (extern, static, auto, register and typedef) */ | |
156 | %token <y_scl> T_SCLASS | 158 | %token <y_scl> T_SCLASS | |
157 | 159 | |||
158 | /* types (char, int, short, long, unsigned, signed, float, double, void) */ | 160 | /* types (char, int, short, long, unsigned, signed, float, double, void) */ | |
159 | %token <y_tspec> T_TYPE | 161 | %token <y_tspec> T_TYPE | |
160 | 162 | |||
161 | /* qualifiers (const, volatile) */ | 163 | /* qualifiers (const, volatile) */ | |
162 | %token <y_tqual> T_QUAL | 164 | %token <y_tqual> T_QUAL | |
163 | 165 | |||
164 | /* struct or union */ | 166 | /* struct or union */ | |
165 | %token <y_tspec> T_SOU | 167 | %token <y_tspec> T_SOU | |
166 | 168 | |||
167 | /* enum */ | 169 | /* enum */ | |
168 | %token T_ENUM | 170 | %token T_ENUM | |
169 | 171 | |||
170 | /* remaining keywords */ | 172 | /* remaining keywords */ | |
171 | %token T_CASE | 173 | %token T_CASE | |
172 | %token T_DEFAULT | 174 | %token T_DEFAULT | |
173 | %token T_IF | 175 | %token T_IF | |
174 | %token T_ELSE | 176 | %token T_ELSE | |
175 | %token T_SWITCH | 177 | %token T_SWITCH | |
176 | %token T_DO | 178 | %token T_DO | |
177 | %token T_WHILE | 179 | %token T_WHILE | |
178 | %token T_FOR | 180 | %token T_FOR | |
179 | %token T_GOTO | 181 | %token T_GOTO | |
180 | %token T_CONTINUE | 182 | %token T_CONTINUE | |
181 | %token T_BREAK | 183 | %token T_BREAK | |
182 | %token T_RETURN | 184 | %token T_RETURN | |
183 | %token T_ASM | 185 | %token T_ASM | |
184 | %token T_SYMBOLRENAME | 186 | %token T_SYMBOLRENAME | |
185 | %token T_PACKED | 187 | %token T_PACKED | |
186 | /* Type Attributes */ | 188 | /* Type Attributes */ | |
187 | %token <y_type> T_ATTRIBUTE | 189 | %token <y_type> T_ATTRIBUTE | |
188 | %token <y_type> T_AT_ALIGNED | 190 | %token <y_type> T_AT_ALIGNED | |
189 | %token <y_type> T_AT_DEPRECATED | 191 | %token <y_type> T_AT_DEPRECATED | |
190 | %token <y_type> T_AT_MAY_ALIAS | 192 | %token <y_type> T_AT_MAY_ALIAS | |
191 | %token <y_type> T_AT_PACKED | 193 | %token <y_type> T_AT_PACKED | |
192 | %token <y_type> T_AT_TUINION | 194 | %token <y_type> T_AT_TUINION | |
193 | %token <y_type> T_AT_TUNION | 195 | %token <y_type> T_AT_TUNION | |
194 | %token <y_type> T_AT_UNUSED | 196 | %token <y_type> T_AT_UNUSED | |
195 | 197 | |||
196 | 198 | |||
197 | 199 | |||
198 | %left T_COMMA | 200 | %left T_COMMA | |
199 | %right T_ASSIGN T_OPASS | 201 | %right T_ASSIGN T_OPASS | |
200 | %right T_QUEST T_COLON | 202 | %right T_QUEST T_COLON | |
201 | %left T_LOGOR | 203 | %left T_LOGOR | |
202 | %left T_LOGAND | 204 | %left T_LOGAND | |
203 | %left T_OR | 205 | %left T_OR | |
204 | %left T_XOR | 206 | %left T_XOR | |
205 | %left T_AND | 207 | %left T_AND | |
206 | %left T_EQOP | 208 | %left T_EQOP | |
207 | %left T_RELOP | 209 | %left T_RELOP | |
208 | %left T_SHFTOP | 210 | %left T_SHFTOP | |
209 | %left T_ADDOP | 211 | %left T_ADDOP | |
210 | %left T_MULT T_DIVOP | 212 | %left T_MULT T_DIVOP | |
211 | %right T_UNOP T_INCDEC T_SIZEOF T_ALIGNOF T_REAL T_IMAG | 213 | %right T_UNOP T_INCDEC T_SIZEOF T_ALIGNOF T_REAL T_IMAG | |
212 | %left T_LPARN T_LBRACK T_STROP | 214 | %left T_LPARN T_LBRACK T_STROP | |
213 | 215 | |||
214 | %token <y_sb> T_NAME | 216 | %token <y_sb> T_NAME | |
215 | %token <y_sb> T_TYPENAME | 217 | %token <y_sb> T_TYPENAME | |
216 | %token <y_val> T_CON | 218 | %token <y_val> T_CON | |
217 | %token <y_strg> T_STRING | 219 | %token <y_strg> T_STRING | |
218 | 220 | |||
219 | %type <y_sym> func_decl | 221 | %type <y_sym> func_decl | |
220 | %type <y_sym> notype_decl | 222 | %type <y_sym> notype_decl | |
221 | %type <y_sym> type_decl | 223 | %type <y_sym> type_decl | |
222 | %type <y_type> typespec | 224 | %type <y_type> typespec | |
223 | %type <y_type> clrtyp_typespec | 225 | %type <y_type> clrtyp_typespec | |
224 | %type <y_type> notype_typespec | 226 | %type <y_type> notype_typespec | |
225 | %type <y_type> struct_spec | 227 | %type <y_type> struct_spec | |
226 | %type <y_type> enum_spec | 228 | %type <y_type> enum_spec | |
227 | %type <y_type> type_attribute | 229 | %type <y_type> type_attribute | |
228 | %type <y_type> type_attribute_spec | 230 | %type <y_type> type_attribute_spec | |
229 | %type <y_sym> struct_tag | 231 | %type <y_sym> struct_tag | |
230 | %type <y_sym> enum_tag | 232 | %type <y_sym> enum_tag | |
231 | %type <y_tspec> struct | 233 | %type <y_tspec> struct | |
232 | %type <y_sym> struct_declaration | 234 | %type <y_sym> struct_declaration | |
233 | %type <y_sb> identifier | 235 | %type <y_sb> identifier | |
234 | %type <y_sym> member_declaration_list_with_rbrace | 236 | %type <y_sym> member_declaration_list_with_rbrace | |
235 | %type <y_sym> member_declaration_list | 237 | %type <y_sym> member_declaration_list | |
236 | %type <y_sym> member_declaration | 238 | %type <y_sym> member_declaration | |
237 | %type <y_sym> notype_member_decls | 239 | %type <y_sym> notype_member_decls | |
238 | %type <y_sym> type_member_decls | 240 | %type <y_sym> type_member_decls | |
239 | %type <y_sym> notype_member_decl | 241 | %type <y_sym> notype_member_decl | |
240 | %type <y_sym> type_member_decl | 242 | %type <y_sym> type_member_decl | |
241 | %type <y_tnode> constant | 243 | %type <y_tnode> constant | |
242 | %type <y_sym> enum_declaration | 244 | %type <y_sym> enum_declaration | |
243 | %type <y_sym> enums_with_opt_comma | 245 | %type <y_sym> enums_with_opt_comma | |
244 | %type <y_sym> enums | 246 | %type <y_sym> enums | |
245 | %type <y_sym> enumerator | 247 | %type <y_sym> enumerator | |
246 | %type <y_sym> ename | 248 | %type <y_sym> ename | |
247 | %type <y_sym> notype_direct_decl | 249 | %type <y_sym> notype_direct_decl | |
248 | %type <y_sym> type_direct_decl | 250 | %type <y_sym> type_direct_decl | |
249 | %type <y_pqinf> pointer | 251 | %type <y_pqinf> pointer | |
250 | %type <y_pqinf> asterisk | 252 | %type <y_pqinf> asterisk | |
251 | %type <y_sym> param_decl | 253 | %type <y_sym> param_decl | |
252 | %type <y_sym> param_list | 254 | %type <y_sym> param_list | |
253 | %type <y_sym> abs_decl_param_list | 255 | %type <y_sym> abs_decl_param_list | |
254 | %type <y_sym> direct_param_decl | 256 | %type <y_sym> direct_param_decl | |
255 | %type <y_sym> notype_param_decl | 257 | %type <y_sym> notype_param_decl | |
256 | %type <y_sym> direct_notype_param_decl | 258 | %type <y_sym> direct_notype_param_decl | |
257 | %type <y_pqinf> type_qualifier_list | 259 | %type <y_pqinf> type_qualifier_list | |
258 | %type <y_pqinf> type_qualifier | 260 | %type <y_pqinf> type_qualifier | |
259 | %type <y_sym> identifier_list | 261 | %type <y_sym> identifier_list | |
260 | %type <y_sym> abs_decl | 262 | %type <y_sym> abs_decl | |
261 | %type <y_sym> direct_abs_decl | 263 | %type <y_sym> direct_abs_decl | |
262 | %type <y_sym> vararg_parameter_type_list | 264 | %type <y_sym> vararg_parameter_type_list | |
263 | %type <y_sym> parameter_type_list | 265 | %type <y_sym> parameter_type_list | |
264 | %type <y_sym> parameter_declaration | 266 | %type <y_sym> parameter_declaration | |
265 | %type <y_tnode> expr | 267 | %type <y_tnode> expr | |
266 | %type <y_tnode> expr_stmnt_val | 268 | %type <y_tnode> expr_stmnt_val | |
267 | %type <y_tnode> expr_stmnt_list | 269 | %type <y_tnode> expr_stmnt_list | |
268 | %type <y_tnode> term | 270 | %type <y_tnode> term | |
269 | %type <y_tnode> func_arg_list | 271 | %type <y_tnode> func_arg_list | |
270 | %type <y_op> point_or_arrow | 272 | %type <y_op> point_or_arrow | |
271 | %type <y_type> type_name | 273 | %type <y_type> type_name | |
272 | %type <y_sym> abstract_declaration | 274 | %type <y_sym> abstract_declaration | |
273 | %type <y_tnode> do_while_expr | 275 | %type <y_tnode> do_while_expr | |
274 | %type <y_tnode> opt_expr | 276 | %type <y_tnode> opt_expr | |
275 | %type <y_strg> string | 277 | %type <y_strg> string | |
276 | %type <y_strg> string2 | 278 | %type <y_strg> string2 | |
277 | %type <y_sb> opt_asm_or_symbolrename | 279 | %type <y_sb> opt_asm_or_symbolrename | |
278 | %type <y_range> range | 280 | %type <y_range> range | |
279 | %type <y_range> lorange | 281 | %type <y_range> lorange | |
280 | 282 | |||
281 | 283 | |||
282 | %% | 284 | %% | |
283 | 285 | |||
284 | program: | 286 | program: | |
285 | /* empty */ { | 287 | /* empty */ { | |
286 | if (sflag) { | 288 | if (sflag) { | |
287 | /* empty translation unit */ | 289 | /* empty translation unit */ | |
288 | error(272); | 290 | error(272); | |
289 | } else if (!tflag) { | 291 | } else if (!tflag) { | |
290 | /* empty translation unit */ | 292 | /* empty translation unit */ | |
291 | warning(272); | 293 | warning(272); | |
292 | } | 294 | } | |
293 | } | 295 | } | |
294 | | translation_unit | 296 | | translation_unit | |
295 | ; | 297 | ; | |
296 | 298 | |||
297 | translation_unit: | 299 | translation_unit: | |
298 | ext_decl | 300 | ext_decl | |
299 | | translation_unit ext_decl | 301 | | translation_unit ext_decl | |
300 | ; | 302 | ; | |
301 | 303 | |||
302 | ext_decl: | 304 | ext_decl: | |
303 | asm_stmnt | 305 | asm_stmnt | |
304 | | func_def { | 306 | | func_def { | |
305 | glclup(0); | 307 | glclup(0); | |
306 | CLRWFLGS(__FILE__, __LINE__); | 308 | CLRWFLGS(__FILE__, __LINE__); | |
307 | } | 309 | } | |
308 | | data_def { | 310 | | data_def { | |
309 | glclup(0); | 311 | glclup(0); | |
310 | CLRWFLGS(__FILE__, __LINE__); | 312 | CLRWFLGS(__FILE__, __LINE__); | |
311 | } | 313 | } | |
312 | ; | 314 | ; | |
313 | 315 | |||
314 | data_def: | 316 | data_def: | |
315 | T_SEMI { | 317 | T_SEMI { | |
316 | if (sflag) { | 318 | if (sflag) { | |
317 | /* syntax error: empty declaration */ | 319 | /* syntax error: empty declaration */ | |
318 | error(0); | 320 | error(0); | |
319 | } else if (!tflag) { | 321 | } else if (!tflag) { | |
320 | /* syntax error: empty declaration */ | 322 | /* syntax error: empty declaration */ | |
321 | warning(0); | 323 | warning(0); | |
322 | } | 324 | } | |
323 | } | 325 | } | |
324 | | clrtyp deftyp notype_init_decls T_SEMI { | 326 | | clrtyp deftyp notype_init_decls T_SEMI { | |
325 | if (sflag) { | 327 | if (sflag) { | |
326 | /* old style declaration; add "int" */ | 328 | /* old style declaration; add "int" */ | |
327 | error(1); | 329 | error(1); | |
328 | } else if (!tflag) { | 330 | } else if (!tflag) { | |
329 | /* old style declaration; add "int" */ | 331 | /* old style declaration; add "int" */ | |
330 | warning(1); | 332 | warning(1); | |
331 | } | 333 | } | |
332 | } | 334 | } | |
333 | | declmods deftyp T_SEMI { | 335 | | declmods deftyp T_SEMI { | |
334 | if (dcs->d_scl == TYPEDEF) { | 336 | if (dcs->d_scl == TYPEDEF) { | |
335 | /* typedef declares no type name */ | 337 | /* typedef declares no type name */ | |
336 | warning(72); | 338 | warning(72); | |
337 | } else { | 339 | } else { | |
338 | /* empty declaration */ | 340 | /* empty declaration */ | |
339 | warning(2); | 341 | warning(2); | |
340 | } | 342 | } | |
341 | } | 343 | } | |
342 | | declmods deftyp notype_init_decls T_SEMI | 344 | | declmods deftyp notype_init_decls T_SEMI | |
343 | | declspecs deftyp T_SEMI { | 345 | | declspecs deftyp T_SEMI { | |
344 | if (dcs->d_scl == TYPEDEF) { | 346 | if (dcs->d_scl == TYPEDEF) { | |
345 | /* typedef declares no type name */ | 347 | /* typedef declares no type name */ | |
346 | warning(72); | 348 | warning(72); | |
347 | } else if (!dcs->d_nedecl) { | 349 | } else if (!dcs->d_nedecl) { | |
348 | /* empty declaration */ | 350 | /* empty declaration */ | |
349 | warning(2); | 351 | warning(2); | |
350 | } | 352 | } | |
351 | } | 353 | } | |
352 | | declspecs deftyp type_init_decls T_SEMI | 354 | | declspecs deftyp type_init_decls T_SEMI | |
353 | | error T_SEMI { | 355 | | error T_SEMI { | |
354 | globclup(); | 356 | globclup(); | |
355 | } | 357 | } | |
356 | | error T_RBRACE { | 358 | | error T_RBRACE { | |
357 | globclup(); | 359 | globclup(); | |
358 | } | 360 | } | |
359 | ; | 361 | ; | |
360 | 362 | |||
361 | func_def: | 363 | func_def: | |
362 | func_decl { | 364 | func_decl { | |
363 | if ($1->s_type->t_tspec != FUNC) { | 365 | if ($1->s_type->t_tspec != FUNC) { | |
364 | /* syntax error */ | 366 | /* syntax error */ | |
365 | error(249, yytext); | 367 | error(249, yytext); | |
366 | YYERROR; | 368 | YYERROR; | |
367 | } | 369 | } | |
368 | if ($1->s_type->t_typedef) { | 370 | if ($1->s_type->t_typedef) { | |
369 | /* ()-less function definition */ | 371 | /* ()-less function definition */ | |
370 | error(64); | 372 | error(64); | |
371 | YYERROR; | 373 | YYERROR; | |
372 | } | 374 | } | |
373 | funcdef($1); | 375 | funcdef($1); | |
374 | blklev++; | 376 | blklev++; | |
375 | pushdecl(ARG); | 377 | pushdecl(ARG); | |
376 | if (lwarn == LWARN_NONE) | 378 | if (lwarn == LWARN_NONE) | |
377 | $1->s_used = 1; | 379 | $1->s_used = 1; | |
378 | } opt_arg_declaration_list { | 380 | } opt_arg_declaration_list { | |
379 | popdecl(); | 381 | popdecl(); | |
380 | blklev--; | 382 | blklev--; | |
381 | cluparg(); | 383 | cluparg(); | |
382 | pushctrl(0); | 384 | pushctrl(0); | |
383 | } comp_stmnt { | 385 | } comp_stmnt { | |
384 | funcend(); | 386 | funcend(); | |
385 | popctrl(0); | 387 | popctrl(0); | |
386 | } | 388 | } | |
387 | ; | 389 | ; | |
388 | 390 | |||
389 | func_decl: | 391 | func_decl: | |
390 | clrtyp deftyp notype_decl { | 392 | clrtyp deftyp notype_decl { | |
391 | $$ = $3; | 393 | $$ = $3; | |
392 | } | 394 | } | |
393 | | declmods deftyp notype_decl { | 395 | | declmods deftyp notype_decl { | |
394 | $$ = $3; | 396 | $$ = $3; | |
395 | } | 397 | } | |
396 | | declspecs deftyp type_decl { | 398 | | declspecs deftyp type_decl { | |
397 | $$ = $3; | 399 | $$ = $3; | |
398 | } | 400 | } | |
399 | ; | 401 | ; | |
400 | 402 | |||
401 | opt_arg_declaration_list: | 403 | opt_arg_declaration_list: | |
402 | /* empty */ | 404 | /* empty */ | |
403 | | arg_declaration_list | 405 | | arg_declaration_list | |
404 | ; | 406 | ; | |
405 | 407 | |||
406 | arg_declaration_list: | 408 | arg_declaration_list: | |
407 | arg_declaration | 409 | arg_declaration | |
408 | | arg_declaration_list arg_declaration | 410 | | arg_declaration_list arg_declaration | |
409 | /* XXX or better "arg_declaration error" ? */ | 411 | /* XXX or better "arg_declaration error" ? */ | |
410 | | error | 412 | | error | |
411 | ; | 413 | ; | |
412 | 414 | |||
413 | /* | 415 | /* | |
414 | * "arg_declaration" is separated from "declaration" because it | 416 | * "arg_declaration" is separated from "declaration" because it | |
415 | * needs other error handling. | 417 | * needs other error handling. | |
416 | */ | 418 | */ | |
417 | 419 | |||
418 | arg_declaration: | 420 | arg_declaration: | |
419 | declmods deftyp T_SEMI { | 421 | declmods deftyp T_SEMI { | |
420 | /* empty declaration */ | 422 | /* empty declaration */ | |
421 | warning(2); | 423 | warning(2); | |
422 | } | 424 | } | |
423 | | declmods deftyp notype_init_decls T_SEMI | 425 | | declmods deftyp notype_init_decls T_SEMI | |
424 | | declspecs deftyp T_SEMI { | 426 | | declspecs deftyp T_SEMI { | |
425 | if (!dcs->d_nedecl) { | 427 | if (!dcs->d_nedecl) { | |
426 | /* empty declaration */ | 428 | /* empty declaration */ | |
427 | warning(2); | 429 | warning(2); | |
428 | } else { | 430 | } else { | |
429 | tspec_t ts = dcs->d_type->t_tspec; | 431 | tspec_t ts = dcs->d_type->t_tspec; | |
430 | /* %s declared in argument declaration list */ | 432 | /* %s declared in argument declaration list */ | |
431 | warning(3, ts == STRUCT ? "struct" : | 433 | warning(3, ts == STRUCT ? "struct" : | |
432 | (ts == UNION ? "union" : "enum")); | 434 | (ts == UNION ? "union" : "enum")); | |
433 | } | 435 | } | |
434 | } | 436 | } | |
435 | | declspecs deftyp type_init_decls T_SEMI { | 437 | | declspecs deftyp type_init_decls T_SEMI { | |
436 | if (dcs->d_nedecl) { | 438 | if (dcs->d_nedecl) { | |
437 | tspec_t ts = dcs->d_type->t_tspec; | 439 | tspec_t ts = dcs->d_type->t_tspec; | |
438 | /* %s declared in argument declaration list */ | 440 | /* %s declared in argument declaration list */ | |
439 | warning(3, ts == STRUCT ? "struct" : | 441 | warning(3, ts == STRUCT ? "struct" : | |
440 | (ts == UNION ? "union" : "enum")); | 442 | (ts == UNION ? "union" : "enum")); | |
441 | } | 443 | } | |
442 | } | 444 | } | |
443 | | declmods error | 445 | | declmods error | |
444 | | declspecs error | 446 | | declspecs error | |
445 | ; | 447 | ; | |
446 | 448 | |||
447 | declaration: | 449 | declaration: | |
448 | declmods deftyp T_SEMI { | 450 | declmods deftyp T_SEMI { | |
449 | if (dcs->d_scl == TYPEDEF) { | 451 | if (dcs->d_scl == TYPEDEF) { | |
450 | /* typedef declares no type name */ | 452 | /* typedef declares no type name */ | |
451 | warning(72); | 453 | warning(72); | |
452 | } else { | 454 | } else { | |
453 | /* empty declaration */ | 455 | /* empty declaration */ | |
454 | warning(2); | 456 | warning(2); | |
455 | } | 457 | } | |
456 | } | 458 | } | |
457 | | declmods deftyp notype_init_decls T_SEMI | 459 | | declmods deftyp notype_init_decls T_SEMI | |
458 | | declspecs deftyp T_SEMI { | 460 | | declspecs deftyp T_SEMI { | |
459 | if (dcs->d_scl == TYPEDEF) { | 461 | if (dcs->d_scl == TYPEDEF) { | |
460 | /* typedef declares no type name */ | 462 | /* typedef declares no type name */ | |
461 | warning(72); | 463 | warning(72); | |
462 | } else if (!dcs->d_nedecl) { | 464 | } else if (!dcs->d_nedecl) { | |
463 | /* empty declaration */ | 465 | /* empty declaration */ | |
464 | warning(2); | 466 | warning(2); | |
465 | } | 467 | } | |
466 | } | 468 | } | |
467 | | declspecs deftyp type_init_decls T_SEMI | 469 | | declspecs deftyp type_init_decls T_SEMI | |
468 | | error T_SEMI | 470 | | error T_SEMI | |
469 | ; | 471 | ; | |
470 | 472 | |||
471 | type_attribute_spec: | 473 | type_attribute_spec: | |
472 | T_AT_DEPRECATED | 474 | T_AT_DEPRECATED | |
473 | | T_AT_ALIGNED T_LPARN constant T_RPARN | 475 | | T_AT_ALIGNED T_LPARN constant T_RPARN | |
474 | | T_AT_MAY_ALIAS | 476 | | T_AT_MAY_ALIAS | |
475 | | T_AT_PACKED { | 477 | | T_AT_PACKED { | |
476 | addpacked(); | 478 | addpacked(); | |
477 | } | 479 | } | |
478 | | T_AT_TUNION | 480 | | T_AT_TUNION | |
479 | | T_AT_UNUSED | 481 | | T_AT_UNUSED | |
480 | ; | 482 | ; | |
481 | 483 | |||
482 | type_attribute: | 484 | type_attribute: | |
483 | T_ATTRIBUTE T_LPARN T_LPARN type_attribute_spec T_RPARN T_RPARN | 485 | T_ATTRIBUTE T_LPARN T_LPARN type_attribute_spec T_RPARN T_RPARN | |
484 | | T_PACKED { | 486 | | T_PACKED { | |
485 | addpacked(); | 487 | addpacked(); | |
486 | } | 488 | } | |
487 | ; | 489 | ; | |
488 | 490 | |||
489 | clrtyp: | 491 | clrtyp: | |
490 | { | 492 | { | |
491 | clrtyp(); | 493 | clrtyp(); | |
492 | } | 494 | } | |
493 | ; | 495 | ; | |
494 | 496 | |||
495 | deftyp: | 497 | deftyp: | |
496 | /* empty */ { | 498 | /* empty */ { | |
497 | deftyp(); | 499 | deftyp(); | |
498 | } | 500 | } | |
499 | ; | 501 | ; | |
500 | 502 | |||
501 | declspecs: | 503 | declspecs: | |
502 | clrtyp_typespec { | 504 | clrtyp_typespec { | |
503 | addtype($1); | 505 | addtype($1); | |
504 | } | 506 | } | |
505 | | declmods typespec { | 507 | | declmods typespec { | |
506 | addtype($2); | 508 | addtype($2); | |
507 | } | 509 | } | |
508 | | declspecs type_attribute | 510 | | declspecs type_attribute | |
509 | | declspecs declmod | 511 | | declspecs declmod | |
510 | | declspecs notype_typespec { | 512 | | declspecs notype_typespec { | |
511 | addtype($2); | 513 | addtype($2); | |
512 | } | 514 | } | |
513 | ; | 515 | ; | |
514 | 516 | |||
515 | declmods: | 517 | declmods: | |
516 | clrtyp T_QUAL { | 518 | clrtyp T_QUAL { | |
517 | addqual($2); | 519 | addqual($2); | |
518 | } | 520 | } | |
519 | | clrtyp T_SCLASS { | 521 | | clrtyp T_SCLASS { | |
520 | addscl($2); | 522 | addscl($2); | |
521 | } | 523 | } | |
522 | | declmods declmod | 524 | | declmods declmod | |
523 | ; | 525 | ; | |
524 | 526 | |||
525 | declmod: | 527 | declmod: | |
526 | T_QUAL { | 528 | T_QUAL { | |
527 | addqual($1); | 529 | addqual($1); | |
528 | } | 530 | } | |
529 | | T_SCLASS { | 531 | | T_SCLASS { | |
530 | addscl($1); | 532 | addscl($1); | |
531 | } | 533 | } | |
532 | ; | 534 | ; | |
533 | 535 | |||
534 | clrtyp_typespec: | 536 | clrtyp_typespec: | |
535 | clrtyp notype_typespec { | 537 | clrtyp notype_typespec { | |
536 | $$ = $2; | 538 | $$ = $2; | |
537 | } | 539 | } | |
538 | | T_TYPENAME clrtyp { | 540 | | T_TYPENAME clrtyp { | |
539 | $$ = getsym($1)->s_type; | 541 | $$ = getsym($1)->s_type; | |
540 | } | 542 | } | |
541 | ; | 543 | ; | |
542 | 544 | |||
543 | typespec: | 545 | typespec: | |
544 | notype_typespec { | 546 | notype_typespec { | |
545 | $$ = $1; | 547 | $$ = $1; | |
546 | } | 548 | } | |
547 | | T_TYPENAME { | 549 | | T_TYPENAME { | |
548 | $$ = getsym($1)->s_type; | 550 | $$ = getsym($1)->s_type; | |
549 | } | 551 | } | |
550 | ; | 552 | ; | |
551 | 553 | |||
552 | notype_typespec: | 554 | notype_typespec: | |
553 | T_TYPE { | 555 | T_TYPE { | |
554 | $$ = gettyp($1); | 556 | $$ = gettyp($1); | |
555 | } | 557 | } | |
558 | | T_TYPEOF T_LPARN term T_RPARN { | |||
559 | $$ = $3->tn_type; | |||
560 | } | |||
556 | | struct_spec { | 561 | | struct_spec { | |
557 | popdecl(); | 562 | popdecl(); | |
558 | $$ = $1; | 563 | $$ = $1; | |
559 | } | 564 | } | |
560 | | enum_spec { | 565 | | enum_spec { | |
561 | popdecl(); | 566 | popdecl(); | |
562 | $$ = $1; | 567 | $$ = $1; | |
563 | } | 568 | } | |
564 | ; | 569 | ; | |
565 | 570 | |||
566 | struct_spec: | 571 | struct_spec: | |
567 | struct struct_tag { | 572 | struct struct_tag { | |
568 | /* | 573 | /* | |
569 | * STDC requires that "struct a;" always introduces | 574 | * STDC requires that "struct a;" always introduces | |
570 | * a new tag if "a" is not declared at current level | 575 | * a new tag if "a" is not declared at current level | |
571 | * | 576 | * | |
572 | * yychar is valid because otherwise the parser would | 577 | * yychar is valid because otherwise the parser would | |
573 | * not been able to deceide if he must shift or reduce | 578 | * not been able to deceide if he must shift or reduce | |
574 | */ | 579 | */ | |
575 | $$ = mktag($2, $1, 0, yychar == T_SEMI); | 580 | $$ = mktag($2, $1, 0, yychar == T_SEMI); | |
576 | } | 581 | } | |
577 | | struct struct_tag { | 582 | | struct struct_tag { | |
578 | dcs->d_tagtyp = mktag($2, $1, 1, 0); | 583 | dcs->d_tagtyp = mktag($2, $1, 1, 0); | |
579 | } struct_declaration { | 584 | } struct_declaration { | |
580 | $$ = compltag(dcs->d_tagtyp, $4); | 585 | $$ = compltag(dcs->d_tagtyp, $4); | |
581 | } | 586 | } | |
582 | | struct { | 587 | | struct { | |
583 | dcs->d_tagtyp = mktag(NULL, $1, 1, 0); | 588 | dcs->d_tagtyp = mktag(NULL, $1, 1, 0); | |
584 | } struct_declaration { | 589 | } struct_declaration { | |
585 | $$ = compltag(dcs->d_tagtyp, $3); | 590 | $$ = compltag(dcs->d_tagtyp, $3); | |
586 | } | 591 | } | |
587 | | struct error { | 592 | | struct error { | |
588 | symtyp = FVFT; | 593 | symtyp = FVFT; | |
589 | $$ = gettyp(INT); | 594 | $$ = gettyp(INT); | |
590 | } | 595 | } | |
591 | ; | 596 | ; | |
592 | 597 | |||
593 | struct: | 598 | struct: | |
594 | struct type_attribute | 599 | struct type_attribute | |
595 | | T_SOU { | 600 | | T_SOU { | |
596 | symtyp = FTAG; | 601 | symtyp = FTAG; | |
597 | pushdecl($1 == STRUCT ? MOS : MOU); | 602 | pushdecl($1 == STRUCT ? MOS : MOU); | |
598 | dcs->d_offset = 0; | 603 | dcs->d_offset = 0; | |
599 | dcs->d_stralign = CHAR_BIT; | 604 | dcs->d_stralign = CHAR_BIT; | |
600 | $$ = $1; | 605 | $$ = $1; | |
601 | } | 606 | } | |
602 | ; | 607 | ; | |
603 | 608 | |||
604 | struct_tag: | 609 | struct_tag: | |
605 | identifier { | 610 | identifier { | |
606 | $$ = getsym($1); | 611 | $$ = getsym($1); | |
607 | } | 612 | } | |
608 | ; | 613 | ; | |
609 | 614 | |||
610 | struct_declaration: | 615 | struct_declaration: | |
611 | struct_decl_lbrace member_declaration_list_with_rbrace { | 616 | struct_decl_lbrace member_declaration_list_with_rbrace { | |
612 | $$ = $2; | 617 | $$ = $2; | |
613 | } | 618 | } | |
614 | ; | 619 | ; | |
615 | 620 | |||
616 | struct_decl_lbrace: | 621 | struct_decl_lbrace: | |
617 | T_LBRACE { | 622 | T_LBRACE { | |
618 | symtyp = FVFT; | 623 | symtyp = FVFT; | |
619 | } | 624 | } | |
620 | ; | 625 | ; | |
621 | 626 | |||
622 | member_declaration_list_with_rbrace: | 627 | member_declaration_list_with_rbrace: | |
623 | member_declaration_list T_SEMI T_RBRACE { | 628 | member_declaration_list T_SEMI T_RBRACE { | |
624 | $$ = $1; | 629 | $$ = $1; | |
625 | } | 630 | } | |
626 | | member_declaration_list T_RBRACE { | 631 | | member_declaration_list T_RBRACE { | |
627 | if (sflag) { | 632 | if (sflag) { | |
628 | /* syntax req. ";" after last struct/union member */ | 633 | /* syntax req. ";" after last struct/union member */ | |
629 | error(66); | 634 | error(66); | |
630 | } else { | 635 | } else { | |
631 | /* syntax req. ";" after last struct/union member */ | 636 | /* syntax req. ";" after last struct/union member */ | |
632 | warning(66); | 637 | warning(66); | |
633 | } | 638 | } | |
634 | $$ = $1; | 639 | $$ = $1; | |
635 | } | 640 | } | |
636 | | T_RBRACE { | 641 | | T_RBRACE { | |
637 | $$ = NULL; | 642 | $$ = NULL; | |
638 | } | 643 | } | |
639 | ; | 644 | ; | |
640 | 645 | |||
641 | member_declaration_list: | 646 | member_declaration_list: | |
642 | member_declaration { | 647 | member_declaration { | |
643 | $$ = $1; | 648 | $$ = $1; | |
644 | } | 649 | } | |
645 | | member_declaration_list T_SEMI member_declaration { | 650 | | member_declaration_list T_SEMI member_declaration { | |
646 | $$ = lnklst($1, $3); | 651 | $$ = lnklst($1, $3); | |
647 | } | 652 | } | |
648 | ; | 653 | ; | |
649 | 654 | |||
650 | member_declaration: | 655 | member_declaration: | |
651 | noclass_declmods deftyp { | 656 | noclass_declmods deftyp { | |
652 | /* too late, i know, but getsym() compensates it */ | 657 | /* too late, i know, but getsym() compensates it */ | |
653 | symtyp = FMOS; | 658 | symtyp = FMOS; | |
654 | } notype_member_decls { | 659 | } notype_member_decls { | |
655 | symtyp = FVFT; | 660 | symtyp = FVFT; | |
656 | $$ = $4; | 661 | $$ = $4; | |
657 | } | 662 | } | |
658 | | noclass_declspecs deftyp { | 663 | | noclass_declspecs deftyp { | |
659 | symtyp = FMOS; | 664 | symtyp = FMOS; | |
660 | } type_member_decls { | 665 | } type_member_decls { | |
661 | symtyp = FVFT; | 666 | symtyp = FVFT; | |
662 | $$ = $4; | 667 | $$ = $4; | |
663 | } | 668 | } | |
664 | | noclass_declmods deftyp { | 669 | | noclass_declmods deftyp { | |
665 | /* struct or union member must be named */ | 670 | /* struct or union member must be named */ | |
666 | warning(49); | 671 | warning(49); | |
667 | $$ = NULL; | 672 | $$ = NULL; | |
668 | } | 673 | } | |
669 | | noclass_declspecs deftyp { | 674 | | noclass_declspecs deftyp { | |
670 | /* struct or union member must be named */ | 675 | /* struct or union member must be named */ | |
671 | warning(49); | 676 | warning(49); | |
672 | $$ = NULL; | 677 | $$ = NULL; | |
673 | } | 678 | } | |
674 | | error { | 679 | | error { | |
675 | symtyp = FVFT; | 680 | symtyp = FVFT; | |
676 | $$ = NULL; | 681 | $$ = NULL; | |
677 | } | 682 | } | |
678 | ; | 683 | ; | |
679 | 684 | |||
680 | noclass_declspecs: | 685 | noclass_declspecs: | |
681 | clrtyp_typespec { | 686 | clrtyp_typespec { | |
682 | addtype($1); | 687 | addtype($1); | |
683 | } | 688 | } | |
684 | | noclass_declmods typespec { | 689 | | noclass_declmods typespec { | |
685 | addtype($2); | 690 | addtype($2); | |
686 | } | 691 | } | |
687 | | noclass_declspecs T_QUAL { | 692 | | noclass_declspecs T_QUAL { | |
688 | addqual($2); | 693 | addqual($2); | |
689 | } | 694 | } | |
690 | | noclass_declspecs notype_typespec { | 695 | | noclass_declspecs notype_typespec { | |
691 | addtype($2); | 696 | addtype($2); | |
692 | } | 697 | } | |
693 | | noclass_declspecs type_attribute | 698 | | noclass_declspecs type_attribute | |
694 | ; | 699 | ; | |
695 | 700 | |||
696 | noclass_declmods: | 701 | noclass_declmods: | |
697 | clrtyp T_QUAL { | 702 | clrtyp T_QUAL { | |
698 | addqual($2); | 703 | addqual($2); | |
699 | } | 704 | } | |
700 | | noclass_declmods T_QUAL { | 705 | | noclass_declmods T_QUAL { | |
701 | addqual($2); | 706 | addqual($2); | |
702 | } | 707 | } | |
703 | ; | 708 | ; | |
704 | 709 | |||
705 | notype_member_decls: | 710 | notype_member_decls: | |
706 | notype_member_decl { | 711 | notype_member_decl { | |
707 | $$ = decl1str($1); | 712 | $$ = decl1str($1); | |
708 | } | 713 | } | |
709 | | notype_member_decls { | 714 | | notype_member_decls { | |
710 | symtyp = FMOS; | 715 | symtyp = FMOS; | |
711 | } T_COMMA type_member_decl { | 716 | } T_COMMA type_member_decl { | |
712 | $$ = lnklst($1, decl1str($4)); | 717 | $$ = lnklst($1, decl1str($4)); | |
713 | } | 718 | } | |
714 | ; | 719 | ; | |
715 | 720 | |||
716 | type_member_decls: | 721 | type_member_decls: | |
717 | type_member_decl { | 722 | type_member_decl { | |
718 | $$ = decl1str($1); | 723 | $$ = decl1str($1); | |
719 | } | 724 | } | |
720 | | type_member_decls { | 725 | | type_member_decls { | |
721 | symtyp = FMOS; | 726 | symtyp = FMOS; | |
722 | } T_COMMA type_member_decl { | 727 | } T_COMMA type_member_decl { | |
723 | $$ = lnklst($1, decl1str($4)); | 728 | $$ = lnklst($1, decl1str($4)); | |
724 | } | 729 | } | |
725 | ; | 730 | ; | |
726 | 731 | |||
727 | notype_member_decl: | 732 | notype_member_decl: | |
728 | notype_decl { | 733 | notype_decl { | |
729 | $$ = $1; | 734 | $$ = $1; | |
730 | } | 735 | } | |
731 | | notype_decl T_COLON constant { | 736 | | notype_decl T_COLON constant { | |
732 | $$ = bitfield($1, toicon($3, 1)); | 737 | $$ = bitfield($1, toicon($3, 1)); | |
733 | } | 738 | } | |
734 | | { | 739 | | { | |
735 | symtyp = FVFT; | 740 | symtyp = FVFT; | |
736 | } T_COLON constant { | 741 | } T_COLON constant { | |
737 | $$ = bitfield(NULL, toicon($3, 1)); | 742 | $$ = bitfield(NULL, toicon($3, 1)); | |
738 | } | 743 | } | |
739 | ; | 744 | ; | |
740 | 745 | |||
741 | type_member_decl: | 746 | type_member_decl: | |
742 | type_decl { | 747 | type_decl { | |
743 | $$ = $1; | 748 | $$ = $1; | |
744 | } | 749 | } | |
745 | | type_decl T_COLON constant { | 750 | | type_decl T_COLON constant { | |
746 | $$ = bitfield($1, toicon($3, 1)); | 751 | $$ = bitfield($1, toicon($3, 1)); | |
747 | } | 752 | } | |
748 | | { | 753 | | { | |
749 | symtyp = FVFT; | 754 | symtyp = FVFT; | |
750 | } T_COLON constant { | 755 | } T_COLON constant { | |
751 | $$ = bitfield(NULL, toicon($3, 1)); | 756 | $$ = bitfield(NULL, toicon($3, 1)); | |
752 | } | 757 | } | |
753 | ; | 758 | ; | |
754 | 759 | |||
755 | enum_spec: | 760 | enum_spec: | |
756 | enum enum_tag { | 761 | enum enum_tag { | |
757 | $$ = mktag($2, ENUM, 0, 0); | 762 | $$ = mktag($2, ENUM, 0, 0); | |
758 | } | 763 | } | |
759 | | enum enum_tag { | 764 | | enum enum_tag { | |
760 | dcs->d_tagtyp = mktag($2, ENUM, 1, 0); | 765 | dcs->d_tagtyp = mktag($2, ENUM, 1, 0); | |
761 | } enum_declaration { | 766 | } enum_declaration { | |
762 | $$ = compltag(dcs->d_tagtyp, $4); | 767 | $$ = compltag(dcs->d_tagtyp, $4); | |
763 | } | 768 | } | |
764 | | enum { | 769 | | enum { | |
765 | dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0); | 770 | dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0); | |
766 | } enum_declaration { | 771 | } enum_declaration { | |
767 | $$ = compltag(dcs->d_tagtyp, $3); | 772 | $$ = compltag(dcs->d_tagtyp, $3); | |
768 | } | 773 | } | |
769 | | enum error { | 774 | | enum error { | |
770 | symtyp = FVFT; | 775 | symtyp = FVFT; | |
771 | $$ = gettyp(INT); | 776 | $$ = gettyp(INT); | |
772 | } | 777 | } | |
773 | ; | 778 | ; | |
774 | 779 | |||
775 | enum: | 780 | enum: | |
776 | T_ENUM { | 781 | T_ENUM { | |
777 | symtyp = FTAG; | 782 | symtyp = FTAG; | |
778 | pushdecl(ENUMCON); | 783 | pushdecl(ENUMCON); | |
779 | } | 784 | } | |
780 | ; | 785 | ; | |
781 | 786 | |||
782 | enum_tag: | 787 | enum_tag: | |
783 | identifier { | 788 | identifier { | |
784 | $$ = getsym($1); | 789 | $$ = getsym($1); | |
785 | } | 790 | } | |
786 | ; | 791 | ; | |
787 | 792 | |||
788 | enum_declaration: | 793 | enum_declaration: | |
789 | enum_decl_lbrace enums_with_opt_comma T_RBRACE { | 794 | enum_decl_lbrace enums_with_opt_comma T_RBRACE { | |
790 | $$ = $2; | 795 | $$ = $2; | |
791 | } | 796 | } | |
792 | ; | 797 | ; | |
793 | 798 | |||
794 | enum_decl_lbrace: | 799 | enum_decl_lbrace: | |
795 | T_LBRACE { | 800 | T_LBRACE { | |
796 | symtyp = FVFT; | 801 | symtyp = FVFT; | |
797 | enumval = 0; | 802 | enumval = 0; | |
798 | } | 803 | } | |
799 | ; | 804 | ; | |
800 | 805 | |||
801 | enums_with_opt_comma: | 806 | enums_with_opt_comma: | |
802 | enums { | 807 | enums { | |
803 | $$ = $1; | 808 | $$ = $1; | |
804 | } | 809 | } | |
805 | | enums T_COMMA { | 810 | | enums T_COMMA { | |
806 | if (sflag) { | 811 | if (sflag) { | |
807 | /* trailing "," prohibited in enum declaration */ | 812 | /* trailing "," prohibited in enum declaration */ | |
808 | error(54); | 813 | error(54); | |
809 | } else { | 814 | } else { | |
810 | /* trailing "," prohibited in enum declaration */ | 815 | /* trailing "," prohibited in enum declaration */ | |
811 | c99ism(54); | 816 | c99ism(54); | |
812 | } | 817 | } | |
813 | $$ = $1; | 818 | $$ = $1; | |
814 | } | 819 | } | |
815 | ; | 820 | ; | |
816 | 821 | |||
817 | enums: | 822 | enums: | |
818 | enumerator { | 823 | enumerator { | |
819 | $$ = $1; | 824 | $$ = $1; | |
820 | } | 825 | } | |
821 | | enums T_COMMA enumerator { | 826 | | enums T_COMMA enumerator { | |
822 | $$ = lnklst($1, $3); | 827 | $$ = lnklst($1, $3); | |
823 | } | 828 | } | |
824 | | error { | 829 | | error { | |
825 | $$ = NULL; | 830 | $$ = NULL; | |
826 | } | 831 | } | |
827 | ; | 832 | ; | |
828 | 833 | |||
829 | enumerator: | 834 | enumerator: | |
830 | ename { | 835 | ename { | |
831 | $$ = ename($1, enumval, 1); | 836 | $$ = ename($1, enumval, 1); | |
832 | } | 837 | } | |
833 | | ename T_ASSIGN constant { | 838 | | ename T_ASSIGN constant { | |
834 | $$ = ename($1, toicon($3, 1), 0); | 839 | $$ = ename($1, toicon($3, 1), 0); | |
835 | } | 840 | } | |
836 | ; | 841 | ; | |
837 | 842 | |||
838 | ename: | 843 | ename: | |
839 | identifier { | 844 | identifier { | |
840 | $$ = getsym($1); | 845 | $$ = getsym($1); | |
841 | } | 846 | } | |
842 | ; | 847 | ; | |
843 | 848 | |||
844 | 849 | |||
845 | notype_init_decls: | 850 | notype_init_decls: | |
846 | notype_init_decl | 851 | notype_init_decl | |
847 | | notype_init_decls T_COMMA type_init_decl | 852 | | notype_init_decls T_COMMA type_init_decl | |
848 | ; | 853 | ; | |
849 | 854 | |||
850 | type_init_decls: | 855 | type_init_decls: | |
851 | type_init_decl | 856 | type_init_decl | |
852 | | type_init_decls T_COMMA type_init_decl | 857 | | type_init_decls T_COMMA type_init_decl | |
853 | ; | 858 | ; | |
854 | 859 | |||
855 | notype_init_decl: | 860 | notype_init_decl: | |
856 | notype_decl opt_asm_or_symbolrename { | 861 | notype_decl opt_asm_or_symbolrename { | |
857 | idecl($1, 0, $2); | 862 | idecl($1, 0, $2); | |
858 | chksz($1); | 863 | chksz($1); | |
859 | } | 864 | } | |
860 | | notype_decl opt_asm_or_symbolrename { | 865 | | notype_decl opt_asm_or_symbolrename { | |
861 | idecl($1, 1, $2); | 866 | idecl($1, 1, $2); | |
862 | } T_ASSIGN initializer { | 867 | } T_ASSIGN initializer { | |
863 | chksz($1); | 868 | chksz($1); | |
864 | } | 869 | } | |
865 | ; | 870 | ; | |
866 | 871 | |||
867 | type_init_decl: | 872 | type_init_decl: | |
868 | type_decl opt_asm_or_symbolrename { | 873 | type_decl opt_asm_or_symbolrename { | |
869 | idecl($1, 0, $2); | 874 | idecl($1, 0, $2); | |
870 | chksz($1); | 875 | chksz($1); | |
871 | } | 876 | } | |
872 | | type_decl opt_asm_or_symbolrename { | 877 | | type_decl opt_asm_or_symbolrename { | |
873 | idecl($1, 1, $2); | 878 | idecl($1, 1, $2); | |
874 | } T_ASSIGN initializer { | 879 | } T_ASSIGN initializer { | |
875 | chksz($1); | 880 | chksz($1); | |
876 | } | 881 | } | |
877 | ; | 882 | ; | |
878 | 883 | |||
879 | notype_decl: | 884 | notype_decl: | |
880 | notype_direct_decl { | 885 | notype_direct_decl { | |
881 | $$ = $1; | 886 | $$ = $1; | |
882 | } | 887 | } | |
883 | | pointer notype_direct_decl { | 888 | | pointer notype_direct_decl { | |
884 | $$ = addptr($2, $1); | 889 | $$ = addptr($2, $1); | |
885 | } | 890 | } | |
886 | ; | 891 | ; | |
887 | 892 | |||
888 | notype_direct_decl: | 893 | notype_direct_decl: | |
889 | T_NAME { | 894 | T_NAME { | |
890 | $$ = dname(getsym($1)); | 895 | $$ = dname(getsym($1)); | |
891 | } | 896 | } | |
892 | | T_LPARN type_decl T_RPARN { | 897 | | T_LPARN type_decl T_RPARN { | |
893 | $$ = $2; | 898 | $$ = $2; | |
894 | } | 899 | } | |
895 | | notype_direct_decl T_LBRACK T_RBRACK { | 900 | | notype_direct_decl T_LBRACK T_RBRACK { | |
896 | $$ = addarray($1, 0, 0); | 901 | $$ = addarray($1, 0, 0); | |
897 | } | 902 | } | |
898 | | notype_direct_decl T_LBRACK constant T_RBRACK { | 903 | | notype_direct_decl T_LBRACK constant T_RBRACK { | |
899 | $$ = addarray($1, 1, toicon($3, 0)); | 904 | $$ = addarray($1, 1, toicon($3, 0)); | |
900 | } | 905 | } | |
901 | | notype_direct_decl param_list { | 906 | | notype_direct_decl param_list { | |
902 | $$ = addfunc($1, $2); | 907 | $$ = addfunc($1, $2); | |
903 | popdecl(); | 908 | popdecl(); | |
904 | blklev--; | 909 | blklev--; | |
905 | } | 910 | } | |
906 | | notype_direct_decl type_attribute | 911 | | notype_direct_decl type_attribute | |
907 | ; | 912 | ; | |
908 | 913 | |||
909 | type_decl: | 914 | type_decl: | |
910 | type_direct_decl { | 915 | type_direct_decl { | |
911 | $$ = $1; | 916 | $$ = $1; | |
912 | } | 917 | } | |
913 | | pointer type_direct_decl { | 918 | | pointer type_direct_decl { | |
914 | $$ = addptr($2, $1); | 919 | $$ = addptr($2, $1); | |
915 | } | 920 | } | |
916 | ; | 921 | ; | |
917 | 922 | |||
918 | type_direct_decl: | 923 | type_direct_decl: | |
919 | identifier { | 924 | identifier { | |
920 | $$ = dname(getsym($1)); | 925 | $$ = dname(getsym($1)); | |
921 | } | 926 | } | |
922 | | T_LPARN type_decl T_RPARN { | 927 | | T_LPARN type_decl T_RPARN { | |
923 | $$ = $2; | 928 | $$ = $2; | |
924 | } | 929 | } | |
925 | | type_direct_decl T_LBRACK T_RBRACK { | 930 | | type_direct_decl T_LBRACK T_RBRACK { | |
926 | $$ = addarray($1, 0, 0); | 931 | $$ = addarray($1, 0, 0); | |
927 | } | 932 | } | |
928 | | type_direct_decl T_LBRACK constant T_RBRACK { | 933 | | type_direct_decl T_LBRACK constant T_RBRACK { | |
929 | $$ = addarray($1, 1, toicon($3, 0)); | 934 | $$ = addarray($1, 1, toicon($3, 0)); | |
930 | } | 935 | } | |
931 | | type_direct_decl param_list { | 936 | | type_direct_decl param_list { | |
932 | $$ = addfunc($1, $2); | 937 | $$ = addfunc($1, $2); | |
933 | popdecl(); | 938 | popdecl(); | |
934 | blklev--; | 939 | blklev--; | |
935 | } | 940 | } | |
936 | | type_direct_decl type_attribute | 941 | | type_direct_decl type_attribute | |
937 | ; | 942 | ; | |
938 | 943 | |||
939 | /* | 944 | /* | |
940 | * param_decl and notype_param_decl exist to avoid a conflict in | 945 | * param_decl and notype_param_decl exist to avoid a conflict in | |
941 | * argument lists. A typename enclosed in parens should always be | 946 | * argument lists. A typename enclosed in parens should always be | |
942 | * treated as a typename, not an argument. | 947 | * treated as a typename, not an argument. | |
943 | * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));" | 948 | * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));" | |
944 | * not "typedef int a; f(int a);" | 949 | * not "typedef int a; f(int a);" | |
945 | */ | 950 | */ | |
946 | param_decl: | 951 | param_decl: | |
947 | direct_param_decl { | 952 | direct_param_decl { | |
948 | $$ = $1; | 953 | $$ = $1; | |
949 | } | 954 | } | |
950 | | pointer direct_param_decl { | 955 | | pointer direct_param_decl { | |
951 | $$ = addptr($2, $1); | 956 | $$ = addptr($2, $1); | |
952 | } | 957 | } | |
953 | ; | 958 | ; | |
954 | 959 | |||
955 | direct_param_decl: | 960 | direct_param_decl: | |
956 | identifier { | 961 | identifier { | |
957 | $$ = dname(getsym($1)); | 962 | $$ = dname(getsym($1)); | |
958 | } | 963 | } | |
959 | | T_LPARN notype_param_decl T_RPARN { | 964 | | T_LPARN notype_param_decl T_RPARN { | |
960 | $$ = $2; | 965 | $$ = $2; | |
961 | } | 966 | } | |
962 | | direct_param_decl T_LBRACK T_RBRACK { | 967 | | direct_param_decl T_LBRACK T_RBRACK { | |
963 | $$ = addarray($1, 0, 0); | 968 | $$ = addarray($1, 0, 0); | |
964 | } | 969 | } | |
965 | | direct_param_decl T_LBRACK constant T_RBRACK { | 970 | | direct_param_decl T_LBRACK constant T_RBRACK { | |
966 | $$ = addarray($1, 1, toicon($3, 0)); | 971 | $$ = addarray($1, 1, toicon($3, 0)); | |
967 | } | 972 | } | |
968 | | direct_param_decl param_list { | 973 | | direct_param_decl param_list { | |
969 | $$ = addfunc($1, $2); | 974 | $$ = addfunc($1, $2); | |
970 | popdecl(); | 975 | popdecl(); | |
971 | blklev--; | 976 | blklev--; | |
972 | } | 977 | } | |
973 | ; | 978 | ; | |
974 | 979 | |||
975 | notype_param_decl: | 980 | notype_param_decl: | |
976 | direct_notype_param_decl { | 981 | direct_notype_param_decl { | |
977 | $$ = $1; | 982 | $$ = $1; | |
978 | } | 983 | } | |
979 | | pointer direct_notype_param_decl { | 984 | | pointer direct_notype_param_decl { | |
980 | $$ = addptr($2, $1); | 985 | $$ = addptr($2, $1); | |
981 | } | 986 | } | |
982 | ; | 987 | ; | |
983 | 988 | |||
984 | direct_notype_param_decl: | 989 | direct_notype_param_decl: | |
985 | T_NAME { | 990 | T_NAME { | |
986 | $$ = dname(getsym($1)); | 991 | $$ = dname(getsym($1)); | |
987 | } | 992 | } | |
988 | | T_LPARN notype_param_decl T_RPARN { | 993 | | T_LPARN notype_param_decl T_RPARN { | |
989 | $$ = $2; | 994 | $$ = $2; | |
990 | } | 995 | } | |
991 | | direct_notype_param_decl T_LBRACK T_RBRACK { | 996 | | direct_notype_param_decl T_LBRACK T_RBRACK { | |
992 | $$ = addarray($1, 0, 0); | 997 | $$ = addarray($1, 0, 0); | |
993 | } | 998 | } | |
994 | | direct_notype_param_decl T_LBRACK constant T_RBRACK { | 999 | | direct_notype_param_decl T_LBRACK constant T_RBRACK { | |
995 | $$ = addarray($1, 1, toicon($3, 0)); | 1000 | $$ = addarray($1, 1, toicon($3, 0)); | |
996 | } | 1001 | } | |
997 | | direct_notype_param_decl param_list { | 1002 | | direct_notype_param_decl param_list { | |
998 | $$ = addfunc($1, $2); | 1003 | $$ = addfunc($1, $2); | |
999 | popdecl(); | 1004 | popdecl(); | |
1000 | blklev--; | 1005 | blklev--; | |
1001 | } | 1006 | } | |
1002 | ; | 1007 | ; | |
1003 | 1008 | |||
1004 | pointer: | 1009 | pointer: | |
1005 | asterisk { | 1010 | asterisk { | |
1006 | $$ = $1; | 1011 | $$ = $1; | |
1007 | } | 1012 | } | |
1008 | | asterisk type_qualifier_list { | 1013 | | asterisk type_qualifier_list { | |
1009 | $$ = mergepq($1, $2); | 1014 | $$ = mergepq($1, $2); | |
1010 | } | 1015 | } | |
1011 | | asterisk pointer { | 1016 | | asterisk pointer { | |
1012 | $$ = mergepq($1, $2); | 1017 | $$ = mergepq($1, $2); | |
1013 | } | 1018 | } | |
1014 | | asterisk type_qualifier_list pointer { | 1019 | | asterisk type_qualifier_list pointer { | |
1015 | $$ = mergepq(mergepq($1, $2), $3); | 1020 | $$ = mergepq(mergepq($1, $2), $3); | |
1016 | } | 1021 | } | |
1017 | ; | 1022 | ; | |
1018 | 1023 | |||
1019 | asterisk: | 1024 | asterisk: | |
1020 | T_MULT { | 1025 | T_MULT { | |
1021 | $$ = xcalloc(1, sizeof (pqinf_t)); | 1026 | $$ = xcalloc(1, sizeof (pqinf_t)); | |
1022 | $$->p_pcnt = 1; | 1027 | $$->p_pcnt = 1; | |
1023 | } | 1028 | } | |
1024 | ; | 1029 | ; | |
1025 | 1030 | |||
1026 | type_qualifier_list: | 1031 | type_qualifier_list: | |
1027 | type_qualifier { | 1032 | type_qualifier { | |
1028 | $$ = $1; | 1033 | $$ = $1; | |
1029 | } | 1034 | } | |
1030 | | type_qualifier_list type_qualifier { | 1035 | | type_qualifier_list type_qualifier { | |
1031 | $$ = mergepq($1, $2); | 1036 | $$ = mergepq($1, $2); | |
1032 | } | 1037 | } | |
1033 | ; | 1038 | ; | |
1034 | 1039 | |||
1035 | type_qualifier: | 1040 | type_qualifier: | |
1036 | T_QUAL { | 1041 | T_QUAL { | |
1037 | $$ = xcalloc(1, sizeof (pqinf_t)); | 1042 | $$ = xcalloc(1, sizeof (pqinf_t)); | |
1038 | if ($1 == CONST) { | 1043 | if ($1 == CONST) { | |
1039 | $$->p_const = 1; | 1044 | $$->p_const = 1; | |
1040 | } else { | 1045 | } else { | |
1041 | $$->p_volatile = 1; | 1046 | $$->p_volatile = 1; | |
1042 | } | 1047 | } | |
1043 | } | 1048 | } | |
1044 | ; | 1049 | ; | |
1045 | 1050 | |||
1046 | param_list: | 1051 | param_list: | |
1047 | id_list_lparn identifier_list T_RPARN { | 1052 | id_list_lparn identifier_list T_RPARN { | |
1048 | $$ = $2; | 1053 | $$ = $2; | |
1049 | } | 1054 | } | |
1050 | | abs_decl_param_list { | 1055 | | abs_decl_param_list { | |
1051 | $$ = $1; | 1056 | $$ = $1; | |
1052 | } | 1057 | } | |
1053 | ; | 1058 | ; | |
1054 | 1059 | |||
1055 | id_list_lparn: | 1060 | id_list_lparn: | |
1056 | T_LPARN { | 1061 | T_LPARN { | |
1057 | blklev++; | 1062 | blklev++; | |
1058 | pushdecl(PARG); | 1063 | pushdecl(PARG); | |
1059 | } | 1064 | } | |
1060 | ; | 1065 | ; | |
1061 | 1066 | |||
1062 | identifier_list: | 1067 | identifier_list: | |
1063 | T_NAME { | 1068 | T_NAME { | |
1064 | $$ = iname(getsym($1)); | 1069 | $$ = iname(getsym($1)); | |
1065 | } | 1070 | } | |
1066 | | identifier_list T_COMMA T_NAME { | 1071 | | identifier_list T_COMMA T_NAME { | |
1067 | $$ = lnklst($1, iname(getsym($3))); | 1072 | $$ = lnklst($1, iname(getsym($3))); | |
1068 | } | 1073 | } | |
1069 | | identifier_list error { | 1074 | | identifier_list error { | |
1070 | $$ = $1; | 1075 | $$ = $1; | |
1071 | } | 1076 | } | |
1072 | ; | 1077 | ; | |
1073 | 1078 | |||
1074 | abs_decl_param_list: | 1079 | abs_decl_param_list: | |
1075 | abs_decl_lparn T_RPARN { | 1080 | abs_decl_lparn T_RPARN { | |
1076 | $$ = NULL; | 1081 | $$ = NULL; | |
1077 | } | 1082 | } | |
1078 | | abs_decl_lparn vararg_parameter_type_list T_RPARN { | 1083 | | abs_decl_lparn vararg_parameter_type_list T_RPARN { | |
1079 | dcs->d_proto = 1; | 1084 | dcs->d_proto = 1; | |
1080 | $$ = $2; | 1085 | $$ = $2; | |
1081 | } | 1086 | } | |
1082 | | abs_decl_lparn error T_RPARN { | 1087 | | abs_decl_lparn error T_RPARN { | |
1083 | $$ = NULL; | 1088 | $$ = NULL; | |
1084 | } | 1089 | } | |
1085 | ; | 1090 | ; | |
1086 | 1091 | |||
1087 | abs_decl_lparn: | 1092 | abs_decl_lparn: | |
1088 | T_LPARN { | 1093 | T_LPARN { | |
1089 | blklev++; | 1094 | blklev++; | |
1090 | pushdecl(PARG); | 1095 | pushdecl(PARG); | |
1091 | } | 1096 | } | |
1092 | ; | 1097 | ; | |
1093 | 1098 | |||
1094 | vararg_parameter_type_list: | 1099 | vararg_parameter_type_list: | |
1095 | parameter_type_list { | 1100 | parameter_type_list { | |
1096 | $$ = $1; | 1101 | $$ = $1; | |
1097 | } | 1102 | } | |
1098 | | parameter_type_list T_COMMA T_ELLIPSE { | 1103 | | parameter_type_list T_COMMA T_ELLIPSE { | |
1099 | dcs->d_vararg = 1; | 1104 | dcs->d_vararg = 1; | |
1100 | $$ = $1; | 1105 | $$ = $1; | |
1101 | } | 1106 | } | |
1102 | | T_ELLIPSE { | 1107 | | T_ELLIPSE { | |
1103 | if (sflag) { | 1108 | if (sflag) { | |
1104 | /* ANSI C requires formal parameter before "..." */ | 1109 | /* ANSI C requires formal parameter before "..." */ | |
1105 | error(84); | 1110 | error(84); | |
1106 | } else if (!tflag) { | 1111 | } else if (!tflag) { | |
1107 | /* ANSI C requires formal parameter before "..." */ | 1112 | /* ANSI C requires formal parameter before "..." */ | |
1108 | warning(84); | 1113 | warning(84); | |
1109 | } | 1114 | } | |
1110 | dcs->d_vararg = 1; | 1115 | dcs->d_vararg = 1; | |
1111 | $$ = NULL; | 1116 | $$ = NULL; | |
1112 | } | 1117 | } | |
1113 | ; | 1118 | ; | |
1114 | 1119 | |||
1115 | parameter_type_list: | 1120 | parameter_type_list: | |
1116 | parameter_declaration { | 1121 | parameter_declaration { | |
1117 | $$ = $1; | 1122 | $$ = $1; | |
1118 | } | 1123 | } | |
1119 | | parameter_type_list T_COMMA parameter_declaration { | 1124 | | parameter_type_list T_COMMA parameter_declaration { | |
1120 | $$ = lnklst($1, $3); | 1125 | $$ = lnklst($1, $3); | |
1121 | } | 1126 | } | |
1122 | ; | 1127 | ; | |
1123 | 1128 | |||
1124 | parameter_declaration: | 1129 | parameter_declaration: | |
1125 | declmods deftyp { | 1130 | declmods deftyp { | |
1126 | $$ = decl1arg(aname(), 0); | 1131 | $$ = decl1arg(aname(), 0); | |
1127 | } | 1132 | } | |
1128 | | declspecs deftyp { | 1133 | | declspecs deftyp { | |
1129 | $$ = decl1arg(aname(), 0); | 1134 | $$ = decl1arg(aname(), 0); | |
1130 | } | 1135 | } | |
1131 | | declmods deftyp notype_param_decl { | 1136 | | declmods deftyp notype_param_decl { | |
1132 | $$ = decl1arg($3, 0); | 1137 | $$ = decl1arg($3, 0); | |
1133 | } | 1138 | } | |
1134 | /* | 1139 | /* | |
1135 | * param_decl is needed because of following conflict: | 1140 | * param_decl is needed because of following conflict: | |
1136 | * "typedef int a; f(int (a));" could be parsed as | 1141 | * "typedef int a; f(int (a));" could be parsed as | |
1137 | * "function with argument a of type int", or | 1142 | * "function with argument a of type int", or | |
1138 | * "function with an abstract argument of type function". | 1143 | * "function with an abstract argument of type function". | |
1139 | * This grammar realizes the second case. | 1144 | * This grammar realizes the second case. | |
1140 | */ | 1145 | */ | |
1141 | | declspecs deftyp param_decl { | 1146 | | declspecs deftyp param_decl { | |
1142 | $$ = decl1arg($3, 0); | 1147 | $$ = decl1arg($3, 0); | |
1143 | } | 1148 | } | |
1144 | | declmods deftyp abs_decl { | 1149 | | declmods deftyp abs_decl { | |
1145 | $$ = decl1arg($3, 0); | 1150 | $$ = decl1arg($3, 0); | |
1146 | } | 1151 | } | |
1147 | | declspecs deftyp abs_decl { | 1152 | | declspecs deftyp abs_decl { | |
1148 | $$ = decl1arg($3, 0); | 1153 | $$ = decl1arg($3, 0); | |
1149 | } | 1154 | } | |
1150 | ; | 1155 | ; | |
1151 | 1156 | |||
1152 | opt_asm_or_symbolrename: /* expect only one */ | 1157 | opt_asm_or_symbolrename: /* expect only one */ | |
1153 | /* empty */ { | 1158 | /* empty */ { | |
1154 | $$ = NULL; | 1159 | $$ = NULL; | |
1155 | } | 1160 | } | |
1156 | | T_ASM T_LPARN T_STRING T_RPARN { | 1161 | | T_ASM T_LPARN T_STRING T_RPARN { | |
1157 | freeyyv(&$3, T_STRING); | 1162 | freeyyv(&$3, T_STRING); | |
1158 | $$ = NULL; | 1163 | $$ = NULL; | |
1159 | } | 1164 | } | |
1160 | | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN { | 1165 | | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN { | |
1161 | $$ = $3; | 1166 | $$ = $3; | |
1162 | } | 1167 | } | |
1163 | ; | 1168 | ; | |
1164 | 1169 | |||
1165 | initializer: | 1170 | initializer: | |
1166 | init_expr | 1171 | init_expr | |
1167 | ; | 1172 | ; | |
1168 | 1173 | |||
1169 | init_expr: | 1174 | init_expr: | |
1170 | expr %prec T_COMMA { | 1175 | expr %prec T_COMMA { | |
1171 | mkinit($1); | 1176 | mkinit($1); | |
1172 | } | 1177 | } | |
1173 | | init_by_name init_expr %prec T_COMMA | 1178 | | init_by_name init_expr %prec T_COMMA | |
1174 | | init_lbrace init_rbrace | 1179 | | init_lbrace init_rbrace | |
1175 | | init_lbrace init_expr_list init_rbrace | 1180 | | init_lbrace init_expr_list init_rbrace | |
1176 | | init_lbrace init_expr_list T_COMMA init_rbrace | 1181 | | init_lbrace init_expr_list T_COMMA init_rbrace | |
1177 | | error | 1182 | | error | |
1178 | ; | 1183 | ; | |
1179 | 1184 | |||
1180 | init_expr_list: | 1185 | init_expr_list: | |
1181 | init_expr %prec T_COMMA | 1186 | init_expr %prec T_COMMA | |
1182 | | init_expr_list T_COMMA init_expr | 1187 | | init_expr_list T_COMMA init_expr | |
1183 | ; | 1188 | ; | |
1184 | 1189 | |||
1185 | lorange: | 1190 | lorange: | |
1186 | constant T_ELLIPSE { | 1191 | constant T_ELLIPSE { | |
1187 | $$.lo = toicon($1, 1); | 1192 | $$.lo = toicon($1, 1); | |
1188 | } | 1193 | } | |
1189 | ; | 1194 | ; | |
1190 | range: | 1195 | range: | |
1191 | constant { | 1196 | constant { | |
1192 | $$.lo = toicon($1, 1); | 1197 | $$.lo = toicon($1, 1); | |
1193 | $$.hi = $$.lo + 1; | 1198 | $$.hi = $$.lo + 1; | |
1194 | } | 1199 | } | |
1195 | | lorange constant { | 1200 | | lorange constant { | |
1196 | $$.lo = $1.lo; | 1201 | $$.lo = $1.lo; | |
1197 | $$.hi = toicon($2, 1); | 1202 | $$.hi = toicon($2, 1); | |
1198 | } | 1203 | } | |
1199 | ; | 1204 | ; | |
1200 | 1205 | |||
1201 | init_by_name: | 1206 | init_by_name: | |
1202 | T_LBRACK range T_RBRACK T_ASSIGN { | 1207 | T_LBRACK range T_RBRACK T_ASSIGN { | |
1203 | if (!Sflag) | 1208 | if (!Sflag) | |
1204 | warning(321); | 1209 | warning(321); | |
1205 | } | 1210 | } | |
1206 | | point identifier T_ASSIGN { | 1211 | | point identifier T_ASSIGN { | |
1207 | if (!Sflag) | 1212 | if (!Sflag) | |
1208 | warning(313); | 1213 | warning(313); | |
1209 | memberpush($2); | 1214 | memberpush($2); | |
1210 | } | 1215 | } | |
1211 | | identifier T_COLON { | 1216 | | identifier T_COLON { | |
1212 | gnuism(315); | 1217 | gnuism(315); | |
1213 | memberpush($1); | 1218 | memberpush($1); | |
1214 | } | 1219 | } | |
1215 | ; | 1220 | ; | |
1216 | 1221 | |||
1217 | init_lbrace: | 1222 | init_lbrace: | |
1218 | T_LBRACE { | 1223 | T_LBRACE { | |
1219 | initlbr(); | 1224 | initlbr(); | |
1220 | } | 1225 | } | |
1221 | ; | 1226 | ; | |
1222 | 1227 | |||
1223 | init_rbrace: | 1228 | init_rbrace: | |
1224 | T_RBRACE { | 1229 | T_RBRACE { | |
1225 | initrbr(); | 1230 | initrbr(); | |
1226 | } | 1231 | } | |
1227 | ; | 1232 | ; | |
1228 | 1233 | |||
1229 | type_name: | 1234 | type_name: | |
1230 | { | 1235 | { | |
1231 | pushdecl(ABSTRACT); | 1236 | pushdecl(ABSTRACT); | |
1232 | } abstract_declaration { | 1237 | } abstract_declaration { | |
1233 | popdecl(); | 1238 | popdecl(); | |
1234 | $$ = $2->s_type; | 1239 | $$ = $2->s_type; | |
1235 | } | 1240 | } | |
1236 | ; | 1241 | ; | |
1237 | 1242 | |||
1238 | abstract_declaration: | 1243 | abstract_declaration: | |
1239 | noclass_declmods deftyp { | 1244 | noclass_declmods deftyp { | |
1240 | $$ = decl1abs(aname()); | 1245 | $$ = decl1abs(aname()); | |
1241 | } | 1246 | } | |
1242 | | noclass_declspecs deftyp { | 1247 | | noclass_declspecs deftyp { | |
1243 | $$ = decl1abs(aname()); | 1248 | $$ = decl1abs(aname()); | |
1244 | } | 1249 | } | |
1245 | | noclass_declmods deftyp abs_decl { | 1250 | | noclass_declmods deftyp abs_decl { | |
1246 | $$ = decl1abs($3); | 1251 | $$ = decl1abs($3); | |
1247 | } | 1252 | } | |
1248 | | noclass_declspecs deftyp abs_decl { | 1253 | | noclass_declspecs deftyp abs_decl { | |
1249 | $$ = decl1abs($3); | 1254 | $$ = decl1abs($3); | |
1250 | } | 1255 | } | |
1251 | ; | 1256 | ; | |
1252 | 1257 | |||
1253 | abs_decl: | 1258 | abs_decl: | |
1254 | pointer { | 1259 | pointer { | |
1255 | $$ = addptr(aname(), $1); | 1260 | $$ = addptr(aname(), $1); | |
1256 | } | 1261 | } | |
1257 | | direct_abs_decl { | 1262 | | direct_abs_decl { | |
1258 | $$ = $1; | 1263 | $$ = $1; | |
1259 | } | 1264 | } | |
1260 | | pointer direct_abs_decl { | 1265 | | pointer direct_abs_decl { | |
1261 | $$ = addptr($2, $1); | 1266 | $$ = addptr($2, $1); | |
1262 | } | 1267 | } | |
1263 | ; | 1268 | ; | |
1264 | 1269 | |||
1265 | direct_abs_decl: | 1270 | direct_abs_decl: | |
1266 | T_LPARN abs_decl T_RPARN { | 1271 | T_LPARN abs_decl T_RPARN { | |
1267 | $$ = $2; | 1272 | $$ = $2; | |
1268 | } | 1273 | } | |
1269 | | T_LBRACK T_RBRACK { | 1274 | | T_LBRACK T_RBRACK { | |
1270 | $$ = addarray(aname(), 0, 0); | 1275 | $$ = addarray(aname(), 0, 0); | |
1271 | } | 1276 | } | |
1272 | | T_LBRACK constant T_RBRACK { | 1277 | | T_LBRACK constant T_RBRACK { | |
1273 | $$ = addarray(aname(), 1, toicon($2, 0)); | 1278 | $$ = addarray(aname(), 1, toicon($2, 0)); | |
1274 | } | 1279 | } | |
1275 | | direct_abs_decl T_LBRACK T_RBRACK { | 1280 | | direct_abs_decl T_LBRACK T_RBRACK { | |
1276 | $$ = addarray($1, 0, 0); | 1281 | $$ = addarray($1, 0, 0); | |
1277 | } | 1282 | } | |
1278 | | direct_abs_decl T_LBRACK constant T_RBRACK { | 1283 | | direct_abs_decl T_LBRACK constant T_RBRACK { | |
1279 | $$ = addarray($1, 1, toicon($3, 0)); | 1284 | $$ = addarray($1, 1, toicon($3, 0)); | |
1280 | } | 1285 | } | |
1281 | | abs_decl_param_list { | 1286 | | abs_decl_param_list { | |
1282 | $$ = addfunc(aname(), $1); | 1287 | $$ = addfunc(aname(), $1); | |
1283 | popdecl(); | 1288 | popdecl(); | |
1284 | blklev--; | 1289 | blklev--; | |
1285 | } | 1290 | } | |
1286 | | direct_abs_decl abs_decl_param_list { | 1291 | | direct_abs_decl abs_decl_param_list { | |
1287 | $$ = addfunc($1, $2); | 1292 | $$ = addfunc($1, $2); | |
1288 | popdecl(); | 1293 | popdecl(); | |
1289 | blklev--; | 1294 | blklev--; | |
1290 | } | 1295 | } | |
1291 | | direct_abs_decl type_attribute | 1296 | | direct_abs_decl type_attribute | |
1292 | ; | 1297 | ; | |
1293 | 1298 | |||
1294 | non_expr_stmnt: | 1299 | non_expr_stmnt: | |
1295 | labeled_stmnt | 1300 | labeled_stmnt | |
1296 | | comp_stmnt | 1301 | | comp_stmnt | |
1297 | | selection_stmnt | 1302 | | selection_stmnt | |
1298 | | iteration_stmnt | 1303 | | iteration_stmnt | |
1299 | | jump_stmnt { | 1304 | | jump_stmnt { | |
1300 | ftflg = 0; | 1305 | ftflg = 0; | |
1301 | } | 1306 | } | |
1302 | | asm_stmnt | 1307 | | asm_stmnt | |
1303 | 1308 | |||
1304 | stmnt: | 1309 | stmnt: | |
1305 | expr_stmnt | 1310 | expr_stmnt | |
1306 | | non_expr_stmnt | 1311 | | non_expr_stmnt | |
1307 | ; | 1312 | ; | |
1308 | 1313 | |||
1309 | labeled_stmnt: | 1314 | labeled_stmnt: | |
1310 | label stmnt | 1315 | label stmnt | |
1311 | ; | 1316 | ; | |
1312 | 1317 | |||
1313 | label: | 1318 | label: | |
1314 | T_NAME T_COLON { | 1319 | T_NAME T_COLON { | |
1315 | symtyp = FLAB; | 1320 | symtyp = FLAB; | |
1316 | label(T_NAME, getsym($1), NULL); | 1321 | label(T_NAME, getsym($1), NULL); | |
1317 | } | 1322 | } | |
1318 | | T_CASE constant T_COLON { | 1323 | | T_CASE constant T_COLON { | |
1319 | label(T_CASE, NULL, $2); | 1324 | label(T_CASE, NULL, $2); | |
1320 | ftflg = 1; | 1325 | ftflg = 1; | |
1321 | } | 1326 | } | |
1322 | | T_CASE constant T_ELLIPSE constant T_COLON { | 1327 | | T_CASE constant T_ELLIPSE constant T_COLON { | |
1323 | /* XXX: We don't fill all cases */ | 1328 | /* XXX: We don't fill all cases */ | |
1324 | label(T_CASE, NULL, $2); | 1329 | label(T_CASE, NULL, $2); | |
1325 | ftflg = 1; | 1330 | ftflg = 1; | |
1326 | } | 1331 | } | |
1327 | | T_DEFAULT T_COLON { | 1332 | | T_DEFAULT T_COLON { | |
1328 | label(T_DEFAULT, NULL, NULL); | 1333 | label(T_DEFAULT, NULL, NULL); | |
1329 | ftflg = 1; | 1334 | ftflg = 1; | |
1330 | } | 1335 | } | |
1331 | ; | 1336 | ; | |
1332 | 1337 | |||
1333 | stmnt_d_list: | 1338 | stmnt_d_list: | |
1334 | stmnt_list | 1339 | stmnt_list | |
1335 | | stmnt_d_list declaration_list stmnt_list { | 1340 | | stmnt_d_list declaration_list stmnt_list { | |
1336 | if (!Sflag) | 1341 | if (!Sflag) | |
1337 | c99ism(327); | 1342 | c99ism(327); | |
1338 | } | 1343 | } | |
1339 | ; | 1344 | ; | |
1340 | 1345 | |||
1341 | comp_stmnt: | 1346 | comp_stmnt: | |
1342 | comp_stmnt_lbrace comp_stmnt_rbrace | 1347 | comp_stmnt_lbrace comp_stmnt_rbrace | |
1343 | | comp_stmnt_lbrace stmnt_d_list comp_stmnt_rbrace | 1348 | | comp_stmnt_lbrace stmnt_d_list comp_stmnt_rbrace | |
1344 | | comp_stmnt_lbrace declaration_list comp_stmnt_rbrace | 1349 | | comp_stmnt_lbrace declaration_list comp_stmnt_rbrace | |
1345 | | comp_stmnt_lbrace declaration_list stmnt_d_list comp_stmnt_rbrace | 1350 | | comp_stmnt_lbrace declaration_list stmnt_d_list comp_stmnt_rbrace | |
1346 | ; | 1351 | ; | |
1347 | 1352 | |||
1348 | comp_stmnt_lbrace: | 1353 | comp_stmnt_lbrace: | |
1349 | T_LBRACE { | 1354 | T_LBRACE { | |
1350 | blklev++; | 1355 | blklev++; | |
1351 | mblklev++; | 1356 | mblklev++; | |
1352 | pushdecl(AUTO); | 1357 | pushdecl(AUTO); | |
1353 | } | 1358 | } | |
1354 | ; | 1359 | ; | |
1355 | 1360 | |||
1356 | comp_stmnt_rbrace: | 1361 | comp_stmnt_rbrace: | |
1357 | T_RBRACE { | 1362 | T_RBRACE { | |
1358 | popdecl(); | 1363 | popdecl(); | |
1359 | freeblk(); | 1364 | freeblk(); | |
1360 | mblklev--; | 1365 | mblklev--; | |
1361 | blklev--; | 1366 | blklev--; | |
1362 | ftflg = 0; | 1367 | ftflg = 0; | |
1363 | } | 1368 | } | |
1364 | ; | 1369 | ; | |
1365 | 1370 | |||
1366 | stmnt_list: | 1371 | stmnt_list: | |
1367 | stmnt | 1372 | stmnt | |
1368 | | stmnt_list stmnt { | 1373 | | stmnt_list stmnt { | |
1369 | RESTORE(__FILE__, __LINE__); | 1374 | RESTORE(__FILE__, __LINE__); | |
1370 | } | 1375 | } | |
1371 | | stmnt_list error T_SEMI | 1376 | | stmnt_list error T_SEMI | |
1372 | ; | 1377 | ; | |
1373 | 1378 | |||
1374 | expr_stmnt: | 1379 | expr_stmnt: | |
1375 | expr T_SEMI { | 1380 | expr T_SEMI { | |
1376 | expr($1, 0, 0, 1); | 1381 | expr($1, 0, 0, 1); | |
1377 | ftflg = 0; | 1382 | ftflg = 0; | |
1378 | } | 1383 | } | |
1379 | | T_SEMI { | 1384 | | T_SEMI { | |
1380 | ftflg = 0; | 1385 | ftflg = 0; | |
1381 | } | 1386 | } | |
1382 | ; | 1387 | ; | |
1383 | 1388 | |||
1384 | /* | 1389 | /* | |
1385 | * The following two productions are used to implement | 1390 | * The following two productions are used to implement | |
1386 | * ({ [[decl-list] stmt-list] }). | 1391 | * ({ [[decl-list] stmt-list] }). | |
1387 | * XXX: This is not well tested. | 1392 | * XXX: This is not well tested. | |
1388 | */ | 1393 | */ | |
1389 | expr_stmnt_val: | 1394 | expr_stmnt_val: | |
1390 | expr T_SEMI { | 1395 | expr T_SEMI { | |
1391 | /* XXX: We should really do that only on the last name */ | 1396 | /* XXX: We should really do that only on the last name */ | |
1392 | if ($1->tn_op == NAME) | 1397 | if ($1->tn_op == NAME) | |
1393 | $1->tn_sym->s_used = 1; | 1398 | $1->tn_sym->s_used = 1; | |
1394 | $$ = $1; | 1399 | $$ = $1; | |
1395 | expr($1, 0, 0, 0); | 1400 | expr($1, 0, 0, 0); | |
1396 | ftflg = 0; | 1401 | ftflg = 0; | |
1397 | } | 1402 | } | |
1398 | | non_expr_stmnt { | 1403 | | non_expr_stmnt { | |
1399 | $$ = getnode(); | 1404 | $$ = getnode(); | |
1400 | $$->tn_type = gettyp(VOID); | 1405 | $$->tn_type = gettyp(VOID); | |
1401 | } | 1406 | } | |
1402 | ; | 1407 | ; | |
1403 | 1408 | |||
1404 | expr_stmnt_list: | 1409 | expr_stmnt_list: | |
1405 | expr_stmnt_val | 1410 | expr_stmnt_val | |
1406 | | expr_stmnt_list expr_stmnt_val { | 1411 | | expr_stmnt_list expr_stmnt_val { | |
1407 | $$ = $2; | 1412 | $$ = $2; | |
1408 | } | 1413 | } | |
1409 | ; | 1414 | ; | |
1410 | 1415 | |||
1411 | selection_stmnt: | 1416 | selection_stmnt: | |
1412 | if_without_else { | 1417 | if_without_else { | |
1413 | SAVE(__FILE__, __LINE__); | 1418 | SAVE(__FILE__, __LINE__); | |
1414 | if2(); | 1419 | if2(); | |
1415 | if3(0); | 1420 | if3(0); | |
1416 | } | 1421 | } | |
1417 | | if_without_else T_ELSE { | 1422 | | if_without_else T_ELSE { | |
1418 | SAVE(__FILE__, __LINE__); | 1423 | SAVE(__FILE__, __LINE__); | |
1419 | if2(); | 1424 | if2(); | |
1420 | } stmnt { | 1425 | } stmnt { | |
1421 | CLRWFLGS(__FILE__, __LINE__); | 1426 | CLRWFLGS(__FILE__, __LINE__); | |
1422 | if3(1); | 1427 | if3(1); | |
1423 | } | 1428 | } | |
1424 | | if_without_else T_ELSE error { | 1429 | | if_without_else T_ELSE error { | |
1425 | CLRWFLGS(__FILE__, __LINE__); | 1430 | CLRWFLGS(__FILE__, __LINE__); | |
1426 | if3(0); | 1431 | if3(0); | |
1427 | } | 1432 | } | |
1428 | | switch_expr stmnt { | 1433 | | switch_expr stmnt { | |
1429 | CLRWFLGS(__FILE__, __LINE__); | 1434 | CLRWFLGS(__FILE__, __LINE__); | |
1430 | switch2(); | 1435 | switch2(); | |
1431 | } | 1436 | } | |
1432 | | switch_expr error { | 1437 | | switch_expr error { | |
1433 | CLRWFLGS(__FILE__, __LINE__); | 1438 | CLRWFLGS(__FILE__, __LINE__); | |
1434 | switch2(); | 1439 | switch2(); | |
1435 | } | 1440 | } | |
1436 | ; | 1441 | ; | |
1437 | 1442 | |||
1438 | if_without_else: | 1443 | if_without_else: | |
1439 | if_expr stmnt | 1444 | if_expr stmnt | |
1440 | | if_expr error | 1445 | | if_expr error | |
1441 | ; | 1446 | ; | |
1442 | 1447 | |||
1443 | if_expr: | 1448 | if_expr: | |
1444 | T_IF T_LPARN expr T_RPARN { | 1449 | T_IF T_LPARN expr T_RPARN { | |
1445 | if1($3); | 1450 | if1($3); | |
1446 | CLRWFLGS(__FILE__, __LINE__); | 1451 | CLRWFLGS(__FILE__, __LINE__); | |
1447 | } | 1452 | } | |
1448 | ; | 1453 | ; | |
1449 | 1454 | |||
1450 | switch_expr: | 1455 | switch_expr: | |
1451 | T_SWITCH T_LPARN expr T_RPARN { | 1456 | T_SWITCH T_LPARN expr T_RPARN { | |
1452 | switch1($3); | 1457 | switch1($3); | |
1453 | CLRWFLGS(__FILE__, __LINE__); | 1458 | CLRWFLGS(__FILE__, __LINE__); | |
1454 | } | 1459 | } | |
1455 | ; | 1460 | ; | |
1456 | 1461 | |||
1457 | do_stmnt: | 1462 | do_stmnt: | |
1458 | do stmnt { | 1463 | do stmnt { | |
1459 | CLRWFLGS(__FILE__, __LINE__); | 1464 | CLRWFLGS(__FILE__, __LINE__); | |
1460 | } | 1465 | } | |
1461 | ; | 1466 | ; | |
1462 | 1467 | |||
1463 | iteration_stmnt: | 1468 | iteration_stmnt: | |
1464 | while_expr stmnt { | 1469 | while_expr stmnt { | |
1465 | CLRWFLGS(__FILE__, __LINE__); | 1470 | CLRWFLGS(__FILE__, __LINE__); | |
1466 | while2(); | 1471 | while2(); | |
1467 | } | 1472 | } | |
1468 | | while_expr error { | 1473 | | while_expr error { | |
1469 | CLRWFLGS(__FILE__, __LINE__); | 1474 | CLRWFLGS(__FILE__, __LINE__); | |
1470 | while2(); | 1475 | while2(); | |
1471 | } | 1476 | } | |
1472 | | do_stmnt do_while_expr { | 1477 | | do_stmnt do_while_expr { | |
1473 | do2($2); | 1478 | do2($2); | |
1474 | ftflg = 0; | 1479 | ftflg = 0; | |
1475 | } | 1480 | } | |
1476 | | do error { | 1481 | | do error { | |
1477 | CLRWFLGS(__FILE__, __LINE__); | 1482 | CLRWFLGS(__FILE__, __LINE__); | |
1478 | do2(NULL); | 1483 | do2(NULL); | |
1479 | } | 1484 | } | |
1480 | | for_exprs stmnt { | 1485 | | for_exprs stmnt { | |
1481 | CLRWFLGS(__FILE__, __LINE__); | 1486 | CLRWFLGS(__FILE__, __LINE__); | |
1482 | for2(); | 1487 | for2(); | |
1483 | } | 1488 | } | |
1484 | | for_exprs error { | 1489 | | for_exprs error { | |
1485 | CLRWFLGS(__FILE__, __LINE__); | 1490 | CLRWFLGS(__FILE__, __LINE__); | |
1486 | for2(); | 1491 | for2(); | |
1487 | } | 1492 | } | |
1488 | ; | 1493 | ; | |
1489 | 1494 | |||
1490 | while_expr: | 1495 | while_expr: | |
1491 | T_WHILE T_LPARN expr T_RPARN { | 1496 | T_WHILE T_LPARN expr T_RPARN { | |
1492 | while1($3); | 1497 | while1($3); | |
1493 | CLRWFLGS(__FILE__, __LINE__); | 1498 | CLRWFLGS(__FILE__, __LINE__); | |
1494 | } | 1499 | } | |
1495 | ; | 1500 | ; | |
1496 | 1501 | |||
1497 | do: | 1502 | do: | |
1498 | T_DO { | 1503 | T_DO { | |
1499 | do1(); | 1504 | do1(); | |
1500 | } | 1505 | } | |
1501 | ; | 1506 | ; | |
1502 | 1507 | |||
1503 | do_while_expr: | 1508 | do_while_expr: | |
1504 | T_WHILE T_LPARN expr T_RPARN T_SEMI { | 1509 | T_WHILE T_LPARN expr T_RPARN T_SEMI { | |
1505 | $$ = $3; | 1510 | $$ = $3; | |
1506 | } | 1511 | } | |
1507 | ; | 1512 | ; | |
1508 | 1513 | |||
1509 | for_exprs: | 1514 | for_exprs: | |
1510 | T_FOR T_LPARN declspecs deftyp notype_init_decls T_SEMI opt_expr | 1515 | T_FOR T_LPARN declspecs deftyp notype_init_decls T_SEMI opt_expr | |
1511 | T_SEMI opt_expr T_RPARN { | 1516 | T_SEMI opt_expr T_RPARN { | |
1512 | c99ism(325); | 1517 | c99ism(325); | |
1513 | for1(NULL, $7, $9); | 1518 | for1(NULL, $7, $9); | |
1514 | CLRWFLGS(__FILE__, __LINE__); | 1519 | CLRWFLGS(__FILE__, __LINE__); | |
1515 | } | 1520 | } | |
1516 | | T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN { | 1521 | | T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN { | |
1517 | for1($3, $5, $7); | 1522 | for1($3, $5, $7); | |
1518 | CLRWFLGS(__FILE__, __LINE__); | 1523 | CLRWFLGS(__FILE__, __LINE__); | |
1519 | } | 1524 | } | |
1520 | ; | 1525 | ; | |
1521 | 1526 | |||
1522 | opt_expr: | 1527 | opt_expr: | |
1523 | /* empty */ { | 1528 | /* empty */ { | |
1524 | $$ = NULL; | 1529 | $$ = NULL; | |
1525 | } | 1530 | } | |
1526 | | expr { | 1531 | | expr { | |
1527 | $$ = $1; | 1532 | $$ = $1; | |
1528 | } | 1533 | } | |
1529 | ; | 1534 | ; | |
1530 | 1535 | |||
1531 | jump_stmnt: | 1536 | jump_stmnt: | |
1532 | goto identifier T_SEMI { | 1537 | goto identifier T_SEMI { | |
1533 | dogoto(getsym($2)); | 1538 | dogoto(getsym($2)); | |
1534 | } | 1539 | } | |
1535 | | goto error T_SEMI { | 1540 | | goto error T_SEMI { | |
1536 | symtyp = FVFT; | 1541 | symtyp = FVFT; | |
1537 | } | 1542 | } | |
1538 | | T_CONTINUE T_SEMI { | 1543 | | T_CONTINUE T_SEMI { | |
1539 | docont(); | 1544 | docont(); | |
1540 | } | 1545 | } | |
1541 | | T_BREAK T_SEMI { | 1546 | | T_BREAK T_SEMI { | |
1542 | dobreak(); | 1547 | dobreak(); | |
1543 | } | 1548 | } | |
1544 | | T_RETURN T_SEMI { | 1549 | | T_RETURN T_SEMI { | |
1545 | doreturn(NULL); | 1550 | doreturn(NULL); | |
1546 | } | 1551 | } | |
1547 | | T_RETURN expr T_SEMI { | 1552 | | T_RETURN expr T_SEMI { | |
1548 | doreturn($2); | 1553 | doreturn($2); | |
1549 | } | 1554 | } | |
1550 | ; | 1555 | ; | |
1551 | 1556 | |||
1552 | goto: | 1557 | goto: | |
1553 | T_GOTO { | 1558 | T_GOTO { | |
1554 | symtyp = FLAB; | 1559 | symtyp = FLAB; | |
1555 | } | 1560 | } | |
1556 | ; | 1561 | ; | |
1557 | 1562 | |||
1558 | asm_stmnt: | 1563 | asm_stmnt: | |
1559 | T_ASM T_LPARN read_until_rparn T_SEMI { | 1564 | T_ASM T_LPARN read_until_rparn T_SEMI { | |
1560 | setasm(); | 1565 | setasm(); | |
1561 | } | 1566 | } | |
1562 | | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI { | 1567 | | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI { | |
1563 | setasm(); | 1568 | setasm(); | |
1564 | } | 1569 | } | |
1565 | | T_ASM error | 1570 | | T_ASM error | |
1566 | ; | 1571 | ; | |
1567 | 1572 | |||
1568 | read_until_rparn: | 1573 | read_until_rparn: | |
1569 | /* empty */ { | 1574 | /* empty */ { | |
1570 | ignuptorp(); | 1575 | ignuptorp(); | |
1571 | } | 1576 | } | |
1572 | ; | 1577 | ; | |
1573 | 1578 | |||
1574 | declaration_list: | 1579 | declaration_list: | |
1575 | declaration { | 1580 | declaration { | |
1576 | CLRWFLGS(__FILE__, __LINE__); | 1581 | CLRWFLGS(__FILE__, __LINE__); | |
1577 | } | 1582 | } | |
1578 | | declaration_list declaration { | 1583 | | declaration_list declaration { | |
1579 | CLRWFLGS(__FILE__, __LINE__); | 1584 | CLRWFLGS(__FILE__, __LINE__); | |
1580 | } | 1585 | } | |
1581 | ; | 1586 | ; | |
1582 | 1587 | |||
1583 | constant: | 1588 | constant: | |
1584 | expr %prec T_COMMA { | 1589 | expr %prec T_COMMA { | |
1585 | $$ = $1; | 1590 | $$ = $1; | |
1586 | } | 1591 | } | |
1587 | ; | 1592 | ; | |
1588 | 1593 | |||
1589 | expr: | 1594 | expr: | |
1590 | expr T_MULT expr { | 1595 | expr T_MULT expr { | |
1591 | $$ = build(MULT, $1, $3); | 1596 | $$ = build(MULT, $1, $3); | |
1592 | } | 1597 | } | |
1593 | | expr T_DIVOP expr { | 1598 | | expr T_DIVOP expr { | |
1594 | $$ = build($2, $1, $3); | 1599 | $$ = build($2, $1, $3); | |
1595 | } | 1600 | } | |
1596 | | expr T_ADDOP expr { | 1601 | | expr T_ADDOP expr { | |
1597 | $$ = build($2, $1, $3); | 1602 | $$ = build($2, $1, $3); | |
1598 | } | 1603 | } | |
1599 | | expr T_SHFTOP expr { | 1604 | | expr T_SHFTOP expr { | |
1600 | $$ = build($2, $1, $3); | 1605 | $$ = build($2, $1, $3); | |
1601 | } | 1606 | } | |
1602 | | expr T_RELOP expr { | 1607 | | expr T_RELOP expr { | |
1603 | $$ = build($2, $1, $3); | 1608 | $$ = build($2, $1, $3); | |
1604 | } | 1609 | } | |
1605 | | expr T_EQOP expr { | 1610 | | expr T_EQOP expr { | |
1606 | $$ = build($2, $1, $3); | 1611 | $$ = build($2, $1, $3); | |
1607 | } | 1612 | } | |
1608 | | expr T_AND expr { | 1613 | | expr T_AND expr { | |
1609 | $$ = build(AND, $1, $3); | 1614 | $$ = build(AND, $1, $3); | |
1610 | } | 1615 | } | |
1611 | | expr T_XOR expr { | 1616 | | expr T_XOR expr { | |
1612 | $$ = build(XOR, $1, $3); | 1617 | $$ = build(XOR, $1, $3); | |
1613 | } | 1618 | } | |
1614 | | expr T_OR expr { | 1619 | | expr T_OR expr { | |
1615 | $$ = build(OR, $1, $3); | 1620 | $$ = build(OR, $1, $3); | |
1616 | } | 1621 | } | |
1617 | | expr T_LOGAND expr { | 1622 | | expr T_LOGAND expr { | |
1618 | $$ = build(LOGAND, $1, $3); | 1623 | $$ = build(LOGAND, $1, $3); | |
1619 | } | 1624 | } | |
1620 | | expr T_LOGOR expr { | 1625 | | expr T_LOGOR expr { | |
1621 | $$ = build(LOGOR, $1, $3); | 1626 | $$ = build(LOGOR, $1, $3); | |
1622 | } | 1627 | } | |
1623 | | expr T_QUEST expr T_COLON expr { | 1628 | | expr T_QUEST expr T_COLON expr { | |
1624 | $$ = build(QUEST, $1, build(COLON, $3, $5)); | 1629 | $$ = build(QUEST, $1, build(COLON, $3, $5)); | |
1625 | } | 1630 | } | |
1626 | | expr T_ASSIGN expr { | 1631 | | expr T_ASSIGN expr { | |
1627 | $$ = build(ASSIGN, $1, $3); | 1632 | $$ = build(ASSIGN, $1, $3); | |
1628 | } | 1633 | } | |
1629 | | expr T_OPASS expr { | 1634 | | expr T_OPASS expr { | |
1630 | $$ = build($2, $1, $3); | 1635 | $$ = build($2, $1, $3); | |
1631 | } | 1636 | } | |
1632 | | expr T_COMMA expr { | 1637 | | expr T_COMMA expr { | |
1633 | $$ = build(COMMA, $1, $3); | 1638 | $$ = build(COMMA, $1, $3); | |
1634 | } | 1639 | } | |
1635 | | term { | 1640 | | term { | |
1636 | $$ = $1; | 1641 | $$ = $1; | |
1637 | } | 1642 | } | |
1638 | ; | 1643 | ; | |
1639 | 1644 | |||
1640 | term: | 1645 | term: | |
1641 | T_NAME { | 1646 | T_NAME { | |
1642 | /* XXX really necessary? */ | 1647 | /* XXX really necessary? */ | |
1643 | if (yychar < 0) | 1648 | if (yychar < 0) | |
1644 | yychar = yylex(); | 1649 | yychar = yylex(); | |
1645 | $$ = getnnode(getsym($1), yychar); | 1650 | $$ = getnnode(getsym($1), yychar); | |
1646 | } | 1651 | } | |
1647 | | string { | 1652 | | string { | |
1648 | $$ = getsnode($1); | 1653 | $$ = getsnode($1); | |
1649 | } | 1654 | } | |
1650 | | T_CON { | 1655 | | T_CON { | |
1651 | $$ = getcnode(gettyp($1->v_tspec), $1); | 1656 | $$ = getcnode(gettyp($1->v_tspec), $1); | |
1652 | } | 1657 | } | |
1653 | | T_LPARN expr T_RPARN { | 1658 | | T_LPARN expr T_RPARN { | |
1654 | if ($2 != NULL) | 1659 | if ($2 != NULL) | |
1655 | $2->tn_parn = 1; | 1660 | $2->tn_parn = 1; | |
1656 | $$ = $2; | 1661 | $$ = $2; | |
1657 | } | 1662 | } | |
1658 | | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list { | 1663 | | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list { | |
1659 | blklev--; | 1664 | blklev--; | |
1660 | mblklev--; | 1665 | mblklev--; | |
1661 | initsym = mktempsym(duptyp($4->tn_type)); | 1666 | initsym = mktempsym(duptyp($4->tn_type)); | |
1662 | mblklev++; | 1667 | mblklev++; | |
1663 | blklev++; | 1668 | blklev++; | |
1664 | gnuism(320); | 1669 | gnuism(320); | |
1665 | } comp_stmnt_rbrace T_RPARN { | 1670 | } comp_stmnt_rbrace T_RPARN { | |
1666 | $$ = getnnode(initsym, 0); | 1671 | $$ = getnnode(initsym, 0); | |
1667 | } | 1672 | } | |
1668 | | T_LPARN comp_stmnt_lbrace expr_stmnt_list { | 1673 | | T_LPARN comp_stmnt_lbrace expr_stmnt_list { | |
1669 | blklev--; | 1674 | blklev--; | |
1670 | mblklev--; | 1675 | mblklev--; | |
1671 | initsym = mktempsym($3->tn_type); | 1676 | initsym = mktempsym($3->tn_type); | |
1672 | mblklev++; | 1677 | mblklev++; | |
1673 | blklev++; | 1678 | blklev++; | |
1674 | gnuism(320); | 1679 | gnuism(320); | |
1675 | } comp_stmnt_rbrace T_RPARN { | 1680 | } comp_stmnt_rbrace T_RPARN { | |
1676 | $$ = getnnode(initsym, 0); | 1681 | $$ = getnnode(initsym, 0); | |
1677 | } | 1682 | } | |
1678 | | term T_INCDEC { | 1683 | | term T_INCDEC { | |
1679 | $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL); | 1684 | $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL); | |
1680 | } | 1685 | } | |
1681 | | T_INCDEC term { | 1686 | | T_INCDEC term { | |
1682 | $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL); | 1687 | $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL); | |
1683 | } | 1688 | } | |
1684 | | T_MULT term { | 1689 | | T_MULT term { | |
1685 | $$ = build(STAR, $2, NULL); | 1690 | $$ = build(STAR, $2, NULL); | |
1686 | } | 1691 | } | |
1687 | | T_AND term { | 1692 | | T_AND term { | |
1688 | $$ = build(AMPER, $2, NULL); | 1693 | $$ = build(AMPER, $2, NULL); | |
1689 | } | 1694 | } | |
1690 | | T_UNOP term { | 1695 | | T_UNOP term { | |
1691 | $$ = build($1, $2, NULL); | 1696 | $$ = build($1, $2, NULL); | |
1692 | } | 1697 | } | |
1693 | | T_ADDOP term { | 1698 | | T_ADDOP term { | |
1694 | if (tflag && $1 == PLUS) { | 1699 | if (tflag && $1 == PLUS) { | |
1695 | /* unary + is illegal in traditional C */ | 1700 | /* unary + is illegal in traditional C */ | |
1696 | warning(100); | 1701 | warning(100); | |
1697 | } | 1702 | } | |
1698 | $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL); | 1703 | $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL); | |
1699 | } | 1704 | } | |
1700 | | term T_LBRACK expr T_RBRACK { | 1705 | | term T_LBRACK expr T_RBRACK { | |
1701 | $$ = build(STAR, build(PLUS, $1, $3), NULL); | 1706 | $$ = build(STAR, build(PLUS, $1, $3), NULL); | |
1702 | } | 1707 | } | |
1703 | | term T_LPARN T_RPARN { | 1708 | | term T_LPARN T_RPARN { | |
1704 | $$ = funccall($1, NULL); | 1709 | $$ = funccall($1, NULL); | |
1705 | } | 1710 | } | |
1706 | | term T_LPARN func_arg_list T_RPARN { | 1711 | | term T_LPARN func_arg_list T_RPARN { | |
1707 | $$ = funccall($1, $3); | 1712 | $$ = funccall($1, $3); | |
1708 | } | 1713 | } | |
1709 | | term point_or_arrow T_NAME { | 1714 | | term point_or_arrow T_NAME { | |
1710 | if ($1 != NULL) { | 1715 | if ($1 != NULL) { | |
1711 | sym_t *msym; | 1716 | sym_t *msym; | |
1712 | /* XXX strmemb should be integrated in build() */ | 1717 | /* XXX strmemb should be integrated in build() */ | |
1713 | if ($2 == ARROW) { | 1718 | if ($2 == ARROW) { | |
1714 | /* must to this before strmemb is called */ | 1719 | /* must to this before strmemb is called */ | |
1715 | $1 = cconv($1); | 1720 | $1 = cconv($1); | |
1716 | } | 1721 | } | |
1717 | msym = strmemb($1, $2, getsym($3)); | 1722 | msym = strmemb($1, $2, getsym($3)); | |
1718 | $$ = build($2, $1, getnnode(msym, 0)); | 1723 | $$ = build($2, $1, getnnode(msym, 0)); | |
1719 | } else { | 1724 | } else { | |
1720 | $$ = NULL; | 1725 | $$ = NULL; | |
1721 | } | 1726 | } | |
1722 | } | 1727 | } | |
1723 | | T_REAL term { | 1728 | | T_REAL term { | |
1724 | $$ = build(REAL, $2, NULL); | 1729 | $$ = build(REAL, $2, NULL); | |
1725 | } | 1730 | } | |
1726 | | T_IMAG term { | 1731 | | T_IMAG term { | |
1727 | $$ = build(IMAG, $2, NULL); | 1732 | $$ = build(IMAG, $2, NULL); | |
1728 | } | 1733 | } | |
1729 | | T_REAL T_LPARN term T_RPARN { | 1734 | | T_REAL T_LPARN term T_RPARN { | |
1730 | $$ = build(REAL, $3, NULL); | 1735 | $$ = build(REAL, $3, NULL); | |
1731 | } | 1736 | } | |
1732 | | T_IMAG T_LPARN term T_RPARN { | 1737 | | T_IMAG T_LPARN term T_RPARN { | |
1733 | $$ = build(IMAG, $3, NULL); | 1738 | $$ = build(IMAG, $3, NULL); | |
1734 | } | 1739 | } | |
1740 | | T_EXTENSION T_LPARN term T_RPARN { | |||
1741 | $$ = $3; | |||
1742 | } | |||
1735 | | T_SIZEOF term %prec T_SIZEOF { | 1743 | | T_SIZEOF term %prec T_SIZEOF { | |
1736 | if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL) | 1744 | if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL) | |
1737 | chkmisc($2, 0, 0, 0, 0, 0, 1); | 1745 | chkmisc($2, 0, 0, 0, 0, 0, 1); | |
1738 | } | 1746 | } | |
1739 | | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF { | 1747 | | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF { | |
1740 | $$ = bldszof($3); | 1748 | $$ = bldszof($3); | |
1741 | } | 1749 | } | |
1742 | | T_ALIGNOF T_LPARN type_name T_RPARN %prec T_ALIGNOF { | 1750 | | T_ALIGNOF T_LPARN type_name T_RPARN %prec T_ALIGNOF { | |
1743 | $$ = bldalof($3); | 1751 | $$ = bldalof($3); | |
1744 | } | 1752 | } | |
1745 | | T_LPARN type_name T_RPARN term %prec T_UNOP { | 1753 | | T_LPARN type_name T_RPARN term %prec T_UNOP { | |
1746 | $$ = cast($4, $2); | 1754 | $$ = cast($4, $2); | |
1747 | } | 1755 | } | |
1748 | | T_LPARN type_name T_RPARN %prec T_UNOP { | 1756 | | T_LPARN type_name T_RPARN %prec T_UNOP { | |
1749 | sym_t *tmp = mktempsym($2); | 1757 | sym_t *tmp = mktempsym($2); | |
1750 | idecl(tmp, 1, NULL); | 1758 | idecl(tmp, 1, NULL); | |
1751 | } init_lbrace init_expr_list init_rbrace { | 1759 | } init_lbrace init_expr_list init_rbrace { | |
1752 | if (!Sflag) | 1760 | if (!Sflag) | |
1753 | gnuism(319); | 1761 | gnuism(319); | |
1754 | $$ = getnnode(initsym, 0); | 1762 | $$ = getnnode(initsym, 0); | |
1755 | } | 1763 | } | |
1756 | ; | 1764 | ; | |
1757 | 1765 | |||
1758 | string: | 1766 | string: | |
1759 | T_STRING { | 1767 | T_STRING { | |
1760 | $$ = $1; | 1768 | $$ = $1; | |
1761 | } | 1769 | } | |
1762 | | T_STRING string2 { | 1770 | | T_STRING string2 { | |
1763 | $$ = catstrg($1, $2); | 1771 | $$ = catstrg($1, $2); | |
1764 | } | 1772 | } | |
1765 | ; | 1773 | ; | |
1766 | 1774 | |||
1767 | string2: | 1775 | string2: | |
1768 | T_STRING { | 1776 | T_STRING { | |
1769 | if (tflag) { | 1777 | if (tflag) { | |
1770 | /* concatenated strings are illegal in traditional C */ | 1778 | /* concatenated strings are illegal in traditional C */ | |
1771 | warning(219); | 1779 | warning(219); | |
1772 | } | 1780 | } | |
1773 | $$ = $1; | 1781 | $$ = $1; | |
1774 | } | 1782 | } | |
1775 | | string2 T_STRING { | 1783 | | string2 T_STRING { | |
1776 | $$ = catstrg($1, $2); | 1784 | $$ = catstrg($1, $2); | |
1777 | } | 1785 | } | |
1778 | ; | 1786 | ; | |
1779 | 1787 | |||
1780 | func_arg_list: | 1788 | func_arg_list: | |
1781 | expr %prec T_COMMA { | 1789 | expr %prec T_COMMA { | |
1782 | $$ = funcarg(NULL, $1); | 1790 | $$ = funcarg(NULL, $1); | |
1783 | } | 1791 | } | |
1784 | | func_arg_list T_COMMA expr { | 1792 | | func_arg_list T_COMMA expr { | |
1785 | $$ = funcarg($1, $3); | 1793 | $$ = funcarg($1, $3); | |
1786 | } | 1794 | } | |
1787 | ; | 1795 | ; | |
1788 | 1796 | |||
1789 | point_or_arrow: | 1797 | point_or_arrow: | |
1790 | T_STROP { | 1798 | T_STROP { | |
1791 | symtyp = FMOS; | 1799 | symtyp = FMOS; | |
1792 | $$ = $1; | 1800 | $$ = $1; | |
1793 | } | 1801 | } | |
1794 | ; | 1802 | ; | |
1795 | 1803 | |||
1796 | point: | 1804 | point: | |
1797 | T_STROP { | 1805 | T_STROP { | |
1798 | if ($1 != POINT) { | 1806 | if ($1 != POINT) { | |
1799 | error(249, yytext); | 1807 | error(249, yytext); | |
1800 | } | 1808 | } | |
1801 | } | 1809 | } | |
1802 | ; | 1810 | ; | |
1803 | 1811 | |||
1804 | identifier: | 1812 | identifier: | |
1805 | T_NAME { | 1813 | T_NAME { | |
1806 | $$ = $1; | 1814 | $$ = $1; | |
1807 | } | 1815 | } | |
1808 | | T_TYPENAME { | 1816 | | T_TYPENAME { | |
1809 | $$ = $1; | 1817 | $$ = $1; | |
1810 | } | 1818 | } | |
1811 | ; | 1819 | ; | |
1812 | 1820 | |||
1813 | %% | 1821 | %% | |
1814 | 1822 | |||
1815 | /* ARGSUSED */ | 1823 | /* ARGSUSED */ | |
1816 | int | 1824 | int | |
1817 | yyerror(const char *msg) | 1825 | yyerror(const char *msg) | |
1818 | { | 1826 | { | |
1819 | error(249, yytext); | 1827 | error(249, yytext); | |
1820 | if (++sytxerr >= 5) | 1828 | if (++sytxerr >= 5) | |
1821 | norecover(); | 1829 | norecover(); | |
1822 | return (0); | 1830 | return (0); | |
1823 | } | 1831 | } | |
1824 | 1832 | |||
1825 | static __inline int uq_gt(uint64_t, uint64_t); | 1833 | static __inline int uq_gt(uint64_t, uint64_t); | |
1826 | static __inline int q_gt(int64_t, int64_t); | 1834 | static __inline int q_gt(int64_t, int64_t); | |
1827 | 1835 | |||
1828 | static __inline int | 1836 | static __inline int | |
1829 | uq_gt(uint64_t a, uint64_t b) | 1837 | uq_gt(uint64_t a, uint64_t b) | |
1830 | { | 1838 | { | |
1831 | 1839 | |||
1832 | return (a > b); | 1840 | return (a > b); | |
1833 | } | 1841 | } | |
1834 | 1842 | |||
1835 | static __inline int | 1843 | static __inline int | |
1836 | q_gt(int64_t a, int64_t b) | 1844 | q_gt(int64_t a, int64_t b) | |
1837 | { | 1845 | { | |
1838 | 1846 | |||
1839 | return (a > b); | 1847 | return (a > b); | |
1840 | } | 1848 | } | |
1841 | 1849 | |||
1842 | #define q_lt(a, b) q_gt(b, a) | 1850 | #define q_lt(a, b) q_gt(b, a) | |
1843 | 1851 | |||
1844 | /* | 1852 | /* | |
1845 | * Gets a node for a constant and returns the value of this constant | 1853 | * Gets a node for a constant and returns the value of this constant | |
1846 | * as integer. | 1854 | * as integer. | |
1847 | * Is the node not constant or too large for int or of type float, | 1855 | * Is the node not constant or too large for int or of type float, | |
1848 | * a warning will be printed. | 1856 | * a warning will be printed. | |
1849 | * | 1857 | * | |
1850 | * toicon() should be used only inside declarations. If it is used in | 1858 | * toicon() should be used only inside declarations. If it is used in | |
1851 | * expressions, it frees the memory used for the expression. | 1859 | * expressions, it frees the memory used for the expression. | |
1852 | */ | 1860 | */ | |
1853 | static int | 1861 | static int | |
1854 | toicon(tnode_t *tn, int required) | 1862 | toicon(tnode_t *tn, int required) | |
1855 | { | 1863 | { | |
1856 | int i; | 1864 | int i; | |
1857 | tspec_t t; | 1865 | tspec_t t; | |
1858 | val_t *v; | 1866 | val_t *v; | |
1859 | 1867 | |||
1860 | v = constant(tn, required); | 1868 | v = constant(tn, required); | |
1861 | 1869 | |||
1862 | /* | 1870 | /* | |
1863 | * Abstract declarations are used inside expression. To free | 1871 | * Abstract declarations are used inside expression. To free | |
1864 | * the memory would be a fatal error. | 1872 | * the memory would be a fatal error. | |
1865 | */ | 1873 | */ | |
1866 | if (dcs->d_ctx != ABSTRACT) | 1874 | if (dcs->d_ctx != ABSTRACT) | |
1867 | tfreeblk(); | 1875 | tfreeblk(); | |
1868 | 1876 | |||
1869 | if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) { | 1877 | if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) { | |
1870 | i = (int)v->v_ldbl; | 1878 | i = (int)v->v_ldbl; | |
1871 | /* integral constant expression expected */ | 1879 | /* integral constant expression expected */ | |
1872 | error(55); | 1880 | error(55); | |
1873 | } else { | 1881 | } else { | |
1874 | i = (int)v->v_quad; | 1882 | i = (int)v->v_quad; | |
1875 | if (isutyp(t)) { | 1883 | if (isutyp(t)) { | |
1876 | if (uq_gt((uint64_t)v->v_quad, | 1884 | if (uq_gt((uint64_t)v->v_quad, | |
1877 | (uint64_t)TARG_INT_MAX)) { | 1885 | (uint64_t)TARG_INT_MAX)) { | |
1878 | /* integral constant too large */ | 1886 | /* integral constant too large */ | |
1879 | warning(56); | 1887 | warning(56); | |
1880 | } | 1888 | } | |
1881 | } else { | 1889 | } else { | |
1882 | if (q_gt(v->v_quad, (int64_t)TARG_INT_MAX) || | 1890 | if (q_gt(v->v_quad, (int64_t)TARG_INT_MAX) || | |
1883 | q_lt(v->v_quad, (int64_t)TARG_INT_MIN)) { | 1891 | q_lt(v->v_quad, (int64_t)TARG_INT_MIN)) { | |
1884 | /* integral constant too large */ | 1892 | /* integral constant too large */ | |
1885 | warning(56); | 1893 | warning(56); | |
1886 | } | 1894 | } | |
1887 | } | 1895 | } | |
1888 | } | 1896 | } | |
1889 | free(v); | 1897 | free(v); | |
1890 | return (i); | 1898 | return (i); | |
1891 | } | 1899 | } | |
1892 | 1900 | |||
1893 | static void | 1901 | static void | |
1894 | idecl(sym_t *decl, int initflg, sbuf_t *renaming) | 1902 | idecl(sym_t *decl, int initflg, sbuf_t *renaming) | |
1895 | { | 1903 | { | |
1896 | char *s; | 1904 | char *s; | |
1897 | 1905 | |||
1898 | initerr = 0; | 1906 | initerr = 0; | |
1899 | initsym = decl; | 1907 | initsym = decl; | |
1900 | 1908 | |||
1901 | switch (dcs->d_ctx) { | 1909 | switch (dcs->d_ctx) { | |
1902 | case EXTERN: | 1910 | case EXTERN: | |
1903 | if (renaming != NULL) { | 1911 | if (renaming != NULL) { | |
1904 | if (decl->s_rename != NULL) | 1912 | if (decl->s_rename != NULL) | |
1905 | LERROR("idecl()"); | 1913 | LERROR("idecl()"); | |
1906 | 1914 | |||
1907 | s = getlblk(1, renaming->sb_len + 1); | 1915 | s = getlblk(1, renaming->sb_len + 1); | |
1908 | (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1); | 1916 | (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1); | |
1909 | decl->s_rename = s; | 1917 | decl->s_rename = s; | |
1910 | freeyyv(&renaming, T_NAME); | 1918 | freeyyv(&renaming, T_NAME); | |
1911 | } | 1919 | } | |
1912 | decl1ext(decl, initflg); | 1920 | decl1ext(decl, initflg); | |
1913 | break; | 1921 | break; | |
1914 | case ARG: | 1922 | case ARG: | |
1915 | if (renaming != NULL) { | 1923 | if (renaming != NULL) { | |
1916 | /* symbol renaming can't be used on function arguments */ | 1924 | /* symbol renaming can't be used on function arguments */ | |
1917 | error(310); | 1925 | error(310); | |
1918 | freeyyv(&renaming, T_NAME); | 1926 | freeyyv(&renaming, T_NAME); | |
1919 | break; | 1927 | break; | |
1920 | } | 1928 | } | |
1921 | (void)decl1arg(decl, initflg); | 1929 | (void)decl1arg(decl, initflg); | |
1922 | break; | 1930 | break; | |
1923 | case AUTO: | 1931 | case AUTO: | |
1924 | if (renaming != NULL) { | 1932 | if (renaming != NULL) { | |
1925 | /* symbol renaming can't be used on automatic variables */ | 1933 | /* symbol renaming can't be used on automatic variables */ | |
1926 | error(311); | 1934 | error(311); | |
1927 | freeyyv(&renaming, T_NAME); | 1935 | freeyyv(&renaming, T_NAME); | |
1928 | break; | 1936 | break; | |
1929 | } | 1937 | } | |
1930 | decl1loc(decl, initflg); | 1938 | decl1loc(decl, initflg); | |
1931 | break; | 1939 | break; | |
1932 | default: | 1940 | default: | |
1933 | LERROR("idecl()"); | 1941 | LERROR("idecl()"); | |
1934 | } | 1942 | } | |
1935 | 1943 | |||
1936 | if (initflg && !initerr) | 1944 | if (initflg && !initerr) | |
1937 | prepinit(); | 1945 | prepinit(); | |
1938 | } | 1946 | } | |
1939 | 1947 | |||
1940 | /* | 1948 | /* | |
1941 | * Discard all input tokens up to and including the next | 1949 | * Discard all input tokens up to and including the next | |
1942 | * unmatched right paren | 1950 | * unmatched right paren | |
1943 | */ | 1951 | */ | |
1944 | static void | 1952 | static void | |
1945 | ignuptorp(void) | 1953 | ignuptorp(void) | |
1946 | { | 1954 | { | |
1947 | int level; | 1955 | int level; | |
1948 | 1956 | |||
1949 | if (yychar < 0) | 1957 | if (yychar < 0) | |
1950 | yychar = yylex(); | 1958 | yychar = yylex(); | |
1951 | freeyyv(&yylval, yychar); | 1959 | freeyyv(&yylval, yychar); | |
1952 | 1960 | |||
1953 | level = 1; | 1961 | level = 1; | |
1954 | while (yychar != T_RPARN || --level > 0) { | 1962 | while (yychar != T_RPARN || --level > 0) { | |
1955 | if (yychar == T_LPARN) { | 1963 | if (yychar == T_LPARN) { | |
1956 | level++; | 1964 | level++; | |
1957 | } else if (yychar <= 0) { | 1965 | } else if (yychar <= 0) { | |
1958 | break; | 1966 | break; | |
1959 | } | 1967 | } | |
1960 | freeyyv(&yylval, yychar = yylex()); | 1968 | freeyyv(&yylval, yychar = yylex()); | |
1961 | } | 1969 | } | |
1962 | 1970 | |||
1963 | yyclearin; | 1971 | yyclearin; | |
1964 | } | 1972 | } |
--- src/usr.bin/xlint/lint1/err.c 2013/04/19 17:43:05 1.46
+++ src/usr.bin/xlint/lint1/err.c 2014/02/18 22:01:36 1.47
@@ -1,563 +1,563 @@ | @@ -1,563 +1,563 @@ | |||
1 | /* $NetBSD: err.c,v 1.46 2013/04/19 17:43:05 christos Exp $ */ | 1 | /* $NetBSD: err.c,v 1.47 2014/02/18 22:01:36 christos Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | 4 | * Copyright (c) 1994, 1995 Jochen Pohl | |
5 | * All Rights Reserved. | 5 | * All Rights Reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
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: err.c,v 1.46 2013/04/19 17:43:05 christos Exp $"); | 40 | __RCSID("$NetBSD: err.c,v 1.47 2014/02/18 22:01:36 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | 42 | |||
43 | #include <sys/types.h> | 43 | #include <sys/types.h> | |
44 | #include <stdlib.h> | 44 | #include <stdlib.h> | |
45 | #include <stdarg.h> | 45 | #include <stdarg.h> | |
46 | 46 | |||
47 | #include "lint1.h" | 47 | #include "lint1.h" | |
48 | 48 | |||
49 | /* number of errors found */ | 49 | /* number of errors found */ | |
50 | int nerr; | 50 | int nerr; | |
51 | 51 | |||
52 | /* number of syntax errors */ | 52 | /* number of syntax errors */ | |
53 | int sytxerr; | 53 | int sytxerr; | |
54 | 54 | |||
55 | 55 | |||
56 | static const char *lbasename(const char *); | 56 | static const char *lbasename(const char *); | |
57 | static void verror(int, va_list); | 57 | static void verror(int, va_list); | |
58 | static void vwarning(int, va_list); | 58 | static void vwarning(int, va_list); | |
59 | 59 | |||
60 | 60 | |||
61 | const char *msgs[] = { | 61 | const char *msgs[] = { | |
62 | "empty declaration", /* 0 */ | 62 | "empty declaration", /* 0 */ | |
63 | "old style declaration; add int", /* 1 */ | 63 | "old style declaration; add int", /* 1 */ | |
64 | "empty declaration", /* 2 */ | 64 | "empty declaration", /* 2 */ | |
65 | "%s declared in argument declaration list", /* 3 */ | 65 | "%s declared in argument declaration list", /* 3 */ | |
66 | "illegal type combination", /* 4 */ | 66 | "illegal type combination", /* 4 */ | |
67 | "modifying typedef with '%s'; only qualifiers allowed", /* 5 */ | 67 | "modifying typedef with '%s'; only qualifiers allowed", /* 5 */ | |
68 | "use 'double' instead of 'long float'", /* 6 */ | 68 | "use 'double' instead of 'long float'", /* 6 */ | |
69 | "only one storage class allowed", /* 7 */ | 69 | "only one storage class allowed", /* 7 */ | |
70 | "illegal storage class", /* 8 */ | 70 | "illegal storage class", /* 8 */ | |
71 | "only register valid as formal parameter storage class", /* 9 */ | 71 | "only register valid as formal parameter storage class", /* 9 */ | |
72 | "duplicate '%s'", /* 10 */ | 72 | "duplicate '%s'", /* 10 */ | |
73 | "bit-field initializer out of range", /* 11 */ | 73 | "bit-field initializer out of range", /* 11 */ | |
74 | "compiler takes size of function", /* 12 */ | 74 | "compiler takes size of function", /* 12 */ | |
75 | "incomplete enum type: %s", /* 13 */ | 75 | "incomplete enum type: %s", /* 13 */ | |
76 | "compiler takes alignment of function", /* 14 */ | 76 | "compiler takes alignment of function", /* 14 */ | |
77 | "function returns illegal type", /* 15 */ | 77 | "function returns illegal type", /* 15 */ | |
78 | "array of function is illegal", /* 16 */ | 78 | "array of function is illegal", /* 16 */ | |
79 | "null dimension", /* 17 */ | 79 | "null dimension", /* 17 */ | |
80 | "illegal use of 'void'", /* 18 */ | 80 | "illegal use of 'void'", /* 18 */ | |
81 | "void type for %s", /* 19 */ | 81 | "void type for %s", /* 19 */ | |
82 | "negative array dimension (%d)", /* 20 */ | 82 | "negative array dimension (%d)", /* 20 */ | |
83 | "redeclaration of formal parameter %s", /* 21 */ | 83 | "redeclaration of formal parameter %s", /* 21 */ | |
84 | "incomplete or misplaced function definition", /* 22 */ | 84 | "incomplete or misplaced function definition", /* 22 */ | |
85 | "undefined label %s", /* 23 */ | 85 | "undefined label %s", /* 23 */ | |
86 | "cannot initialize function: %s", /* 24 */ | 86 | "cannot initialize function: %s", /* 24 */ | |
87 | "cannot initialize typedef: %s", /* 25 */ | 87 | "cannot initialize typedef: %s", /* 25 */ | |
88 | "cannot initialize extern declaration: %s", /* 26 */ | 88 | "cannot initialize extern declaration: %s", /* 26 */ | |
89 | "redeclaration of %s", /* 27 */ | 89 | "redeclaration of %s", /* 27 */ | |
90 | "redefinition of %s", /* 28 */ | 90 | "redefinition of %s", /* 28 */ | |
91 | "previously declared extern, becomes static: %s", /* 29 */ | 91 | "previously declared extern, becomes static: %s", /* 29 */ | |
92 | "redeclaration of %s; ANSI C requires static", /* 30 */ | 92 | "redeclaration of %s; ANSI C requires static", /* 30 */ | |
93 | "incomplete structure or union %s: %s", /* 31 */ | 93 | "incomplete structure or union %s: %s", /* 31 */ | |
94 | "argument type defaults to 'int': %s", /* 32 */ | 94 | "argument type defaults to 'int': %s", /* 32 */ | |
95 | "duplicate member name: %s", /* 33 */ | 95 | "duplicate member name: %s", /* 33 */ | |
96 | "nonportable bit-field type", /* 34 */ | 96 | "nonportable bit-field type", /* 34 */ | |
97 | "illegal bit-field type", /* 35 */ | 97 | "illegal bit-field type", /* 35 */ | |
98 | "illegal bit-field size", /* 36 */ | 98 | "illegal bit-field size", /* 36 */ | |
99 | "zero size bit-field", /* 37 */ | 99 | "zero size bit-field", /* 37 */ | |
100 | "function illegal in structure or union", /* 38 */ | 100 | "function illegal in structure or union", /* 38 */ | |
101 | "zero sized array in struct is a C99 extension: %s", /* 39 */ | 101 | "zero sized array in struct is a C99 extension: %s", /* 39 */ | |
102 | "unknown size: %s", /* 40 */ | 102 | "unknown size: %s", /* 40 */ | |
103 | "illegal use of bit-field", /* 41 */ | 103 | "illegal use of bit-field", /* 41 */ | |
104 | "forward reference to enum type", /* 42 */ | 104 | "forward reference to enum type", /* 42 */ | |
105 | "redefinition hides earlier one: %s", /* 43 */ | 105 | "redefinition hides earlier one: %s", /* 43 */ | |
106 | "declaration introduces new type in ANSI C: %s %s", /* 44 */ | 106 | "declaration introduces new type in ANSI C: %s %s", /* 44 */ | |
107 | "base type is really '%s %s'", /* 45 */ | 107 | "base type is really '%s %s'", /* 45 */ | |
108 | "(%s) tag redeclared", /* 46 */ | 108 | "(%s) tag redeclared", /* 46 */ | |
109 | "zero sized %s is a C9X feature", /* 47 */ | 109 | "zero sized %s is a C9X feature", /* 47 */ | |
110 | "overflow in enumeration values: %s", /* 48 */ | 110 | "overflow in enumeration values: %s", /* 48 */ | |
111 | "struct or union member must be named", /* 49 */ | 111 | "struct or union member must be named", /* 49 */ | |
112 | "a function is declared as an argument: %s", /* 50 */ | 112 | "a function is declared as an argument: %s", /* 50 */ | |
113 | "parameter mismatch: %d declared, %d defined", /* 51 */ | 113 | "parameter mismatch: %d declared, %d defined", /* 51 */ | |
114 | "cannot initialize parameter: %s", /* 52 */ | 114 | "cannot initialize parameter: %s", /* 52 */ | |
115 | "declared argument %s is missing", /* 53 */ | 115 | "declared argument %s is missing", /* 53 */ | |
116 | "trailing ',' prohibited in enum declaration", /* 54 */ | 116 | "trailing ',' prohibited in enum declaration", /* 54 */ | |
117 | "integral constant expression expected", /* 55 */ | 117 | "integral constant expression expected", /* 55 */ | |
118 | "integral constant too large", /* 56 */ | 118 | "integral constant too large", /* 56 */ | |
119 | "enumeration constant hides parameter: %s", /* 57 */ | 119 | "enumeration constant hides parameter: %s", /* 57 */ | |
120 | "type does not match prototype: %s", /* 58 */ | 120 | "type does not match prototype: %s", /* 58 */ | |
121 | "formal parameter lacks name: param #%d", /* 59 */ | 121 | "formal parameter lacks name: param #%d", /* 59 */ | |
122 | "void must be sole parameter", /* 60 */ | 122 | "void must be sole parameter", /* 60 */ | |
123 | "void parameter cannot have name: %s", /* 61 */ | 123 | "void parameter cannot have name: %s", /* 61 */ | |
124 | "function prototype parameters must have types", /* 62 */ | 124 | "function prototype parameters must have types", /* 62 */ | |
125 | "prototype does not match old-style definition", /* 63 */ | 125 | "prototype does not match old-style definition", /* 63 */ | |
126 | "()-less function definition", /* 64 */ | 126 | "()-less function definition", /* 64 */ | |
127 | "%s has no named members", /* 65 */ | 127 | "%s has no named members", /* 65 */ | |
128 | "syntax requires ';' after last struct/union member", /* 66 */ | 128 | "syntax requires ';' after last struct/union member", /* 66 */ | |
129 | "cannot return incomplete type", /* 67 */ | 129 | "cannot return incomplete type", /* 67 */ | |
130 | "typedef already qualified with '%s'", /* 68 */ | 130 | "typedef already qualified with '%s'", /* 68 */ | |
131 | "inappropriate qualifiers with 'void'", /* 69 */ | 131 | "inappropriate qualifiers with 'void'", /* 69 */ | |
132 | "%soperand of '%s' is unsigned in ANSI C", /* 70 */ | 132 | "%soperand of '%s' is unsigned in ANSI C", /* 70 */ | |
133 | "too many characters in character constant", /* 71 */ | 133 | "too many characters in character constant", /* 71 */ | |
134 | "typedef declares no type name", /* 72 */ | 134 | "typedef declares no type name", /* 72 */ | |
135 | "empty character constant", /* 73 */ | 135 | "empty character constant", /* 73 */ | |
136 | "no hex digits follow \\x", /* 74 */ | 136 | "no hex digits follow \\x", /* 74 */ | |
137 | "overflow in hex escape", /* 75 */ | 137 | "overflow in hex escape", /* 75 */ | |
138 | "character escape does not fit in character", /* 76 */ | 138 | "character escape does not fit in character", /* 76 */ | |
139 | "bad octal digit %c", /* 77 */ | 139 | "bad octal digit %c", /* 77 */ | |
140 | "nonportable character escape", /* 78 */ | 140 | "nonportable character escape", /* 78 */ | |
141 | "dubious escape \\%c", /* 79 */ | 141 | "dubious escape \\%c", /* 79 */ | |
142 | "dubious escape \\%o", /* 80 */ | 142 | "dubious escape \\%o", /* 80 */ | |
143 | "\\a undefined in traditional C", /* 81 */ | 143 | "\\a undefined in traditional C", /* 81 */ | |
144 | "\\x undefined in traditional C", /* 82 */ | 144 | "\\x undefined in traditional C", /* 82 */ | |
145 | "storage class after type is obsolescent", /* 83 */ | 145 | "storage class after type is obsolescent", /* 83 */ | |
146 | "ANSI C requires formal parameter before '...'", /* 84 */ | 146 | "ANSI C requires formal parameter before '...'", /* 84 */ | |
147 | "dubious tag declaration: %s %s", /* 85 */ | 147 | "dubious tag declaration: %s %s", /* 85 */ | |
148 | "automatic hides external declaration: %s", /* 86 */ | 148 | "automatic hides external declaration: %s", /* 86 */ | |
149 | "static hides external declaration: %s", /* 87 */ | 149 | "static hides external declaration: %s", /* 87 */ | |
150 | "typedef hides external declaration: %s", /* 88 */ | 150 | "typedef hides external declaration: %s", /* 88 */ | |
151 | "typedef redeclared: %s", /* 89 */ | 151 | "typedef redeclared: %s", /* 89 */ | |
152 | "inconsistent redeclaration of extern: %s", /* 90 */ | 152 | "inconsistent redeclaration of extern: %s", /* 90 */ | |
153 | "declaration hides parameter: %s", /* 91 */ | 153 | "declaration hides parameter: %s", /* 91 */ | |
154 | "inconsistent redeclaration of static: %s", /* 92 */ | 154 | "inconsistent redeclaration of static: %s", /* 92 */ | |
155 | "dubious static function at block level: %s", /* 93 */ | 155 | "dubious static function at block level: %s", /* 93 */ | |
156 | "function has illegal storage class: %s", /* 94 */ | 156 | "function has illegal storage class: %s", /* 94 */ | |
157 | "declaration hides earlier one: %s", /* 95 */ | 157 | "declaration hides earlier one: %s", /* 95 */ | |
158 | "cannot dereference non-pointer type", /* 96 */ | 158 | "cannot dereference non-pointer type", /* 96 */ | |
159 | "suffix U is illegal in traditional C", /* 97 */ | 159 | "suffix U is illegal in traditional C", /* 97 */ | |
160 | "suffixes F and L are illegal in traditional C", /* 98 */ | 160 | "suffixes F and L are illegal in traditional C", /* 98 */ | |
161 | "%s undefined", /* 99 */ | 161 | "%s undefined", /* 99 */ | |
162 | "unary + is illegal in traditional C", /* 100 */ | 162 | "unary + is illegal in traditional C", /* 100 */ | |
163 | "undefined struct/union member: %s", /* 101 */ | 163 | "undefined struct/union member: %s", /* 101 */ | |
164 | "illegal member use: %s", /* 102 */ | 164 | "illegal member use: %s", /* 102 */ | |
165 | "left operand of '.' must be struct/union object", /* 103 */ | 165 | "left operand of '.' must be struct/union object", /* 103 */ | |
166 | "left operand of '->' must be pointer to struct/union", /* 104 */ | 166 | "left operand of '->' must be pointer to struct/union", /* 104 */ | |
167 | "non-unique member requires struct/union %s", /* 105 */ | 167 | "non-unique member requires struct/union %s", /* 105 */ | |
168 | "left operand of '->' must be pointer", /* 106 */ | 168 | "left operand of '->' must be pointer", /* 106 */ | |
169 | "operands of '%s' have incompatible types (%s != %s)", /* 107 */ | 169 | "operands of '%s' have incompatible types (%s != %s)", /* 107 */ | |
170 | "operand of '%s' has incompatible type (%s != %s)", /* 108 */ | 170 | "operand of '%s' has incompatible type (%s != %s)", /* 108 */ | |
171 | "void type illegal in expression", /* 109 */ | 171 | "void type illegal in expression", /* 109 */ | |
172 | "pointer to function is not allowed here", /* 110 */ | 172 | "pointer to function is not allowed here", /* 110 */ | |
173 | "unacceptable operand of '%s'", /* 111 */ | 173 | "unacceptable operand of '%s'", /* 111 */ | |
174 | "cannot take address of bit-field", /* 112 */ | 174 | "cannot take address of bit-field", /* 112 */ | |
175 | "cannot take address of register %s", /* 113 */ | 175 | "cannot take address of register %s", /* 113 */ | |
176 | "%soperand of '%s' must be lvalue", /* 114 */ | 176 | "%soperand of '%s' must be lvalue", /* 114 */ | |
177 | "%soperand of '%s' must be modifiable lvalue", /* 115 */ | 177 | "%soperand of '%s' must be modifiable lvalue", /* 115 */ | |
178 | "illegal pointer subtraction", /* 116 */ | 178 | "illegal pointer subtraction", /* 116 */ | |
179 | "bitwise operation on signed value possibly nonportable", /* 117 */ | 179 | "bitwise operation on signed value possibly nonportable", /* 117 */ | |
180 | "semantics of '%s' change in ANSI C; use explicit cast", /* 118 */ | 180 | "semantics of '%s' change in ANSI C; use explicit cast", /* 118 */ | |
181 | "conversion of '%s' to '%s' is out of range", /* 119 */ | 181 | "conversion of '%s' to '%s' is out of range", /* 119 */ | |
182 | "bitwise operation on signed value nonportable", /* 120 */ | 182 | "bitwise operation on signed value nonportable", /* 120 */ | |
183 | "negative shift", /* 121 */ | 183 | "negative shift", /* 121 */ | |
184 | "shift greater than size of object", /* 122 */ | 184 | "shift greater than size of object", /* 122 */ | |
185 | "illegal combination of pointer and integer, op %s", /* 123 */ | 185 | "illegal combination of pointer and integer, op %s", /* 123 */ | |
186 | "illegal pointer combination, op %s", /* 124 */ | 186 | "illegal pointer combination, op %s", /* 124 */ | |
187 | "ANSI C forbids ordered comparisons of pointers to functions",/* 125 */ | 187 | "ANSI C forbids ordered comparisons of pointers to functions",/* 125 */ | |
188 | "incompatible types in conditional", /* 126 */ | 188 | "incompatible types in conditional", /* 126 */ | |
189 | "'&' before array or function: ignored", /* 127 */ | 189 | "'&' before array or function: ignored", /* 127 */ | |
190 | "operands have incompatible pointer types, op %s (%s != %s)", /* 128 */ | 190 | "operands have incompatible pointer types, op %s (%s != %s)", /* 128 */ | |
191 | "expression has null effect", /* 129 */ | 191 | "expression has null effect", /* 129 */ | |
192 | "enum type mismatch, op %s", /* 130 */ | 192 | "enum type mismatch, op %s", /* 130 */ | |
193 | "conversion to '%s' may sign-extend incorrectly", /* 131 */ | 193 | "conversion to '%s' may sign-extend incorrectly", /* 131 */ | |
194 | "conversion from '%s' to '%s' may lose accuracy", /* 132 */ | 194 | "conversion from '%s' to '%s' may lose accuracy", /* 132 */ | |
195 | "conversion of pointer to '%s' loses bits", /* 133 */ | 195 | "conversion of pointer to '%s' loses bits", /* 133 */ | |
196 | "conversion of pointer to '%s' may lose bits", /* 134 */ | 196 | "conversion of pointer to '%s' may lose bits", /* 134 */ | |
197 | "possible pointer alignment problem", /* 135 */ | 197 | "possible pointer alignment problem", /* 135 */ | |
198 | "cannot do pointer arithmetic on operand of unknown size", /* 136 */ | 198 | "cannot do pointer arithmetic on operand of unknown size", /* 136 */ | |
199 | "use of incomplete enum type, op %s", /* 137 */ | 199 | "use of incomplete enum type, op %s", /* 137 */ | |
200 | "unknown operand size, op %s", /* 138 */ | 200 | "unknown operand size, op %s", /* 138 */ | |
201 | "division by 0", /* 139 */ | 201 | "division by 0", /* 139 */ | |
202 | "modulus by 0", /* 140 */ | 202 | "modulus by 0", /* 140 */ | |
203 | "integer overflow detected, op %s", /* 141 */ | 203 | "integer overflow detected, op %s", /* 141 */ | |
204 | "floating point overflow detected, op %s", /* 142 */ | 204 | "floating point overflow detected, op %s", /* 142 */ | |
205 | "cannot take size/alignment of incomplete type", /* 143 */ | 205 | "cannot take size/alignment of incomplete type", /* 143 */ | |
206 | "cannot take size/alignment of function", /* 144 */ | 206 | "cannot take size/alignment of function", /* 144 */ | |
207 | "cannot take size/alignment of bit-field", /* 145 */ | 207 | "cannot take size/alignment of bit-field", /* 145 */ | |
208 | "cannot take size/alignment of void", /* 146 */ | 208 | "cannot take size/alignment of void", /* 146 */ | |
209 | "invalid cast expression", /* 147 */ | 209 | "invalid cast expression", /* 147 */ | |
210 | "improper cast of void expression", /* 148 */ | 210 | "improper cast of void expression", /* 148 */ | |
211 | "illegal function", /* 149 */ | 211 | "illegal function (type %s)", /* 149 */ | |
212 | "argument mismatch: %d arg%s passed, %d expected", /* 150 */ | 212 | "argument mismatch: %d arg%s passed, %d expected", /* 150 */ | |
213 | "void expressions may not be arguments, arg #%d", /* 151 */ | 213 | "void expressions may not be arguments, arg #%d", /* 151 */ | |
214 | "argument cannot have unknown size, arg #%d", /* 152 */ | 214 | "argument cannot have unknown size, arg #%d", /* 152 */ | |
215 | "argument has incompatible pointer type, arg #%d (%s != %s)", /* 153 */ | 215 | "argument has incompatible pointer type, arg #%d (%s != %s)", /* 153 */ | |
216 | "illegal combination of pointer and integer, arg #%d", /* 154 */ | 216 | "illegal combination of pointer and integer, arg #%d", /* 154 */ | |
217 | "argument is incompatible with prototype, arg #%d", /* 155 */ | 217 | "argument is incompatible with prototype, arg #%d", /* 155 */ | |
218 | "enum type mismatch, arg #%d", /* 156 */ | 218 | "enum type mismatch, arg #%d", /* 156 */ | |
219 | "ANSI C treats constant as unsigned", /* 157 */ | 219 | "ANSI C treats constant as unsigned", /* 157 */ | |
220 | "%s may be used before set", /* 158 */ | 220 | "%s may be used before set", /* 158 */ | |
221 | "assignment in conditional context", /* 159 */ | 221 | "assignment in conditional context", /* 159 */ | |
222 | "operator '==' found where '=' was expected", /* 160 */ | 222 | "operator '==' found where '=' was expected", /* 160 */ | |
223 | "constant in conditional context", /* 161 */ | 223 | "constant in conditional context", /* 161 */ | |
224 | "comparison of %s with %s, op %s", /* 162 */ | 224 | "comparison of %s with %s, op %s", /* 162 */ | |
225 | "a cast does not yield an lvalue", /* 163 */ | 225 | "a cast does not yield an lvalue", /* 163 */ | |
226 | "assignment of negative constant to unsigned type", /* 164 */ | 226 | "assignment of negative constant to unsigned type", /* 164 */ | |
227 | "constant truncated by assignment", /* 165 */ | 227 | "constant truncated by assignment", /* 165 */ | |
228 | "precision lost in bit-field assignment", /* 166 */ | 228 | "precision lost in bit-field assignment", /* 166 */ | |
229 | "array subscript cannot be negative: %ld", /* 167 */ | 229 | "array subscript cannot be negative: %ld", /* 167 */ | |
230 | "array subscript cannot be > %d: %ld", /* 168 */ | 230 | "array subscript cannot be > %d: %ld", /* 168 */ | |
231 | "precedence confusion possible: parenthesize!", /* 169 */ | 231 | "precedence confusion possible: parenthesize!", /* 169 */ | |
232 | "first operand must have scalar type, op ? :", /* 170 */ | 232 | "first operand must have scalar type, op ? :", /* 170 */ | |
233 | "assignment type mismatch (%s != %s)", /* 171 */ | 233 | "assignment type mismatch (%s != %s)", /* 171 */ | |
234 | "too many struct/union initializers", /* 172 */ | 234 | "too many struct/union initializers", /* 172 */ | |
235 | "too many array initializers, expected %d", /* 173 */ | 235 | "too many array initializers, expected %d", /* 173 */ | |
236 | "too many initializers", /* 174 */ | 236 | "too many initializers", /* 174 */ | |
237 | "initialisation of an incomplete type", /* 175 */ | 237 | "initialisation of an incomplete type", /* 175 */ | |
238 | "invalid initializer type %s", /* 176 */ | 238 | "invalid initializer type %s", /* 176 */ | |
239 | "non-constant initializer", /* 177 */ | 239 | "non-constant initializer", /* 177 */ | |
240 | "initializer does not fit", /* 178 */ | 240 | "initializer does not fit", /* 178 */ | |
241 | "cannot initialize struct/union with no named member", /* 179 */ | 241 | "cannot initialize struct/union with no named member", /* 179 */ | |
242 | "bit-field initializer does not fit", /* 180 */ | 242 | "bit-field initializer does not fit", /* 180 */ | |
243 | "{}-enclosed initializer required", /* 181 */ | 243 | "{}-enclosed initializer required", /* 181 */ | |
244 | "incompatible pointer types (%s != %s)", /* 182 */ | 244 | "incompatible pointer types (%s != %s)", /* 182 */ | |
245 | "illegal combination of pointer and integer", /* 183 */ | 245 | "illegal combination of pointer and integer", /* 183 */ | |
246 | "illegal pointer combination", /* 184 */ | 246 | "illegal pointer combination", /* 184 */ | |
247 | "initialisation type mismatch", /* 185 */ | 247 | "initialisation type mismatch", /* 185 */ | |
248 | "bit-field initialisation is illegal in traditional C", /* 186 */ | 248 | "bit-field initialisation is illegal in traditional C", /* 186 */ | |
249 | "non-null byte ignored in string initializer", /* 187 */ | 249 | "non-null byte ignored in string initializer", /* 187 */ | |
250 | "no automatic aggregate initialization in traditional C", /* 188 */ | 250 | "no automatic aggregate initialization in traditional C", /* 188 */ | |
251 | "assignment of struct/union illegal in traditional C", /* 189 */ | 251 | "assignment of struct/union illegal in traditional C", /* 189 */ | |
252 | "empty array declaration: %s", /* 190 */ | 252 | "empty array declaration: %s", /* 190 */ | |
253 | "%s set but not used in function %s", /* 191 */ | 253 | "%s set but not used in function %s", /* 191 */ | |
254 | "%s unused in function %s", /* 192 */ | 254 | "%s unused in function %s", /* 192 */ | |
255 | "statement not reached", /* 193 */ | 255 | "statement not reached", /* 193 */ | |
256 | "label %s redefined", /* 194 */ | 256 | "label %s redefined", /* 194 */ | |
257 | "case not in switch", /* 195 */ | 257 | "case not in switch", /* 195 */ | |
258 | "case label affected by conversion", /* 196 */ | 258 | "case label affected by conversion", /* 196 */ | |
259 | "non-constant case expression", /* 197 */ | 259 | "non-constant case expression", /* 197 */ | |
260 | "non-integral case expression", /* 198 */ | 260 | "non-integral case expression", /* 198 */ | |
261 | "duplicate case in switch: %ld", /* 199 */ | 261 | "duplicate case in switch: %ld", /* 199 */ | |
262 | "duplicate case in switch: %lu", /* 200 */ | 262 | "duplicate case in switch: %lu", /* 200 */ | |
263 | "default outside switch", /* 201 */ | 263 | "default outside switch", /* 201 */ | |
264 | "duplicate default in switch", /* 202 */ | 264 | "duplicate default in switch", /* 202 */ | |
265 | "case label must be of type `int' in traditional C", /* 203 */ | 265 | "case label must be of type `int' in traditional C", /* 203 */ | |
266 | "controlling expressions must have scalar type", /* 204 */ | 266 | "controlling expressions must have scalar type", /* 204 */ | |
267 | "switch expression must have integral type", /* 205 */ | 267 | "switch expression must have integral type", /* 205 */ | |
268 | "enumeration value(s) not handled in switch", /* 206 */ | 268 | "enumeration value(s) not handled in switch", /* 206 */ | |
269 | "loop not entered at top", /* 207 */ | 269 | "loop not entered at top", /* 207 */ | |
270 | "break outside loop or switch", /* 208 */ | 270 | "break outside loop or switch", /* 208 */ | |
271 | "continue outside loop", /* 209 */ | 271 | "continue outside loop", /* 209 */ | |
272 | "enum type mismatch in initialisation", /* 210 */ | 272 | "enum type mismatch in initialisation", /* 210 */ | |
273 | "return value type mismatch", /* 211 */ | 273 | "return value type mismatch", /* 211 */ | |
274 | "cannot return incomplete type", /* 212 */ | 274 | "cannot return incomplete type", /* 212 */ | |
275 | "void function %s cannot return value", /* 213 */ | 275 | "void function %s cannot return value", /* 213 */ | |
276 | "function %s expects to return value", /* 214 */ | 276 | "function %s expects to return value", /* 214 */ | |
277 | "function implicitly declared to return int", /* 215 */ | 277 | "function implicitly declared to return int", /* 215 */ | |
278 | "function %s has return (e); and return;", /* 216 */ | 278 | "function %s has return (e); and return;", /* 216 */ | |
279 | "function %s falls off bottom without returning value", /* 217 */ | 279 | "function %s falls off bottom without returning value", /* 217 */ | |
280 | "ANSI C treats constant as unsigned, op %s", /* 218 */ | 280 | "ANSI C treats constant as unsigned, op %s", /* 218 */ | |
281 | "concatenated strings are illegal in traditional C", /* 219 */ | 281 | "concatenated strings are illegal in traditional C", /* 219 */ | |
282 | "fallthrough on case statement", /* 220 */ | 282 | "fallthrough on case statement", /* 220 */ | |
283 | "initialisation of unsigned with negative constant", /* 221 */ | 283 | "initialisation of unsigned with negative constant", /* 221 */ | |
284 | "conversion of negative constant to unsigned type", /* 222 */ | 284 | "conversion of negative constant to unsigned type", /* 222 */ | |
285 | "end-of-loop code not reached", /* 223 */ | 285 | "end-of-loop code not reached", /* 223 */ | |
286 | "cannot recover from previous errors", /* 224 */ | 286 | "cannot recover from previous errors", /* 224 */ | |
287 | "static function called but not defined: %s()", /* 225 */ | 287 | "static function called but not defined: %s()", /* 225 */ | |
288 | "static variable %s unused", /* 226 */ | 288 | "static variable %s unused", /* 226 */ | |
289 | "const object %s should have initializer", /* 227 */ | 289 | "const object %s should have initializer", /* 227 */ | |
290 | "function cannot return const or volatile object", /* 228 */ | 290 | "function cannot return const or volatile object", /* 228 */ | |
291 | "questionable conversion of function pointer", /* 229 */ | 291 | "questionable conversion of function pointer", /* 229 */ | |
292 | "nonportable character comparison, op %s", /* 230 */ | 292 | "nonportable character comparison, op %s", /* 230 */ | |
293 | "argument %s unused in function %s", /* 231 */ | 293 | "argument %s unused in function %s", /* 231 */ | |
294 | "label %s unused in function %s", /* 232 */ | 294 | "label %s unused in function %s", /* 232 */ | |
295 | "struct %s never defined", /* 233 */ | 295 | "struct %s never defined", /* 233 */ | |
296 | "union %s never defined", /* 234 */ | 296 | "union %s never defined", /* 234 */ | |
297 | "enum %s never defined", /* 235 */ | 297 | "enum %s never defined", /* 235 */ | |
298 | "static function %s unused", /* 236 */ | 298 | "static function %s unused", /* 236 */ | |
299 | "redeclaration of formal parameter %s", /* 237 */ | 299 | "redeclaration of formal parameter %s", /* 237 */ | |
300 | "initialisation of union is illegal in traditional C", /* 238 */ | 300 | "initialisation of union is illegal in traditional C", /* 238 */ | |
301 | "constant argument to NOT", /* 239 */ | 301 | "constant argument to NOT", /* 239 */ | |
302 | "assignment of different structures (%s != %s)", /* 240 */ | 302 | "assignment of different structures (%s != %s)", /* 240 */ | |
303 | "dubious operation on enum, op %s", /* 241 */ | 303 | "dubious operation on enum, op %s", /* 241 */ | |
304 | "combination of '%s' and '%s', op %s", /* 242 */ | 304 | "combination of '%s' and '%s', op %s", /* 242 */ | |
305 | "dubious comparison of enums, op %s", /* 243 */ | 305 | "dubious comparison of enums, op %s", /* 243 */ | |
306 | "illegal structure pointer combination", /* 244 */ | 306 | "illegal structure pointer combination", /* 244 */ | |
307 | "illegal structure pointer combination, op %s", /* 245 */ | 307 | "illegal structure pointer combination, op %s", /* 245 */ | |
308 | "dubious conversion of enum to '%s'", /* 246 */ | 308 | "dubious conversion of enum to '%s'", /* 246 */ | |
309 | "pointer casts may be troublesome", /* 247 */ | 309 | "pointer casts may be troublesome", /* 247 */ | |
310 | "floating-point constant out of range", /* 248 */ | 310 | "floating-point constant out of range", /* 248 */ | |
311 | "syntax error '%s'", /* 249 */ | 311 | "syntax error '%s'", /* 249 */ | |
312 | "unknown character \\%o", /* 250 */ | 312 | "unknown character \\%o", /* 250 */ | |
313 | "malformed integer constant", /* 251 */ | 313 | "malformed integer constant", /* 251 */ | |
314 | "integer constant out of range", /* 252 */ | 314 | "integer constant out of range", /* 252 */ | |
315 | "unterminated character constant", /* 253 */ | 315 | "unterminated character constant", /* 253 */ | |
316 | "newline in string or char constant", /* 254 */ | 316 | "newline in string or char constant", /* 254 */ | |
317 | "undefined or invalid # directive", /* 255 */ | 317 | "undefined or invalid # directive", /* 255 */ | |
318 | "unterminated comment", /* 256 */ | 318 | "unterminated comment", /* 256 */ | |
319 | "extra characters in lint comment", /* 257 */ | 319 | "extra characters in lint comment", /* 257 */ | |
320 | "unterminated string constant", /* 258 */ | 320 | "unterminated string constant", /* 258 */ | |
321 | "conversion to '%s' due to prototype, arg #%d", /* 259 */ | 321 | "conversion to '%s' due to prototype, arg #%d", /* 259 */ | |
322 | "previous declaration of %s", /* 260 */ | 322 | "previous declaration of %s", /* 260 */ | |
323 | "previous definition of %s", /* 261 */ | 323 | "previous definition of %s", /* 261 */ | |
324 | "\\\" inside character constants undefined in traditional C", /* 262 */ | 324 | "\\\" inside character constants undefined in traditional C", /* 262 */ | |
325 | "\\? undefined in traditional C", /* 263 */ | 325 | "\\? undefined in traditional C", /* 263 */ | |
326 | "\\v undefined in traditional C", /* 264 */ | 326 | "\\v undefined in traditional C", /* 264 */ | |
327 | "%s C does not support 'long long'", /* 265 */ | 327 | "%s C does not support 'long long'", /* 265 */ | |
328 | "'long double' is illegal in traditional C", /* 266 */ | 328 | "'long double' is illegal in traditional C", /* 266 */ | |
329 | "shift equal to size of object", /* 267 */ | 329 | "shift equal to size of object", /* 267 */ | |
330 | "variable declared inline: %s", /* 268 */ | 330 | "variable declared inline: %s", /* 268 */ | |
331 | "argument declared inline: %s", /* 269 */ | 331 | "argument declared inline: %s", /* 269 */ | |
332 | "function prototypes are illegal in traditional C", /* 270 */ | 332 | "function prototypes are illegal in traditional C", /* 270 */ | |
333 | "switch expression must be of type `int' in traditional C", /* 271 */ | 333 | "switch expression must be of type `int' in traditional C", /* 271 */ | |
334 | "empty translation unit", /* 272 */ | 334 | "empty translation unit", /* 272 */ | |
335 | "bit-field type '%s' invalid in ANSI C", /* 273 */ | 335 | "bit-field type '%s' invalid in ANSI C", /* 273 */ | |
336 | "ANSI C forbids comparison of %s with %s", /* 274 */ | 336 | "ANSI C forbids comparison of %s with %s", /* 274 */ | |
337 | "cast discards 'const' from pointer target type", /* 275 */ | 337 | "cast discards 'const' from pointer target type", /* 275 */ | |
338 | "__%s__ is illegal for type %s", /* 276 */ | 338 | "__%s__ is illegal for type %s", /* 276 */ | |
339 | "initialisation of '%s' with '%s'", /* 277 */ | 339 | "initialisation of '%s' with '%s'", /* 277 */ | |
340 | "combination of '%s' and '%s', arg #%d", /* 278 */ | 340 | "combination of '%s' and '%s', arg #%d", /* 278 */ | |
341 | "combination of '%s' and '%s' in return", /* 279 */ | 341 | "combination of '%s' and '%s' in return", /* 279 */ | |
342 | "must be outside function: /* %s */", /* 280 */ | 342 | "must be outside function: /* %s */", /* 280 */ | |
343 | "duplicate use of /* %s */", /* 281 */ | 343 | "duplicate use of /* %s */", /* 281 */ | |
344 | "must precede function definition: /* %s */", /* 282 */ | 344 | "must precede function definition: /* %s */", /* 282 */ | |
345 | "argument number mismatch with directive: /* %s */", /* 283 */ | 345 | "argument number mismatch with directive: /* %s */", /* 283 */ | |
346 | "fallthrough on default statement", /* 284 */ | 346 | "fallthrough on default statement", /* 284 */ | |
347 | "prototype declaration", /* 285 */ | 347 | "prototype declaration", /* 285 */ | |
348 | "function definition is not a prototype", /* 286 */ | 348 | "function definition is not a prototype", /* 286 */ | |
349 | "function declaration is not a prototype", /* 287 */ | 349 | "function declaration is not a prototype", /* 287 */ | |
350 | "dubious use of /* VARARGS */ with /* %s */", /* 288 */ | 350 | "dubious use of /* VARARGS */ with /* %s */", /* 288 */ | |
351 | "can't be used together: /* PRINTFLIKE */ /* SCANFLIKE */", /* 289 */ | 351 | "can't be used together: /* PRINTFLIKE */ /* SCANFLIKE */", /* 289 */ | |
352 | "static function %s declared but not defined", /* 290 */ | 352 | "static function %s declared but not defined", /* 290 */ | |
353 | "invalid multibyte character", /* 291 */ | 353 | "invalid multibyte character", /* 291 */ | |
354 | "cannot concatenate wide and regular string literals", /* 292 */ | 354 | "cannot concatenate wide and regular string literals", /* 292 */ | |
355 | "argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE", /* 293 */ | 355 | "argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE", /* 293 */ | |
356 | "multi-character character constant", /* 294 */ | 356 | "multi-character character constant", /* 294 */ | |
357 | "conversion of '%s' to '%s' is out of range, arg #%d", /* 295 */ | 357 | "conversion of '%s' to '%s' is out of range, arg #%d", /* 295 */ | |
358 | "conversion of negative constant to unsigned type, arg #%d", /* 296 */ | 358 | "conversion of negative constant to unsigned type, arg #%d", /* 296 */ | |
359 | "conversion to '%s' may sign-extend incorrectly, arg #%d", /* 297 */ | 359 | "conversion to '%s' may sign-extend incorrectly, arg #%d", /* 297 */ | |
360 | "conversion from '%s' to '%s' may lose accuracy, arg #%d", /* 298 */ | 360 | "conversion from '%s' to '%s' may lose accuracy, arg #%d", /* 298 */ | |
361 | "prototype does not match old style definition, arg #%d", /* 299 */ | 361 | "prototype does not match old style definition, arg #%d", /* 299 */ | |
362 | "old style definition", /* 300 */ | 362 | "old style definition", /* 300 */ | |
363 | "array of incomplete type", /* 301 */ | 363 | "array of incomplete type", /* 301 */ | |
364 | "%s returns pointer to automatic object", /* 302 */ | 364 | "%s returns pointer to automatic object", /* 302 */ | |
365 | "ANSI C forbids conversion of %s to %s", /* 303 */ | 365 | "ANSI C forbids conversion of %s to %s", /* 303 */ | |
366 | "ANSI C forbids conversion of %s to %s, arg #%d", /* 304 */ | 366 | "ANSI C forbids conversion of %s to %s, arg #%d", /* 304 */ | |
367 | "ANSI C forbids conversion of %s to %s, op %s", /* 305 */ | 367 | "ANSI C forbids conversion of %s to %s, op %s", /* 305 */ | |
368 | "constant truncated by conversion, op %s", /* 306 */ | 368 | "constant truncated by conversion, op %s", /* 306 */ | |
369 | "static variable %s set but not used", /* 307 */ | 369 | "static variable %s set but not used", /* 307 */ | |
370 | "Invalid type %s for _Complex", /* 308 */ | 370 | "Invalid type %s for _Complex", /* 308 */ | |
371 | "extra bits set to 0 in conversion of '%s' to '%s', op %s", /* 309 */ | 371 | "extra bits set to 0 in conversion of '%s' to '%s', op %s", /* 309 */ | |
372 | "symbol renaming can't be used on function arguments", /* 310 */ | 372 | "symbol renaming can't be used on function arguments", /* 310 */ | |
373 | "symbol renaming can't be used on automatic variables", /* 311 */ | 373 | "symbol renaming can't be used on automatic variables", /* 311 */ | |
374 | "%s C does not support // comments", /* 312 */ | 374 | "%s C does not support // comments", /* 312 */ | |
375 | "struct or union member name in initializer is a C9X feature",/* 313 */ | 375 | "struct or union member name in initializer is a C9X feature",/* 313 */ | |
376 | "%s is not a structure or a union", /* 314 */ | 376 | "%s is not a structure or a union", /* 314 */ | |
377 | "GCC style struct or union member name in initializer", /* 315 */ | 377 | "GCC style struct or union member name in initializer", /* 315 */ | |
378 | "__FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension", /* 316 */ | 378 | "__FUNCTION__/__PRETTY_FUNCTION__ is a GCC extension", /* 316 */ | |
379 | "__func__ is a C9X feature", /* 317 */ | 379 | "__func__ is a C9X feature", /* 317 */ | |
380 | "variable array dimension is a C99/GCC extension", /* 318 */ | 380 | "variable array dimension is a C99/GCC extension", /* 318 */ | |
381 | "compound literals are a C9X/GCC extension", /* 319 */ | 381 | "compound literals are a C9X/GCC extension", /* 319 */ | |
382 | "({ }) is a GCC extension", /* 320 */ | 382 | "({ }) is a GCC extension", /* 320 */ | |
383 | "array initializer with designators is a C9X feature", /* 321 */ | 383 | "array initializer with designators is a C9X feature", /* 321 */ | |
384 | "zero sized array is a C99 extension", /* 322 */ | 384 | "zero sized array is a C99 extension", /* 322 */ | |
385 | "continue in 'do ... while (0)' loop", /* 323 */ | 385 | "continue in 'do ... while (0)' loop", /* 323 */ | |
386 | "suggest cast from '%s' to '%s' on op %s to avoid overflow", /* 324 */ | 386 | "suggest cast from '%s' to '%s' on op %s to avoid overflow", /* 324 */ | |
387 | "variable declaration in for loop", /* 325 */ | 387 | "variable declaration in for loop", /* 325 */ | |
388 | "%s attribute ignored for %s", /* 326 */ | 388 | "%s attribute ignored for %s", /* 326 */ | |
389 | "declarations after statements is a C9X feature", /* 327 */ | 389 | "declarations after statements is a C9X feature", /* 327 */ | |
390 | }; | 390 | }; | |
391 | 391 | |||
392 | /* | 392 | /* | |
393 | * print a list of the messages with their ids | 393 | * print a list of the messages with their ids | |
394 | */ | 394 | */ | |
395 | void | 395 | void | |
396 | msglist(void) | 396 | msglist(void) | |
397 | { | 397 | { | |
398 | size_t i; | 398 | size_t i; | |
399 | 399 | |||
400 | for (i = 0; i < sizeof(msgs) / sizeof(msgs[0]); i++) | 400 | for (i = 0; i < sizeof(msgs) / sizeof(msgs[0]); i++) | |
401 | printf("%zu\t%s\n", i, msgs[i]); | 401 | printf("%zu\t%s\n", i, msgs[i]); | |
402 | } | 402 | } | |
403 | 403 | |||
404 | /* | 404 | /* | |
405 | * If Fflag is not set lbasename() returns a pointer to the last | 405 | * If Fflag is not set lbasename() returns a pointer to the last | |
406 | * component of the path, otherwise it returns the argument. | 406 | * component of the path, otherwise it returns the argument. | |
407 | */ | 407 | */ | |
408 | static const char * | 408 | static const char * | |
409 | lbasename(const char *path) | 409 | lbasename(const char *path) | |
410 | { | 410 | { | |
411 | const char *cp, *cp1, *cp2; | 411 | const char *cp, *cp1, *cp2; | |
412 | 412 | |||
413 | if (Fflag) | 413 | if (Fflag) | |
414 | return (path); | 414 | return (path); | |
415 | 415 | |||
416 | cp = cp1 = cp2 = path; | 416 | cp = cp1 = cp2 = path; | |
417 | while (*cp != '\0') { | 417 | while (*cp != '\0') { | |
418 | if (*cp++ == '/') { | 418 | if (*cp++ == '/') { | |
419 | cp2 = cp1; | 419 | cp2 = cp1; | |
420 | cp1 = cp; | 420 | cp1 = cp; | |
421 | } | 421 | } | |
422 | } | 422 | } | |
423 | return (*cp1 == '\0' ? cp2 : cp1); | 423 | return (*cp1 == '\0' ? cp2 : cp1); | |
424 | } | 424 | } | |
425 | 425 | |||
426 | static void | 426 | static void | |
427 | verror( int n, va_list ap) | 427 | verror( int n, va_list ap) | |
428 | { | 428 | { | |
429 | const char *fn; | 429 | const char *fn; | |
430 | 430 | |||
431 | if (ERR_ISSET(n, &msgset)) | 431 | if (ERR_ISSET(n, &msgset)) | |
432 | return; | 432 | return; | |
433 | 433 | |||
434 | fn = lbasename(curr_pos.p_file); | 434 | fn = lbasename(curr_pos.p_file); | |
435 | (void)printf("%s(%d): ", fn, curr_pos.p_line); | 435 | (void)printf("%s(%d): ", fn, curr_pos.p_line); | |
436 | (void)vprintf(msgs[n], ap); | 436 | (void)vprintf(msgs[n], ap); | |
437 | (void)printf(" [%d]\n", n); | 437 | (void)printf(" [%d]\n", n); | |
438 | nerr++; | 438 | nerr++; | |
439 | } | 439 | } | |
440 | 440 | |||
441 | static void | 441 | static void | |
442 | vwarning(int n, va_list ap) | 442 | vwarning(int n, va_list ap) | |
443 | { | 443 | { | |
444 | const char *fn; | 444 | const char *fn; | |
445 | 445 | |||
446 | if (ERR_ISSET(n, &msgset)) | 446 | if (ERR_ISSET(n, &msgset)) | |
447 | return; | 447 | return; | |
448 | 448 | |||
449 | #ifdef DEBUG | 449 | #ifdef DEBUG | |
450 | printf("%s: lwarn=%d n=%d\n", __func__, lwarn, n); | 450 | printf("%s: lwarn=%d n=%d\n", __func__, lwarn, n); | |
451 | #endif | 451 | #endif | |
452 | if (lwarn == LWARN_NONE || lwarn == n) | 452 | if (lwarn == LWARN_NONE || lwarn == n) | |
453 | /* this warning is suppressed by a LINTED comment */ | 453 | /* this warning is suppressed by a LINTED comment */ | |
454 | return; | 454 | return; | |
455 | 455 | |||
456 | fn = lbasename(curr_pos.p_file); | 456 | fn = lbasename(curr_pos.p_file); | |
457 | (void)printf("%s(%d): warning: ", fn, curr_pos.p_line); | 457 | (void)printf("%s(%d): warning: ", fn, curr_pos.p_line); | |
458 | (void)vprintf(msgs[n], ap); | 458 | (void)vprintf(msgs[n], ap); | |
459 | (void)printf(" [%d]\n", n); | 459 | (void)printf(" [%d]\n", n); | |
460 | if (wflag) | 460 | if (wflag) | |
461 | nerr++; | 461 | nerr++; | |
462 | } | 462 | } | |
463 | 463 | |||
464 | void | 464 | void | |
465 | error(int n, ...) | 465 | error(int n, ...) | |
466 | { | 466 | { | |
467 | va_list ap; | 467 | va_list ap; | |
468 | 468 | |||
469 | va_start(ap, n); | 469 | va_start(ap, n); | |
470 | verror(n, ap); | 470 | verror(n, ap); | |
471 | va_end(ap); | 471 | va_end(ap); | |
472 | } | 472 | } | |
473 | 473 | |||
474 | void | 474 | void | |
475 | lerror(const char *file, int line, const char *msg, ...) | 475 | lerror(const char *file, int line, const char *msg, ...) | |
476 | { | 476 | { | |
477 | va_list ap; | 477 | va_list ap; | |
478 | const char *fn; | 478 | const char *fn; | |
479 | 479 | |||
480 | va_start(ap, msg); | 480 | va_start(ap, msg); | |
481 | fn = lbasename(curr_pos.p_file); | 481 | fn = lbasename(curr_pos.p_file); | |
482 | (void)fprintf(stderr, "%s(%d): lint error: %s, %d: ", | 482 | (void)fprintf(stderr, "%s(%d): lint error: %s, %d: ", | |
483 | fn, curr_pos.p_line, file, line); | 483 | fn, curr_pos.p_line, file, line); | |
484 | (void)vfprintf(stderr, msg, ap); | 484 | (void)vfprintf(stderr, msg, ap); | |
485 | (void)fprintf(stderr, "\n"); | 485 | (void)fprintf(stderr, "\n"); | |
486 | va_end(ap); | 486 | va_end(ap); | |
487 | abort(); | 487 | abort(); | |
488 | } | 488 | } | |
489 | 489 | |||
490 | void | 490 | void | |
491 | warning(int n, ...) | 491 | warning(int n, ...) | |
492 | { | 492 | { | |
493 | va_list ap; | 493 | va_list ap; | |
494 | 494 | |||
495 | va_start(ap, n); | 495 | va_start(ap, n); | |
496 | vwarning(n, ap); | 496 | vwarning(n, ap); | |
497 | va_end(ap); | 497 | va_end(ap); | |
498 | } | 498 | } | |
499 | 499 | |||
500 | void | 500 | void | |
501 | message(int n, ...) | 501 | message(int n, ...) | |
502 | { | 502 | { | |
503 | va_list ap; | 503 | va_list ap; | |
504 | const char *fn; | 504 | const char *fn; | |
505 | 505 | |||
506 | if (ERR_ISSET(n, &msgset)) | 506 | if (ERR_ISSET(n, &msgset)) | |
507 | return; | 507 | return; | |
508 | 508 | |||
509 | va_start(ap, n); | 509 | va_start(ap, n); | |
510 | fn = lbasename(curr_pos.p_file); | 510 | fn = lbasename(curr_pos.p_file); | |
511 | (void)printf("%s(%d): ", fn, curr_pos.p_line); | 511 | (void)printf("%s(%d): ", fn, curr_pos.p_line); | |
512 | (void)vprintf(msgs[n], ap); | 512 | (void)vprintf(msgs[n], ap); | |
513 | (void)printf(" [%d]\n", n); | 513 | (void)printf(" [%d]\n", n); | |
514 | va_end(ap); | 514 | va_end(ap); | |
515 | } | 515 | } | |
516 | 516 | |||
517 | /* | 517 | /* | |
518 | * XXX I think the logic is possibly somewhat screwed up here. The | 518 | * XXX I think the logic is possibly somewhat screwed up here. The | |
519 | * question is, how do we want to interpret the -s and -S flags going | 519 | * question is, how do we want to interpret the -s and -S flags going | |
520 | * forward? We need to answer that and then we can fix this to be | 520 | * forward? We need to answer that and then we can fix this to be | |
521 | * "right"... [perry, 2 Nov 2002] | 521 | * "right"... [perry, 2 Nov 2002] | |
522 | */ | 522 | */ | |
523 | int | 523 | int | |
524 | c99ism(int n, ...) | 524 | c99ism(int n, ...) | |
525 | { | 525 | { | |
526 | va_list ap; | 526 | va_list ap; | |
527 | int msg; | 527 | int msg; | |
528 | 528 | |||
529 | va_start(ap, n); | 529 | va_start(ap, n); | |
530 | if (sflag && !(Sflag || gflag)) { | 530 | if (sflag && !(Sflag || gflag)) { | |
531 | verror(n, ap); | 531 | verror(n, ap); | |
532 | msg = 1; | 532 | msg = 1; | |
533 | } else if (!sflag && (Sflag || gflag)) { | 533 | } else if (!sflag && (Sflag || gflag)) { | |
534 | msg = 0; | 534 | msg = 0; | |
535 | } else { | 535 | } else { | |
536 | vwarning(n, ap); | 536 | vwarning(n, ap); | |
537 | msg = 1; | 537 | msg = 1; | |
538 | } | 538 | } | |
539 | va_end(ap); | 539 | va_end(ap); | |
540 | 540 | |||
541 | return (msg); | 541 | return (msg); | |
542 | } | 542 | } | |
543 | 543 | |||
544 | int | 544 | int | |
545 | gnuism(int n, ...) | 545 | gnuism(int n, ...) | |
546 | { | 546 | { | |
547 | va_list ap; | 547 | va_list ap; | |
548 | int msg; | 548 | int msg; | |
549 | 549 | |||
550 | va_start(ap, n); | 550 | va_start(ap, n); | |
551 | if (sflag && !gflag) { | 551 | if (sflag && !gflag) { | |
552 | verror(n, ap); | 552 | verror(n, ap); | |
553 | msg = 1; | 553 | msg = 1; | |
554 | } else if (!sflag && gflag) { | 554 | } else if (!sflag && gflag) { | |
555 | msg = 0; | 555 | msg = 0; | |
556 | } else { | 556 | } else { | |
557 | vwarning(n, ap); | 557 | vwarning(n, ap); | |
558 | msg = 1; | 558 | msg = 1; | |
559 | } | 559 | } | |
560 | va_end(ap); | 560 | va_end(ap); | |
561 | 561 | |||
562 | return (msg); | 562 | return (msg); | |
563 | } | 563 | } |
--- src/usr.bin/xlint/lint1/scan.l 2013/10/18 20:46:09 1.53
+++ src/usr.bin/xlint/lint1/scan.l 2014/02/18 22:01:36 1.54
@@ -1,1257 +1,1261 @@ | @@ -1,1257 +1,1261 @@ | |||
1 | %{ | 1 | %{ | |
2 | /* $NetBSD: scan.l,v 1.53 2013/10/18 20:46:09 christos Exp $ */ | 2 | /* $NetBSD: scan.l,v 1.54 2014/02/18 22:01:36 christos Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | 5 | * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. | |
6 | * Copyright (c) 1994, 1995 Jochen Pohl | 6 | * Copyright (c) 1994, 1995 Jochen Pohl | |
7 | * All Rights Reserved. | 7 | * All Rights Reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | 15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | 16 | * documentation and/or other materials provided with the distribution. | |
17 | * 3. All advertising materials mentioning features or use of this software | 17 | * 3. All advertising materials mentioning features or use of this software | |
18 | * must display the following acknowledgement: | 18 | * must display the following acknowledgement: | |
19 | * This product includes software developed by Jochen Pohl for | 19 | * This product includes software developed by Jochen Pohl for | |
20 | * The NetBSD Project. | 20 | * The NetBSD Project. | |
21 | * 4. The name of the author may not be used to endorse or promote products | 21 | * 4. The name of the author may not be used to endorse or promote products | |
22 | * derived from this software without specific prior written permission. | 22 | * derived from this software without specific prior written permission. | |
23 | * | 23 | * | |
24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 24 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 25 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 26 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 27 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 28 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 29 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | #if defined(__RCSID) && !defined(lint) | 37 | #if defined(__RCSID) && !defined(lint) | |
38 | __RCSID("$NetBSD: scan.l,v 1.53 2013/10/18 20:46:09 christos Exp $"); | 38 | __RCSID("$NetBSD: scan.l,v 1.54 2014/02/18 22:01:36 christos Exp $"); | |
39 | #endif | 39 | #endif | |
40 | 40 | |||
41 | #include <stdlib.h> | 41 | #include <stdlib.h> | |
42 | #include <string.h> | 42 | #include <string.h> | |
43 | #include <limits.h> | 43 | #include <limits.h> | |
44 | #include <float.h> | 44 | #include <float.h> | |
45 | #include <ctype.h> | 45 | #include <ctype.h> | |
46 | #include <errno.h> | 46 | #include <errno.h> | |
47 | #include <math.h> | 47 | #include <math.h> | |
48 | 48 | |||
49 | #include "lint1.h" | 49 | #include "lint1.h" | |
50 | #include "cgram.h" | 50 | #include "cgram.h" | |
51 | 51 | |||
52 | #define CHAR_MASK (~(~0 << CHAR_BIT)) | 52 | #define CHAR_MASK (~(~0 << CHAR_BIT)) | |
53 | 53 | |||
54 | /* Current position (its also updated when an included file is parsed) */ | 54 | /* Current position (its also updated when an included file is parsed) */ | |
55 | pos_t curr_pos = { 1, "", 0 }; | 55 | pos_t curr_pos = { 1, "", 0 }; | |
56 | 56 | |||
57 | /* | 57 | /* | |
58 | * Current position in C source (not updated when an included file is | 58 | * Current position in C source (not updated when an included file is | |
59 | * parsed). | 59 | * parsed). | |
60 | */ | 60 | */ | |
61 | pos_t csrc_pos = { 1, "", 0 }; | 61 | pos_t csrc_pos = { 1, "", 0 }; | |
62 | 62 | |||
63 | static void incline(void); | 63 | static void incline(void); | |
64 | static void badchar(int); | 64 | static void badchar(int); | |
65 | static sbuf_t *allocsb(void); | 65 | static sbuf_t *allocsb(void); | |
66 | static void freesb(sbuf_t *); | 66 | static void freesb(sbuf_t *); | |
67 | static int inpc(void); | 67 | static int inpc(void); | |
68 | static int hash(const char *); | 68 | static int hash(const char *); | |
69 | static sym_t *search(sbuf_t *); | 69 | static sym_t *search(sbuf_t *); | |
70 | static int name(void); | 70 | static int name(void); | |
71 | static int keyw(sym_t *); | 71 | static int keyw(sym_t *); | |
72 | static int icon(int); | 72 | static int icon(int); | |
73 | static int fcon(void); | 73 | static int fcon(void); | |
74 | static int operator(int, op_t); | 74 | static int operator(int, op_t); | |
75 | static int ccon(void); | 75 | static int ccon(void); | |
76 | static int wccon(void); | 76 | static int wccon(void); | |
77 | static int getescc(int); | 77 | static int getescc(int); | |
78 | static void directive(void); | 78 | static void directive(void); | |
79 | static void comment(void); | 79 | static void comment(void); | |
80 | static void slashslashcomment(void); | 80 | static void slashslashcomment(void); | |
81 | static int string(void); | 81 | static int string(void); | |
82 | static int wcstrg(void); | 82 | static int wcstrg(void); | |
83 | 83 | |||
84 | %} | 84 | %} | |
85 | 85 | |||
86 | L [_A-Za-z] | 86 | L [_A-Za-z] | |
87 | D [0-9] | 87 | D [0-9] | |
88 | NZD [1-9] | 88 | NZD [1-9] | |
89 | OD [0-7] | 89 | OD [0-7] | |
90 | HD [0-9A-Fa-f] | 90 | HD [0-9A-Fa-f] | |
91 | EX ([eE][+-]?[0-9]+) | 91 | EX ([eE][+-]?[0-9]+) | |
92 | HX (p[+-]?[0-9A-Fa-f]+) | 92 | HX (p[+-]?[0-9A-Fa-f]+) | |
93 | TL ([fFlL]?[i]?) | 93 | TL ([fFlL]?[i]?) | |
94 | 94 | |||
95 | %option nounput | 95 | %option nounput | |
96 | 96 | |||
97 | %% | 97 | %% | |
98 | 98 | |||
99 | {L}({L}|{D})* return (name()); | 99 | {L}({L}|{D})* return (name()); | |
100 | 0{OD}*[lLuU]* return (icon(8)); | 100 | 0{OD}*[lLuU]* return (icon(8)); | |
101 | {NZD}{D}*[lLuU]* return (icon(10)); | 101 | {NZD}{D}*[lLuU]* return (icon(10)); | |
102 | 0[xX]{HD}+[lLuU]* return (icon(16)); | 102 | 0[xX]{HD}+[lLuU]* return (icon(16)); | |
103 | {D}+\.{D}*{EX}?{TL} | | 103 | {D}+\.{D}*{EX}?{TL} | | |
104 | {D}+{EX}{TL} | | 104 | {D}+{EX}{TL} | | |
105 | 0[xX]{HD}+\.{HD}*{HX}{TL} | | 105 | 0[xX]{HD}+\.{HD}*{HX}{TL} | | |
106 | 0[xX]{HD}+{HX}{TL} | | 106 | 0[xX]{HD}+{HX}{TL} | | |
107 | \.{D}+{EX}?{TL} return (fcon()); | 107 | \.{D}+{EX}?{TL} return (fcon()); | |
108 | "=" return (operator(T_ASSIGN, ASSIGN)); | 108 | "=" return (operator(T_ASSIGN, ASSIGN)); | |
109 | "*=" return (operator(T_OPASS, MULASS)); | 109 | "*=" return (operator(T_OPASS, MULASS)); | |
110 | "/=" return (operator(T_OPASS, DIVASS)); | 110 | "/=" return (operator(T_OPASS, DIVASS)); | |
111 | "%=" return (operator(T_OPASS, MODASS)); | 111 | "%=" return (operator(T_OPASS, MODASS)); | |
112 | "+=" return (operator(T_OPASS, ADDASS)); | 112 | "+=" return (operator(T_OPASS, ADDASS)); | |
113 | "-=" return (operator(T_OPASS, SUBASS)); | 113 | "-=" return (operator(T_OPASS, SUBASS)); | |
114 | "<<=" return (operator(T_OPASS, SHLASS)); | 114 | "<<=" return (operator(T_OPASS, SHLASS)); | |
115 | ">>=" return (operator(T_OPASS, SHRASS)); | 115 | ">>=" return (operator(T_OPASS, SHRASS)); | |
116 | "&=" return (operator(T_OPASS, ANDASS)); | 116 | "&=" return (operator(T_OPASS, ANDASS)); | |
117 | "^=" return (operator(T_OPASS, XORASS)); | 117 | "^=" return (operator(T_OPASS, XORASS)); | |
118 | "|=" return (operator(T_OPASS, ORASS)); | 118 | "|=" return (operator(T_OPASS, ORASS)); | |
119 | "||" return (operator(T_LOGOR, LOGOR)); | 119 | "||" return (operator(T_LOGOR, LOGOR)); | |
120 | "&&" return (operator(T_LOGAND, LOGAND)); | 120 | "&&" return (operator(T_LOGAND, LOGAND)); | |
121 | "|" return (operator(T_OR, OR)); | 121 | "|" return (operator(T_OR, OR)); | |
122 | "&" return (operator(T_AND, AND)); | 122 | "&" return (operator(T_AND, AND)); | |
123 | "^" return (operator(T_XOR, XOR)); | 123 | "^" return (operator(T_XOR, XOR)); | |
124 | "==" return (operator(T_EQOP, EQ)); | 124 | "==" return (operator(T_EQOP, EQ)); | |
125 | "!=" return (operator(T_EQOP, NE)); | 125 | "!=" return (operator(T_EQOP, NE)); | |
126 | "<" return (operator(T_RELOP, LT)); | 126 | "<" return (operator(T_RELOP, LT)); | |
127 | ">" return (operator(T_RELOP, GT)); | 127 | ">" return (operator(T_RELOP, GT)); | |
128 | "<=" return (operator(T_RELOP, LE)); | 128 | "<=" return (operator(T_RELOP, LE)); | |
129 | ">=" return (operator(T_RELOP, GE)); | 129 | ">=" return (operator(T_RELOP, GE)); | |
130 | "<<" return (operator(T_SHFTOP, SHL)); | 130 | "<<" return (operator(T_SHFTOP, SHL)); | |
131 | ">>" return (operator(T_SHFTOP, SHR)); | 131 | ">>" return (operator(T_SHFTOP, SHR)); | |
132 | "++" return (operator(T_INCDEC, INC)); | 132 | "++" return (operator(T_INCDEC, INC)); | |
133 | "--" return (operator(T_INCDEC, DEC)); | 133 | "--" return (operator(T_INCDEC, DEC)); | |
134 | "->" return (operator(T_STROP, ARROW)); | 134 | "->" return (operator(T_STROP, ARROW)); | |
135 | "." return (operator(T_STROP, POINT)); | 135 | "." return (operator(T_STROP, POINT)); | |
136 | "+" return (operator(T_ADDOP, PLUS)); | 136 | "+" return (operator(T_ADDOP, PLUS)); | |
137 | "-" return (operator(T_ADDOP, MINUS)); | 137 | "-" return (operator(T_ADDOP, MINUS)); | |
138 | "*" return (operator(T_MULT, MULT)); | 138 | "*" return (operator(T_MULT, MULT)); | |
139 | "/" return (operator(T_DIVOP, DIV)); | 139 | "/" return (operator(T_DIVOP, DIV)); | |
140 | "%" return (operator(T_DIVOP, MOD)); | 140 | "%" return (operator(T_DIVOP, MOD)); | |
141 | "!" return (operator(T_UNOP, NOT)); | 141 | "!" return (operator(T_UNOP, NOT)); | |
142 | "~" return (operator(T_UNOP, COMPL)); | 142 | "~" return (operator(T_UNOP, COMPL)); | |
143 | "\"" return (string()); | 143 | "\"" return (string()); | |
144 | "L\"" return (wcstrg()); | 144 | "L\"" return (wcstrg()); | |
145 | ";" return (T_SEMI); | 145 | ";" return (T_SEMI); | |
146 | "{" return (T_LBRACE); | 146 | "{" return (T_LBRACE); | |
147 | "}" return (T_RBRACE); | 147 | "}" return (T_RBRACE); | |
148 | "," return (T_COMMA); | 148 | "," return (T_COMMA); | |
149 | ":" return (T_COLON); | 149 | ":" return (T_COLON); | |
150 | "?" return (T_QUEST); | 150 | "?" return (T_QUEST); | |
151 | "[" return (T_LBRACK); | 151 | "[" return (T_LBRACK); | |
152 | "]" return (T_RBRACK); | 152 | "]" return (T_RBRACK); | |
153 | "(" return (T_LPARN); | 153 | "(" return (T_LPARN); | |
154 | ")" return (T_RPARN); | 154 | ")" return (T_RPARN); | |
155 | "..." return (T_ELLIPSE); | 155 | "..." return (T_ELLIPSE); | |
156 | "'" return (ccon()); | 156 | "'" return (ccon()); | |
157 | "L'" return (wccon()); | 157 | "L'" return (wccon()); | |
158 | ^#.*$ directive(); | 158 | ^#.*$ directive(); | |
159 | \n incline(); | 159 | \n incline(); | |
160 | \t|" "|\f|\v ; | 160 | \t|" "|\f|\v ; | |
161 | "/*" comment(); | 161 | "/*" comment(); | |
162 | "//" slashslashcomment(); | 162 | "//" slashslashcomment(); | |
163 | . badchar(yytext[0]); | 163 | . badchar(yytext[0]); | |
164 | 164 | |||
165 | %% | 165 | %% | |
166 | 166 | |||
167 | static void | 167 | static void | |
168 | incline(void) | 168 | incline(void) | |
169 | { | 169 | { | |
170 | curr_pos.p_line++; | 170 | curr_pos.p_line++; | |
171 | curr_pos.p_uniq = 0; | 171 | curr_pos.p_uniq = 0; | |
172 | if (curr_pos.p_file == csrc_pos.p_file) { | 172 | if (curr_pos.p_file == csrc_pos.p_file) { | |
173 | csrc_pos.p_line++; | 173 | csrc_pos.p_line++; | |
174 | csrc_pos.p_uniq = 0; | 174 | csrc_pos.p_uniq = 0; | |
175 | } | 175 | } | |
176 | } | 176 | } | |
177 | 177 | |||
178 | static void | 178 | static void | |
179 | badchar(int c) | 179 | badchar(int c) | |
180 | { | 180 | { | |
181 | 181 | |||
182 | /* unknown character \%o */ | 182 | /* unknown character \%o */ | |
183 | error(250, c); | 183 | error(250, c); | |
184 | } | 184 | } | |
185 | 185 | |||
186 | /* | 186 | /* | |
187 | * Keywords. | 187 | * Keywords. | |
188 | * During initialisation they are written to the symbol table. | 188 | * During initialisation they are written to the symbol table. | |
189 | */ | 189 | */ | |
190 | static struct kwtab { | 190 | static struct kwtab { | |
191 | const char *kw_name; /* keyword */ | 191 | const char *kw_name; /* keyword */ | |
192 | int kw_token; /* token returned by yylex() */ | 192 | int kw_token; /* token returned by yylex() */ | |
193 | scl_t kw_scl; /* storage class if kw_token T_SCLASS */ | 193 | scl_t kw_scl; /* storage class if kw_token T_SCLASS */ | |
194 | tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ | 194 | tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ | |
195 | tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */ | 195 | tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */ | |
196 | u_int kw_c89; /* c89 keyword */ | 196 | u_int kw_c89; /* c89 keyword */ | |
197 | u_int kw_c99; /* c99 keyword */ | 197 | u_int kw_c99; /* c99 keyword */ | |
198 | u_int kw_gcc; /* GCC keyword */ | 198 | u_int kw_gcc; /* GCC keyword */ | |
199 | } kwtab[] = { | 199 | } kwtab[] = { | |
200 | { "__alignof__", T_ALIGNOF, 0, 0, 0, 0, 0, 0 }, | 200 | { "__alignof__", T_ALIGNOF, 0, 0, 0, 0, 0, 0 }, | |
201 | { "__attribute__",T_ATTRIBUTE, 0, 0, 0, 0, 0, 1 }, | 201 | { "__attribute__",T_ATTRIBUTE, 0, 0, 0, 0, 0, 1 }, | |
202 | { "attribute", T_ATTRIBUTE, 0, 0, 0, 0, 0, 1 }, | 202 | { "attribute", T_ATTRIBUTE, 0, 0, 0, 0, 0, 1 }, | |
203 | { "__packed__", T_AT_PACKED, 0, 0, 0, 0, 0, 1 }, | 203 | { "__packed__", T_AT_PACKED, 0, 0, 0, 0, 0, 1 }, | |
204 | { "packed", T_AT_PACKED, 0, 0, 0, 0, 0, 1 }, | 204 | { "packed", T_AT_PACKED, 0, 0, 0, 0, 0, 1 }, | |
205 | { "__aligned__",T_AT_ALIGNED, 0, 0, 0, 0, 0, 1 }, | 205 | { "__aligned__",T_AT_ALIGNED, 0, 0, 0, 0, 0, 1 }, | |
206 | { "aligned", T_AT_ALIGNED, 0, 0, 0, 0, 0, 1 }, | 206 | { "aligned", T_AT_ALIGNED, 0, 0, 0, 0, 0, 1 }, | |
207 | { "__transparent_union__",T_AT_TUNION,0,0, 0, 0, 0, 1 }, | 207 | { "__transparent_union__",T_AT_TUNION,0,0, 0, 0, 0, 1 }, | |
208 | { "transparent_union",T_AT_TUNION,0, 0, 0, 0, 0, 1 }, | 208 | { "transparent_union",T_AT_TUNION,0, 0, 0, 0, 0, 1 }, | |
209 | { "__unused__", T_AT_UNUSED, 0, 0, 0, 0, 0, 1 }, | 209 | { "__unused__", T_AT_UNUSED, 0, 0, 0, 0, 0, 1 }, | |
210 | { "unused", T_AT_UNUSED, 0, 0, 0, 0, 0, 1 }, | 210 | { "unused", T_AT_UNUSED, 0, 0, 0, 0, 0, 1 }, | |
211 | { "__deprecated__",T_AT_DEPRECATED,0, 0, 0, 0, 0, 1 }, | 211 | { "__deprecated__",T_AT_DEPRECATED,0, 0, 0, 0, 0, 1 }, | |
212 | { "deprecated", T_AT_DEPRECATED,0, 0, 0, 0, 0, 1 }, | 212 | { "deprecated", T_AT_DEPRECATED,0, 0, 0, 0, 0, 1 }, | |
213 | { "__may_alias__",T_AT_MAY_ALIAS,0, 0, 0, 0, 0, 1 }, | 213 | { "__may_alias__",T_AT_MAY_ALIAS,0, 0, 0, 0, 0, 1 }, | |
214 | { "may_alias", T_AT_MAY_ALIAS, 0, 0, 0, 0, 0, 1 }, | 214 | { "may_alias", T_AT_MAY_ALIAS, 0, 0, 0, 0, 0, 1 }, | |
215 | { "asm", T_ASM, 0, 0, 0, 0, 0, 1 }, | 215 | { "asm", T_ASM, 0, 0, 0, 0, 0, 1 }, | |
216 | { "__asm", T_ASM, 0, 0, 0, 0, 0, 0 }, | 216 | { "__asm", T_ASM, 0, 0, 0, 0, 0, 0 }, | |
217 | { "__asm__", T_ASM, 0, 0, 0, 0, 0, 0 }, | 217 | { "__asm__", T_ASM, 0, 0, 0, 0, 0, 0 }, | |
218 | { "auto", T_SCLASS, AUTO, 0, 0, 0, 0, 0 }, | 218 | { "auto", T_SCLASS, AUTO, 0, 0, 0, 0, 0 }, | |
219 | { "break", T_BREAK, 0, 0, 0, 0, 0, 0 }, | 219 | { "break", T_BREAK, 0, 0, 0, 0, 0, 0 }, | |
220 | { "_Bool", T_TYPE, 0, BOOL, 0, 0, 1, 0 }, | 220 | { "_Bool", T_TYPE, 0, BOOL, 0, 0, 1, 0 }, | |
221 | { "case", T_CASE, 0, 0, 0, 0, 0, 0 }, | 221 | { "case", T_CASE, 0, 0, 0, 0, 0, 0 }, | |
222 | { "char", T_TYPE, 0, CHAR, 0, 0, 0, 0 }, | 222 | { "char", T_TYPE, 0, CHAR, 0, 0, 0, 0 }, | |
223 | { "const", T_QUAL, 0, 0, CONST, 1, 0, 0 }, | 223 | { "const", T_QUAL, 0, 0, CONST, 1, 0, 0 }, | |
224 | { "_Complex", T_TYPE, 0, COMPLEX,0, 0, 1, 0 }, | 224 | { "_Complex", T_TYPE, 0, COMPLEX,0, 0, 1, 0 }, | |
225 | { "__const__", T_QUAL, 0, 0, CONST, 0, 0, 0 }, | 225 | { "__const__", T_QUAL, 0, 0, CONST, 0, 0, 0 }, | |
226 | { "__const", T_QUAL, 0, 0, CONST, 0, 0, 0 }, | 226 | { "__const", T_QUAL, 0, 0, CONST, 0, 0, 0 }, | |
227 | { "continue", T_CONTINUE, 0, 0, 0, 0, 0, 0 }, | 227 | { "continue", T_CONTINUE, 0, 0, 0, 0, 0, 0 }, | |
228 | { "default", T_DEFAULT, 0, 0, 0, 0, 0, 0 }, | 228 | { "default", T_DEFAULT, 0, 0, 0, 0, 0, 0 }, | |
229 | { "do", T_DO, 0, 0, 0, 0, 0, 0 }, | 229 | { "do", T_DO, 0, 0, 0, 0, 0, 0 }, | |
230 | { "double", T_TYPE, 0, DOUBLE, 0, 0, 0, 0 }, | 230 | { "double", T_TYPE, 0, DOUBLE, 0, 0, 0, 0 }, | |
231 | { "else", T_ELSE, 0, 0, 0, 0, 0, 0 }, | 231 | { "else", T_ELSE, 0, 0, 0, 0, 0, 0 }, | |
232 | { "enum", T_ENUM, 0, 0, 0, 0, 0, 0 }, | 232 | { "enum", T_ENUM, 0, 0, 0, 0, 0, 0 }, | |
233 | { "__extension__", T_EXTENSION, 0, 0, 0, 0, 0, 1 }, | |||
233 | { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0, 0 }, | 234 | { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0, 0 }, | |
234 | { "float", T_TYPE, 0, FLOAT, 0, 0, 0, 0 }, | 235 | { "float", T_TYPE, 0, FLOAT, 0, 0, 0, 0 }, | |
235 | { "for", T_FOR, 0, 0, 0, 0, 0, 0 }, | 236 | { "for", T_FOR, 0, 0, 0, 0, 0, 0 }, | |
236 | { "goto", T_GOTO, 0, 0, 0, 0, 0, 0 }, | 237 | { "goto", T_GOTO, 0, 0, 0, 0, 0, 0 }, | |
237 | { "if", T_IF, 0, 0, 0, 0, 0, 0 }, | 238 | { "if", T_IF, 0, 0, 0, 0, 0, 0 }, | |
238 | { "__imag__", T_IMAG, 0, 0, 0, 0, 1, 0 }, | 239 | { "__imag__", T_IMAG, 0, 0, 0, 0, 1, 0 }, | |
239 | { "inline", T_SCLASS, INLINE, 0, 0, 0, 1, 0 }, | 240 | { "inline", T_SCLASS, INLINE, 0, 0, 0, 1, 0 }, | |
240 | { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, | 241 | { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, | |
241 | { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, | 242 | { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, | |
242 | { "int", T_TYPE, 0, INT, 0, 0, 0, 0 }, | 243 | { "int", T_TYPE, 0, INT, 0, 0, 0, 0 }, | |
243 | { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0, 0 }, | 244 | { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0, 0 }, | |
244 | { "long", T_TYPE, 0, LONG, 0, 0, 0, 0 }, | 245 | { "long", T_TYPE, 0, LONG, 0, 0, 0, 0 }, | |
245 | { "__real__", T_REAL, 0, 0, 0, 0, 1, 0 }, | 246 | { "__real__", T_REAL, 0, 0, 0, 0, 1, 0 }, | |
246 | { "register", T_SCLASS, REG, 0, 0, 0, 0, 0 }, | 247 | { "register", T_SCLASS, REG, 0, 0, 0, 0, 0 }, | |
247 | { "restrict", T_QUAL, 0, 0, RESTRICT, 0, 1, 0 }, | 248 | { "restrict", T_QUAL, 0, 0, RESTRICT, 0, 1, 0 }, | |
248 | { "return", T_RETURN, 0, 0, 0, 0, 0, 0 }, | 249 | { "return", T_RETURN, 0, 0, 0, 0, 0, 0 }, | |
249 | { "__packed", T_PACKED, 0, 0, 0, 0, 0, 0 }, | 250 | { "__packed", T_PACKED, 0, 0, 0, 0, 0, 0 }, | |
250 | { "short", T_TYPE, 0, SHORT, 0, 0, 0, 0 }, | 251 | { "short", T_TYPE, 0, SHORT, 0, 0, 0, 0 }, | |
251 | { "signed", T_TYPE, 0, SIGNED, 0, 1, 0, 0 }, | 252 | { "signed", T_TYPE, 0, SIGNED, 0, 1, 0, 0 }, | |
252 | { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, | 253 | { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, | |
253 | { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, | 254 | { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, | |
254 | { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0, 0 }, | 255 | { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0, 0 }, | |
255 | { "static", T_SCLASS, STATIC, 0, 0, 0, 0, 0 }, | 256 | { "static", T_SCLASS, STATIC, 0, 0, 0, 0, 0 }, | |
256 | { "struct", T_SOU, 0, STRUCT, 0, 0, 0, 0 }, | 257 | { "struct", T_SOU, 0, STRUCT, 0, 0, 0, 0 }, | |
257 | { "switch", T_SWITCH, 0, 0, 0, 0, 0, 0 }, | 258 | { "switch", T_SWITCH, 0, 0, 0, 0, 0, 0 }, | |
258 | { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0, 0 }, | 259 | { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0, 0 }, | |
260 | { "typeof", T_TYPEOF, 0, 0, 0, 0, 0, 1 }, | |||
261 | { "__typeof", T_TYPEOF, 0, 0, 0, 0, 0, 1 }, | |||
262 | { "__typeof__", T_TYPEOF, 0, 0, 0, 0, 0, 1 }, | |||
259 | { "union", T_SOU, 0, UNION, 0, 0, 0, 0 }, | 263 | { "union", T_SOU, 0, UNION, 0, 0, 0, 0 }, | |
260 | { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0, 0 }, | 264 | { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0, 0 }, | |
261 | { "void", T_TYPE, 0, VOID, 0, 0, 0, 0 }, | 265 | { "void", T_TYPE, 0, VOID, 0, 0, 0, 0 }, | |
262 | { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0, 0 }, | 266 | { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0, 0 }, | |
263 | { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, | 267 | { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, | |
264 | { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, | 268 | { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, | |
265 | { "while", T_WHILE, 0, 0, 0, 0, 0, 0 }, | 269 | { "while", T_WHILE, 0, 0, 0, 0, 0, 0 }, | |
266 | { NULL, 0, 0, 0, 0, 0, 0, 0 } | 270 | { NULL, 0, 0, 0, 0, 0, 0, 0 } | |
267 | }; | 271 | }; | |
268 | 272 | |||
269 | /* Symbol table */ | 273 | /* Symbol table */ | |
270 | static sym_t *symtab[HSHSIZ1]; | 274 | static sym_t *symtab[HSHSIZ1]; | |
271 | 275 | |||
272 | /* bit i of the entry with index i is set */ | 276 | /* bit i of the entry with index i is set */ | |
273 | uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; | 277 | uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; | |
274 | 278 | |||
275 | /* least significant i bits are set in the entry with index i */ | 279 | /* least significant i bits are set in the entry with index i */ | |
276 | uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; | 280 | uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; | |
277 | 281 | |||
278 | /* least significant i bits are not set in the entry with index i */ | 282 | /* least significant i bits are not set in the entry with index i */ | |
279 | uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; | 283 | uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; | |
280 | 284 | |||
281 | /* free list for sbuf structures */ | 285 | /* free list for sbuf structures */ | |
282 | static sbuf_t *sbfrlst; | 286 | static sbuf_t *sbfrlst; | |
283 | 287 | |||
284 | /* Typ of next expected symbol */ | 288 | /* Typ of next expected symbol */ | |
285 | symt_t symtyp; | 289 | symt_t symtyp; | |
286 | 290 | |||
287 | 291 | |||
288 | /* | 292 | /* | |
289 | * All keywords are written to the symbol table. This saves us looking | 293 | * All keywords are written to the symbol table. This saves us looking | |
290 | * in a extra table for each name we found. | 294 | * in a extra table for each name we found. | |
291 | */ | 295 | */ | |
292 | void | 296 | void | |
293 | initscan(void) | 297 | initscan(void) | |
294 | { | 298 | { | |
295 | struct kwtab *kw; | 299 | struct kwtab *kw; | |
296 | sym_t *sym; | 300 | sym_t *sym; | |
297 | size_t h, i; | 301 | size_t h, i; | |
298 | uint64_t uq; | 302 | uint64_t uq; | |
299 | 303 | |||
300 | for (kw = kwtab; kw->kw_name != NULL; kw++) { | 304 | for (kw = kwtab; kw->kw_name != NULL; kw++) { | |
301 | if ((kw->kw_c89 || kw->kw_c99) && tflag) | 305 | if ((kw->kw_c89 || kw->kw_c99) && tflag) | |
302 | continue; | 306 | continue; | |
303 | if (kw->kw_c99 && !(Sflag || gflag)) | 307 | if (kw->kw_c99 && !(Sflag || gflag)) | |
304 | continue; | 308 | continue; | |
305 | if (kw->kw_gcc && !gflag) | 309 | if (kw->kw_gcc && !gflag) | |
306 | continue; | 310 | continue; | |
307 | sym = getblk(sizeof (sym_t)); | 311 | sym = getblk(sizeof (sym_t)); | |
308 | sym->s_name = kw->kw_name; | 312 | sym->s_name = kw->kw_name; | |
309 | sym->s_keyw = 1; | 313 | sym->s_keyw = 1; | |
310 | sym->s_value.v_quad = kw->kw_token; | 314 | sym->s_value.v_quad = kw->kw_token; | |
311 | if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) { | 315 | if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) { | |
312 | sym->s_tspec = kw->kw_tspec; | 316 | sym->s_tspec = kw->kw_tspec; | |
313 | } else if (kw->kw_token == T_SCLASS) { | 317 | } else if (kw->kw_token == T_SCLASS) { | |
314 | sym->s_scl = kw->kw_scl; | 318 | sym->s_scl = kw->kw_scl; | |
315 | } else if (kw->kw_token == T_QUAL) { | 319 | } else if (kw->kw_token == T_QUAL) { | |
316 | sym->s_tqual = kw->kw_tqual; | 320 | sym->s_tqual = kw->kw_tqual; | |
317 | } | 321 | } | |
318 | h = hash(sym->s_name); | 322 | h = hash(sym->s_name); | |
319 | if ((sym->s_link = symtab[h]) != NULL) | 323 | if ((sym->s_link = symtab[h]) != NULL) | |
320 | symtab[h]->s_rlink = &sym->s_link; | 324 | symtab[h]->s_rlink = &sym->s_link; | |
321 | sym->s_rlink = &symtab[h]; | 325 | sym->s_rlink = &symtab[h]; | |
322 | symtab[h] = sym; | 326 | symtab[h] = sym; | |
323 | } | 327 | } | |
324 | 328 | |||
325 | /* initialize bit-masks for quads */ | 329 | /* initialize bit-masks for quads */ | |
326 | for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) { | 330 | for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) { | |
327 | qbmasks[i] = (uint64_t)1 << i; | 331 | qbmasks[i] = (uint64_t)1 << i; | |
328 | uq = ~(uint64_t)0 << i; | 332 | uq = ~(uint64_t)0 << i; | |
329 | qumasks[i] = uq; | 333 | qumasks[i] = uq; | |
330 | qlmasks[i] = ~uq; | 334 | qlmasks[i] = ~uq; | |
331 | } | 335 | } | |
332 | qumasks[i] = 0; | 336 | qumasks[i] = 0; | |
333 | qlmasks[i] = ~(uint64_t)0; | 337 | qlmasks[i] = ~(uint64_t)0; | |
334 | } | 338 | } | |
335 | 339 | |||
336 | /* | 340 | /* | |
337 | * Get a free sbuf structure, if possible from the free list | 341 | * Get a free sbuf structure, if possible from the free list | |
338 | */ | 342 | */ | |
339 | static sbuf_t * | 343 | static sbuf_t * | |
340 | allocsb(void) | 344 | allocsb(void) | |
341 | { | 345 | { | |
342 | sbuf_t *sb; | 346 | sbuf_t *sb; | |
343 | 347 | |||
344 | if ((sb = sbfrlst) != NULL) { | 348 | if ((sb = sbfrlst) != NULL) { | |
345 | sbfrlst = sb->sb_nxt; | 349 | sbfrlst = sb->sb_nxt; | |
346 | } else { | 350 | } else { | |
347 | sb = xmalloc(sizeof (sbuf_t)); | 351 | sb = xmalloc(sizeof (sbuf_t)); | |
348 | } | 352 | } | |
349 | (void)memset(sb, 0, sizeof (*sb)); | 353 | (void)memset(sb, 0, sizeof (*sb)); | |
350 | return (sb); | 354 | return (sb); | |
351 | } | 355 | } | |
352 | 356 | |||
353 | /* | 357 | /* | |
354 | * Put a sbuf structure to the free list | 358 | * Put a sbuf structure to the free list | |
355 | */ | 359 | */ | |
356 | static void | 360 | static void | |
357 | freesb(sbuf_t *sb) | 361 | freesb(sbuf_t *sb) | |
358 | { | 362 | { | |
359 | 363 | |||
360 | sb->sb_nxt = sbfrlst; | 364 | sb->sb_nxt = sbfrlst; | |
361 | sbfrlst = sb; | 365 | sbfrlst = sb; | |
362 | } | 366 | } | |
363 | 367 | |||
364 | /* | 368 | /* | |
365 | * Read a character and ensure that it is positive (except EOF). | 369 | * Read a character and ensure that it is positive (except EOF). | |
366 | * Increment line count(s) if necessary. | 370 | * Increment line count(s) if necessary. | |
367 | */ | 371 | */ | |
368 | static int | 372 | static int | |
369 | inpc(void) | 373 | inpc(void) | |
370 | { | 374 | { | |
371 | int c; | 375 | int c; | |
372 | 376 | |||
373 | if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n') | 377 | if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n') | |
374 | incline(); | 378 | incline(); | |
375 | return (c); | 379 | return (c); | |
376 | } | 380 | } | |
377 | 381 | |||
378 | static int | 382 | static int | |
379 | hash(const char *s) | 383 | hash(const char *s) | |
380 | { | 384 | { | |
381 | u_int v; | 385 | u_int v; | |
382 | const u_char *us; | 386 | const u_char *us; | |
383 | 387 | |||
384 | v = 0; | 388 | v = 0; | |
385 | for (us = (const u_char *)s; *us != '\0'; us++) { | 389 | for (us = (const u_char *)s; *us != '\0'; us++) { | |
386 | v = (v << sizeof (v)) + *us; | 390 | v = (v << sizeof (v)) + *us; | |
387 | v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v)); | 391 | v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v)); | |
388 | } | 392 | } | |
389 | return (v % HSHSIZ1); | 393 | return (v % HSHSIZ1); | |
390 | } | 394 | } | |
391 | 395 | |||
392 | /* | 396 | /* | |
393 | * Lex has found a letter followed by zero or more letters or digits. | 397 | * Lex has found a letter followed by zero or more letters or digits. | |
394 | * It looks for a symbol in the symbol table with the same name. This | 398 | * It looks for a symbol in the symbol table with the same name. This | |
395 | * symbol must either be a keyword or a symbol of the type required by | 399 | * symbol must either be a keyword or a symbol of the type required by | |
396 | * symtyp (label, member, tag, ...). | 400 | * symtyp (label, member, tag, ...). | |
397 | * | 401 | * | |
398 | * If it is a keyword, the token is returned. In some cases it is described | 402 | * If it is a keyword, the token is returned. In some cases it is described | |
399 | * more deeply by data written to yylval. | 403 | * more deeply by data written to yylval. | |
400 | * | 404 | * | |
401 | * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct | 405 | * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct | |
402 | * is stored in yylval. This struct contains the name of the symbol, it's | 406 | * is stored in yylval. This struct contains the name of the symbol, it's | |
403 | * length and hash value. If there is already a symbol of the same name | 407 | * length and hash value. If there is already a symbol of the same name | |
404 | * and type in the symbol table, the sbuf struct also contains a pointer | 408 | * and type in the symbol table, the sbuf struct also contains a pointer | |
405 | * to the symbol table entry. | 409 | * to the symbol table entry. | |
406 | */ | 410 | */ | |
407 | static int | 411 | static int | |
408 | name(void) | 412 | name(void) | |
409 | { | 413 | { | |
410 | char *s; | 414 | char *s; | |
411 | sbuf_t *sb; | 415 | sbuf_t *sb; | |
412 | sym_t *sym; | 416 | sym_t *sym; | |
413 | int tok; | 417 | int tok; | |
414 | 418 | |||
415 | sb = allocsb(); | 419 | sb = allocsb(); | |
416 | sb->sb_name = yytext; | 420 | sb->sb_name = yytext; | |
417 | sb->sb_len = yyleng; | 421 | sb->sb_len = yyleng; | |
418 | sb->sb_hash = hash(yytext); | 422 | sb->sb_hash = hash(yytext); | |
419 | if ((sym = search(sb)) != NULL && sym->s_keyw) { | 423 | if ((sym = search(sb)) != NULL && sym->s_keyw) { | |
420 | freesb(sb); | 424 | freesb(sb); | |
421 | return (keyw(sym)); | 425 | return (keyw(sym)); | |
422 | } | 426 | } | |
423 | 427 | |||
424 | sb->sb_sym = sym; | 428 | sb->sb_sym = sym; | |
425 | 429 | |||
426 | if (sym != NULL) { | 430 | if (sym != NULL) { | |
427 | if (blklev < sym->s_blklev) | 431 | if (blklev < sym->s_blklev) | |
428 | LERROR("name()"); | 432 | LERROR("name()"); | |
429 | sb->sb_name = sym->s_name; | 433 | sb->sb_name = sym->s_name; | |
430 | sb->sb_len = strlen(sym->s_name); | 434 | sb->sb_len = strlen(sym->s_name); | |
431 | tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; | 435 | tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; | |
432 | } else { | 436 | } else { | |
433 | s = getblk(yyleng + 1); | 437 | s = getblk(yyleng + 1); | |
434 | (void)memcpy(s, yytext, yyleng + 1); | 438 | (void)memcpy(s, yytext, yyleng + 1); | |
435 | sb->sb_name = s; | 439 | sb->sb_name = s; | |
436 | sb->sb_len = yyleng; | 440 | sb->sb_len = yyleng; | |
437 | tok = T_NAME; | 441 | tok = T_NAME; | |
438 | } | 442 | } | |
439 | 443 | |||
440 | yylval.y_sb = sb; | 444 | yylval.y_sb = sb; | |
441 | return (tok); | 445 | return (tok); | |
442 | } | 446 | } | |
443 | 447 | |||
444 | static sym_t * | 448 | static sym_t * | |
445 | search(sbuf_t *sb) | 449 | search(sbuf_t *sb) | |
446 | { | 450 | { | |
447 | sym_t *sym; | 451 | sym_t *sym; | |
448 | 452 | |||
449 | for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) { | 453 | for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) { | |
450 | if (strcmp(sym->s_name, sb->sb_name) == 0) { | 454 | if (strcmp(sym->s_name, sb->sb_name) == 0) { | |
451 | if (sym->s_keyw || sym->s_kind == symtyp) | 455 | if (sym->s_keyw || sym->s_kind == symtyp) | |
452 | return (sym); | 456 | return (sym); | |
453 | } | 457 | } | |
454 | } | 458 | } | |
455 | 459 | |||
456 | return (NULL); | 460 | return (NULL); | |
457 | } | 461 | } | |
458 | 462 | |||
459 | static int | 463 | static int | |
460 | keyw(sym_t *sym) | 464 | keyw(sym_t *sym) | |
461 | { | 465 | { | |
462 | int t; | 466 | int t; | |
463 | 467 | |||
464 | if ((t = (int)sym->s_value.v_quad) == T_SCLASS) { | 468 | if ((t = (int)sym->s_value.v_quad) == T_SCLASS) { | |
465 | yylval.y_scl = sym->s_scl; | 469 | yylval.y_scl = sym->s_scl; | |
466 | } else if (t == T_TYPE || t == T_SOU) { | 470 | } else if (t == T_TYPE || t == T_SOU) { | |
467 | yylval.y_tspec = sym->s_tspec; | 471 | yylval.y_tspec = sym->s_tspec; | |
468 | } else if (t == T_QUAL) { | 472 | } else if (t == T_QUAL) { | |
469 | yylval.y_tqual = sym->s_tqual; | 473 | yylval.y_tqual = sym->s_tqual; | |
470 | } | 474 | } | |
471 | return (t); | 475 | return (t); | |
472 | } | 476 | } | |
473 | 477 | |||
474 | /* | 478 | /* | |
475 | * Convert a string representing an integer into internal representation. | 479 | * Convert a string representing an integer into internal representation. | |
476 | * The value is returned in yylval. icon() (and yylex()) returns T_CON. | 480 | * The value is returned in yylval. icon() (and yylex()) returns T_CON. | |
477 | */ | 481 | */ | |
478 | static int | 482 | static int | |
479 | icon(int base) | 483 | icon(int base) | |
480 | { | 484 | { | |
481 | int l_suffix, u_suffix; | 485 | int l_suffix, u_suffix; | |
482 | int len; | 486 | int len; | |
483 | const char *cp; | 487 | const char *cp; | |
484 | char c, *eptr; | 488 | char c, *eptr; | |
485 | tspec_t typ; | 489 | tspec_t typ; | |
486 | uint64_t uq = 0; | 490 | uint64_t uq = 0; | |
487 | int ansiu; | 491 | int ansiu; | |
488 | static tspec_t contypes[2][3] = { | 492 | static tspec_t contypes[2][3] = { | |
489 | { INT, LONG, QUAD }, | 493 | { INT, LONG, QUAD }, | |
490 | { UINT, ULONG, UQUAD } | 494 | { UINT, ULONG, UQUAD } | |
491 | }; | 495 | }; | |
492 | 496 | |||
493 | cp = yytext; | 497 | cp = yytext; | |
494 | len = yyleng; | 498 | len = yyleng; | |
495 | 499 | |||
496 | /* skip 0x */ | 500 | /* skip 0x */ | |
497 | if (base == 16) { | 501 | if (base == 16) { | |
498 | cp += 2; | 502 | cp += 2; | |
499 | len -= 2; | 503 | len -= 2; | |
500 | } | 504 | } | |
501 | 505 | |||
502 | /* read suffixes */ | 506 | /* read suffixes */ | |
503 | l_suffix = u_suffix = 0; | 507 | l_suffix = u_suffix = 0; | |
504 | for ( ; ; ) { | 508 | for ( ; ; ) { | |
505 | if ((c = cp[len - 1]) == 'l' || c == 'L') { | 509 | if ((c = cp[len - 1]) == 'l' || c == 'L') { | |
506 | l_suffix++; | 510 | l_suffix++; | |
507 | } else if (c == 'u' || c == 'U') { | 511 | } else if (c == 'u' || c == 'U') { | |
508 | u_suffix++; | 512 | u_suffix++; | |
509 | } else { | 513 | } else { | |
510 | break; | 514 | break; | |
511 | } | 515 | } | |
512 | len--; | 516 | len--; | |
513 | } | 517 | } | |
514 | if (l_suffix > 2 || u_suffix > 1) { | 518 | if (l_suffix > 2 || u_suffix > 1) { | |
515 | /* malformed integer constant */ | 519 | /* malformed integer constant */ | |
516 | warning(251); | 520 | warning(251); | |
517 | if (l_suffix > 2) | 521 | if (l_suffix > 2) | |
518 | l_suffix = 2; | 522 | l_suffix = 2; | |
519 | if (u_suffix > 1) | 523 | if (u_suffix > 1) | |
520 | u_suffix = 1; | 524 | u_suffix = 1; | |
521 | } | 525 | } | |
522 | if (tflag && u_suffix != 0) { | 526 | if (tflag && u_suffix != 0) { | |
523 | /* suffix U is illegal in traditional C */ | 527 | /* suffix U is illegal in traditional C */ | |
524 | warning(97); | 528 | warning(97); | |
525 | } | 529 | } | |
526 | typ = contypes[u_suffix][l_suffix]; | 530 | typ = contypes[u_suffix][l_suffix]; | |
527 | 531 | |||
528 | errno = 0; | 532 | errno = 0; | |
529 | 533 | |||
530 | uq = strtouq(cp, &eptr, base); | 534 | uq = strtouq(cp, &eptr, base); | |
531 | if (eptr != cp + len) | 535 | if (eptr != cp + len) | |
532 | LERROR("icon()"); | 536 | LERROR("icon()"); | |
533 | if (errno != 0) | 537 | if (errno != 0) | |
534 | /* integer constant out of range */ | 538 | /* integer constant out of range */ | |
535 | warning(252); | 539 | warning(252); | |
536 | 540 | |||
537 | /* | 541 | /* | |
538 | * If the value is too big for the current type, we must choose | 542 | * If the value is too big for the current type, we must choose | |
539 | * another type. | 543 | * another type. | |
540 | */ | 544 | */ | |
541 | ansiu = 0; | 545 | ansiu = 0; | |
542 | switch (typ) { | 546 | switch (typ) { | |
543 | case INT: | 547 | case INT: | |
544 | if (uq <= TARG_INT_MAX) { | 548 | if (uq <= TARG_INT_MAX) { | |
545 | /* ok */ | 549 | /* ok */ | |
546 | } else if (uq <= TARG_UINT_MAX && base != 10) { | 550 | } else if (uq <= TARG_UINT_MAX && base != 10) { | |
547 | typ = UINT; | 551 | typ = UINT; | |
548 | } else if (uq <= TARG_LONG_MAX) { | 552 | } else if (uq <= TARG_LONG_MAX) { | |
549 | typ = LONG; | 553 | typ = LONG; | |
550 | } else { | 554 | } else { | |
551 | typ = ULONG; | 555 | typ = ULONG; | |
552 | if (uq > TARG_ULONG_MAX) { | 556 | if (uq > TARG_ULONG_MAX) { | |
553 | /* integer constant out of range */ | 557 | /* integer constant out of range */ | |
554 | warning(252); | 558 | warning(252); | |
555 | } | 559 | } | |
556 | } | 560 | } | |
557 | if (typ == UINT || typ == ULONG) { | 561 | if (typ == UINT || typ == ULONG) { | |
558 | if (tflag) { | 562 | if (tflag) { | |
559 | typ = LONG; | 563 | typ = LONG; | |
560 | } else if (!sflag) { | 564 | } else if (!sflag) { | |
561 | /* | 565 | /* | |
562 | * Remember that the constant is unsigned | 566 | * Remember that the constant is unsigned | |
563 | * only in ANSI C | 567 | * only in ANSI C | |
564 | */ | 568 | */ | |
565 | ansiu = 1; | 569 | ansiu = 1; | |
566 | } | 570 | } | |
567 | } | 571 | } | |
568 | break; | 572 | break; | |
569 | case UINT: | 573 | case UINT: | |
570 | if (uq > TARG_UINT_MAX) { | 574 | if (uq > TARG_UINT_MAX) { | |
571 | typ = ULONG; | 575 | typ = ULONG; | |
572 | if (uq > TARG_ULONG_MAX) { | 576 | if (uq > TARG_ULONG_MAX) { | |
573 | /* integer constant out of range */ | 577 | /* integer constant out of range */ | |
574 | warning(252); | 578 | warning(252); | |
575 | } | 579 | } | |
576 | } | 580 | } | |
577 | break; | 581 | break; | |
578 | case LONG: | 582 | case LONG: | |
579 | if (uq > TARG_LONG_MAX && !tflag) { | 583 | if (uq > TARG_LONG_MAX && !tflag) { | |
580 | typ = ULONG; | 584 | typ = ULONG; | |
581 | if (!sflag) | 585 | if (!sflag) | |
582 | ansiu = 1; | 586 | ansiu = 1; | |
583 | if (uq > TARG_ULONG_MAX) { | 587 | if (uq > TARG_ULONG_MAX) { | |
584 | /* integer constant out of range */ | 588 | /* integer constant out of range */ | |
585 | warning(252); | 589 | warning(252); | |
586 | } | 590 | } | |
587 | } | 591 | } | |
588 | break; | 592 | break; | |
589 | case ULONG: | 593 | case ULONG: | |
590 | if (uq > TARG_ULONG_MAX) { | 594 | if (uq > TARG_ULONG_MAX) { | |
591 | /* integer constant out of range */ | 595 | /* integer constant out of range */ | |
592 | warning(252); | 596 | warning(252); | |
593 | } | 597 | } | |
594 | break; | 598 | break; | |
595 | case QUAD: | 599 | case QUAD: | |
596 | if (uq > TARG_QUAD_MAX && !tflag) { | 600 | if (uq > TARG_QUAD_MAX && !tflag) { | |
597 | typ = UQUAD; | 601 | typ = UQUAD; | |
598 | if (!sflag) | 602 | if (!sflag) | |
599 | ansiu = 1; | 603 | ansiu = 1; | |
600 | } | 604 | } | |
601 | break; | 605 | break; | |
602 | case UQUAD: | 606 | case UQUAD: | |
603 | if (uq > TARG_UQUAD_MAX) { | 607 | if (uq > TARG_UQUAD_MAX) { | |
604 | /* integer constant out of range */ | 608 | /* integer constant out of range */ | |
605 | warning(252); | 609 | warning(252); | |
606 | } | 610 | } | |
607 | break; | 611 | break; | |
608 | /* LINTED206: (enumeration values not handled in switch) */ | 612 | /* LINTED206: (enumeration values not handled in switch) */ | |
609 | case STRUCT: | 613 | case STRUCT: | |
610 | case VOID: | 614 | case VOID: | |
611 | case LDOUBLE: | 615 | case LDOUBLE: | |
612 | case FUNC: | 616 | case FUNC: | |
613 | case ARRAY: | 617 | case ARRAY: | |
614 | case PTR: | 618 | case PTR: | |
615 | case ENUM: | 619 | case ENUM: | |
616 | case UNION: | 620 | case UNION: | |
617 | case SIGNED: | 621 | case SIGNED: | |
618 | case NOTSPEC: | 622 | case NOTSPEC: | |
619 | case DOUBLE: | 623 | case DOUBLE: | |
620 | case FLOAT: | 624 | case FLOAT: | |
621 | case USHORT: | 625 | case USHORT: | |
622 | case SHORT: | 626 | case SHORT: | |
623 | case UCHAR: | 627 | case UCHAR: | |
624 | case SCHAR: | 628 | case SCHAR: | |
625 | case CHAR: | 629 | case CHAR: | |
626 | case BOOL: | 630 | case BOOL: | |
627 | case UNSIGN: | 631 | case UNSIGN: | |
628 | case FCOMPLEX: | 632 | case FCOMPLEX: | |
629 | case DCOMPLEX: | 633 | case DCOMPLEX: | |
630 | case LCOMPLEX: | 634 | case LCOMPLEX: | |
631 | case COMPLEX: | 635 | case COMPLEX: | |
632 | break; | 636 | break; | |
633 | 637 | |||
634 | case NTSPEC: /* this value unused */ | 638 | case NTSPEC: /* this value unused */ | |
635 | break; | 639 | break; | |
636 | } | 640 | } | |
637 | 641 | |||
638 | uq = (uint64_t)xsign((int64_t)uq, typ, -1); | 642 | uq = (uint64_t)xsign((int64_t)uq, typ, -1); | |
639 | 643 | |||
640 | (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; | 644 | (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; | |
641 | yylval.y_val->v_ansiu = ansiu; | 645 | yylval.y_val->v_ansiu = ansiu; | |
642 | yylval.y_val->v_quad = (int64_t)uq; | 646 | yylval.y_val->v_quad = (int64_t)uq; | |
643 | 647 | |||
644 | return (T_CON); | 648 | return (T_CON); | |
645 | } | 649 | } | |
646 | 650 | |||
647 | /* | 651 | /* | |
648 | * Returns 1 if t is a signed type and the value is negative. | 652 | * Returns 1 if t is a signed type and the value is negative. | |
649 | * | 653 | * | |
650 | * len is the number of significant bits. If len is -1, len is set | 654 | * len is the number of significant bits. If len is -1, len is set | |
651 | * to the width of type t. | 655 | * to the width of type t. | |
652 | */ | 656 | */ | |
653 | int | 657 | int | |
654 | sign(int64_t q, tspec_t t, int len) | 658 | sign(int64_t q, tspec_t t, int len) | |
655 | { | 659 | { | |
656 | 660 | |||
657 | if (t == PTR || isutyp(t)) | 661 | if (t == PTR || isutyp(t)) | |
658 | return (0); | 662 | return (0); | |
659 | return (msb(q, t, len)); | 663 | return (msb(q, t, len)); | |
660 | } | 664 | } | |
661 | 665 | |||
662 | int | 666 | int | |
663 | msb(int64_t q, tspec_t t, int len) | 667 | msb(int64_t q, tspec_t t, int len) | |
664 | { | 668 | { | |
665 | 669 | |||
666 | if (len <= 0) | 670 | if (len <= 0) | |
667 | len = size(t); | 671 | len = size(t); | |
668 | return ((q & qbmasks[len - 1]) != 0); | 672 | return ((q & qbmasks[len - 1]) != 0); | |
669 | } | 673 | } | |
670 | 674 | |||
671 | /* | 675 | /* | |
672 | * Extends the sign of q. | 676 | * Extends the sign of q. | |
673 | */ | 677 | */ | |
674 | int64_t | 678 | int64_t | |
675 | xsign(int64_t q, tspec_t t, int len) | 679 | xsign(int64_t q, tspec_t t, int len) | |
676 | { | 680 | { | |
677 | 681 | |||
678 | if (len <= 0) | 682 | if (len <= 0) | |
679 | len = size(t); | 683 | len = size(t); | |
680 | 684 | |||
681 | if (t == PTR || isutyp(t) || !sign(q, t, len)) { | 685 | if (t == PTR || isutyp(t) || !sign(q, t, len)) { | |
682 | q &= qlmasks[len]; | 686 | q &= qlmasks[len]; | |
683 | } else { | 687 | } else { | |
684 | q |= qumasks[len]; | 688 | q |= qumasks[len]; | |
685 | } | 689 | } | |
686 | return (q); | 690 | return (q); | |
687 | } | 691 | } | |
688 | 692 | |||
689 | /* | 693 | /* | |
690 | * Convert a string representing a floating point value into its interal | 694 | * Convert a string representing a floating point value into its interal | |
691 | * representation. Type and value are returned in yylval. fcon() | 695 | * representation. Type and value are returned in yylval. fcon() | |
692 | * (and yylex()) returns T_CON. | 696 | * (and yylex()) returns T_CON. | |
693 | * XXX Currently it is not possible to convert constants of type | 697 | * XXX Currently it is not possible to convert constants of type | |
694 | * long double which are greater than DBL_MAX. | 698 | * long double which are greater than DBL_MAX. | |
695 | */ | 699 | */ | |
696 | static int | 700 | static int | |
697 | fcon(void) | 701 | fcon(void) | |
698 | { | 702 | { | |
699 | const char *cp; | 703 | const char *cp; | |
700 | int len; | 704 | int len; | |
701 | tspec_t typ; | 705 | tspec_t typ; | |
702 | char c, *eptr; | 706 | char c, *eptr; | |
703 | double d; | 707 | double d; | |
704 | float f = 0; | 708 | float f = 0; | |
705 | 709 | |||
706 | cp = yytext; | 710 | cp = yytext; | |
707 | len = yyleng; | 711 | len = yyleng; | |
708 | 712 | |||
709 | if (cp[len - 1] == 'i') { | 713 | if (cp[len - 1] == 'i') { | |
710 | /* imaginary, do nothing for now */ | 714 | /* imaginary, do nothing for now */ | |
711 | len--; | 715 | len--; | |
712 | } | 716 | } | |
713 | if ((c = cp[len - 1]) == 'f' || c == 'F') { | 717 | if ((c = cp[len - 1]) == 'f' || c == 'F') { | |
714 | typ = FLOAT; | 718 | typ = FLOAT; | |
715 | len--; | 719 | len--; | |
716 | } else if (c == 'l' || c == 'L') { | 720 | } else if (c == 'l' || c == 'L') { | |
717 | typ = LDOUBLE; | 721 | typ = LDOUBLE; | |
718 | len--; | 722 | len--; | |
719 | } else { | 723 | } else { | |
720 | if (c == 'd' || c == 'D') | 724 | if (c == 'd' || c == 'D') | |
721 | len--; | 725 | len--; | |
722 | typ = DOUBLE; | 726 | typ = DOUBLE; | |
723 | } | 727 | } | |
724 | 728 | |||
725 | if (tflag && typ != DOUBLE) { | 729 | if (tflag && typ != DOUBLE) { | |
726 | /* suffixes F and L are illegal in traditional C */ | 730 | /* suffixes F and L are illegal in traditional C */ | |
727 | warning(98); | 731 | warning(98); | |
728 | } | 732 | } | |
729 | 733 | |||
730 | errno = 0; | 734 | errno = 0; | |
731 | d = strtod(cp, &eptr); | 735 | d = strtod(cp, &eptr); | |
732 | if (eptr != cp + len) { | 736 | if (eptr != cp + len) { | |
733 | switch (*eptr) { | 737 | switch (*eptr) { | |
734 | /* | 738 | /* | |
735 | * XXX: non-native non-current strtod() may not handle hex | 739 | * XXX: non-native non-current strtod() may not handle hex | |
736 | * floats, ignore the rest if we find traces of hex float | 740 | * floats, ignore the rest if we find traces of hex float | |
737 | * syntax... | 741 | * syntax... | |
738 | */ | 742 | */ | |
739 | case 'p': | 743 | case 'p': | |
740 | case 'P': | 744 | case 'P': | |
741 | case 'x': | 745 | case 'x': | |
742 | case 'X': | 746 | case 'X': | |
743 | d = 0; | 747 | d = 0; | |
744 | errno = 0; | 748 | errno = 0; | |
745 | break; | 749 | break; | |
746 | default: | 750 | default: | |
747 | LERROR("fcon(%s->%s)", cp, eptr); | 751 | LERROR("fcon(%s->%s)", cp, eptr); | |
748 | } | 752 | } | |
749 | } | 753 | } | |
750 | if (errno != 0) | 754 | if (errno != 0) | |
751 | /* floating-point constant out of range */ | 755 | /* floating-point constant out of range */ | |
752 | warning(248); | 756 | warning(248); | |
753 | 757 | |||
754 | if (typ == FLOAT) { | 758 | if (typ == FLOAT) { | |
755 | f = (float)d; | 759 | f = (float)d; | |
756 | if (!finite(f)) { | 760 | if (!finite(f)) { | |
757 | /* floating-point constant out of range */ | 761 | /* floating-point constant out of range */ | |
758 | warning(248); | 762 | warning(248); | |
759 | f = f > 0 ? FLT_MAX : -FLT_MAX; | 763 | f = f > 0 ? FLT_MAX : -FLT_MAX; | |
760 | } | 764 | } | |
761 | } | 765 | } | |
762 | 766 | |||
763 | (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; | 767 | (yylval.y_val = xcalloc(1, sizeof (val_t)))->v_tspec = typ; | |
764 | if (typ == FLOAT) { | 768 | if (typ == FLOAT) { | |
765 | yylval.y_val->v_ldbl = f; | 769 | yylval.y_val->v_ldbl = f; | |
766 | } else { | 770 | } else { | |
767 | yylval.y_val->v_ldbl = d; | 771 | yylval.y_val->v_ldbl = d; | |
768 | } | 772 | } | |
769 | 773 | |||
770 | return (T_CON); | 774 | return (T_CON); | |
771 | } | 775 | } | |
772 | 776 | |||
773 | static int | 777 | static int | |
774 | operator(int t, op_t o) | 778 | operator(int t, op_t o) | |
775 | { | 779 | { | |
776 | 780 | |||
777 | yylval.y_op = o; | 781 | yylval.y_op = o; | |
778 | return (t); | 782 | return (t); | |
779 | } | 783 | } | |
780 | 784 | |||
781 | /* | 785 | /* | |
782 | * Called if lex found a leading \'. | 786 | * Called if lex found a leading \'. | |
783 | */ | 787 | */ | |
784 | static int | 788 | static int | |
785 | ccon(void) | 789 | ccon(void) | |
786 | { | 790 | { | |
787 | size_t n; | 791 | size_t n; | |
788 | int val, c; | 792 | int val, c; | |
789 | char cv; | 793 | char cv; | |
790 | 794 | |||
791 | n = 0; | 795 | n = 0; | |
792 | val = 0; | 796 | val = 0; | |
793 | while ((c = getescc('\'')) >= 0) { | 797 | while ((c = getescc('\'')) >= 0) { | |
794 | val = (val << CHAR_BIT) + c; | 798 | val = (val << CHAR_BIT) + c; | |
795 | n++; | 799 | n++; | |
796 | } | 800 | } | |
797 | if (c == -2) { | 801 | if (c == -2) { | |
798 | /* unterminated character constant */ | 802 | /* unterminated character constant */ | |
799 | error(253); | 803 | error(253); | |
800 | } else { | 804 | } else { | |
801 | if (n > sizeof (int) || (n > 1 && (pflag || hflag))) { | 805 | if (n > sizeof (int) || (n > 1 && (pflag || hflag))) { | |
802 | /* too many characters in character constant */ | 806 | /* too many characters in character constant */ | |
803 | error(71); | 807 | error(71); | |
804 | } else if (n > 1) { | 808 | } else if (n > 1) { | |
805 | /* multi-character character constant */ | 809 | /* multi-character character constant */ | |
806 | warning(294); | 810 | warning(294); | |
807 | } else if (n == 0) { | 811 | } else if (n == 0) { | |
808 | /* empty character constant */ | 812 | /* empty character constant */ | |
809 | error(73); | 813 | error(73); | |
810 | } | 814 | } | |
811 | } | 815 | } | |
812 | if (n == 1) { | 816 | if (n == 1) { | |
813 | cv = (char)val; | 817 | cv = (char)val; | |
814 | val = cv; | 818 | val = cv; | |
815 | } | 819 | } | |
816 | 820 | |||
817 | yylval.y_val = xcalloc(1, sizeof (val_t)); | 821 | yylval.y_val = xcalloc(1, sizeof (val_t)); | |
818 | yylval.y_val->v_tspec = INT; | 822 | yylval.y_val->v_tspec = INT; | |
819 | yylval.y_val->v_quad = val; | 823 | yylval.y_val->v_quad = val; | |
820 | 824 | |||
821 | return (T_CON); | 825 | return (T_CON); | |
822 | } | 826 | } | |
823 | 827 | |||
824 | /* | 828 | /* | |
825 | * Called if lex found a leading L\' | 829 | * Called if lex found a leading L\' | |
826 | */ | 830 | */ | |
827 | static int | 831 | static int | |
828 | wccon(void) | 832 | wccon(void) | |
829 | { | 833 | { | |
830 | static char buf[MB_LEN_MAX + 1]; | 834 | static char buf[MB_LEN_MAX + 1]; | |
831 | size_t i; | 835 | size_t i; | |
832 | int c; | 836 | int c; | |
833 | wchar_t wc; | 837 | wchar_t wc; | |
834 | 838 | |||
835 | i = 0; | 839 | i = 0; | |
836 | while ((c = getescc('\'')) >= 0) { | 840 | while ((c = getescc('\'')) >= 0) { | |
837 | if (i < MB_CUR_MAX) | 841 | if (i < MB_CUR_MAX) | |
838 | buf[i] = (char)c; | 842 | buf[i] = (char)c; | |
839 | i++; | 843 | i++; | |
840 | } | 844 | } | |
841 | 845 | |||
842 | wc = 0; | 846 | wc = 0; | |
843 | 847 | |||
844 | if (c == -2) { | 848 | if (c == -2) { | |
845 | /* unterminated character constant */ | 849 | /* unterminated character constant */ | |
846 | error(253); | 850 | error(253); | |
847 | } else if (c == 0) { | 851 | } else if (c == 0) { | |
848 | /* empty character constant */ | 852 | /* empty character constant */ | |
849 | error(73); | 853 | error(73); | |
850 | } else { | 854 | } else { | |
851 | if (i > MB_CUR_MAX) { | 855 | if (i > MB_CUR_MAX) { | |
852 | i = MB_CUR_MAX; | 856 | i = MB_CUR_MAX; | |
853 | /* too many characters in character constant */ | 857 | /* too many characters in character constant */ | |
854 | error(71); | 858 | error(71); | |
855 | } else { | 859 | } else { | |
856 | buf[i] = '\0'; | 860 | buf[i] = '\0'; | |
857 | (void)mbtowc(NULL, NULL, 0); | 861 | (void)mbtowc(NULL, NULL, 0); | |
858 | if (mbtowc(&wc, buf, MB_CUR_MAX) < 0) | 862 | if (mbtowc(&wc, buf, MB_CUR_MAX) < 0) | |
859 | /* invalid multibyte character */ | 863 | /* invalid multibyte character */ | |
860 | error(291); | 864 | error(291); | |
861 | } | 865 | } | |
862 | } | 866 | } | |
863 | 867 | |||
864 | yylval.y_val = xcalloc(1, sizeof (val_t)); | 868 | yylval.y_val = xcalloc(1, sizeof (val_t)); | |
865 | yylval.y_val->v_tspec = WCHAR; | 869 | yylval.y_val->v_tspec = WCHAR; | |
866 | yylval.y_val->v_quad = wc; | 870 | yylval.y_val->v_quad = wc; | |
867 | 871 | |||
868 | return (T_CON); | 872 | return (T_CON); | |
869 | } | 873 | } | |
870 | 874 | |||
871 | /* | 875 | /* | |
872 | * Read a character which is part of a character constant or of a string | 876 | * Read a character which is part of a character constant or of a string | |
873 | * and handle escapes. | 877 | * and handle escapes. | |
874 | * | 878 | * | |
875 | * The Argument is the character which delimits the character constant or | 879 | * The Argument is the character which delimits the character constant or | |
876 | * string. | 880 | * string. | |
877 | * | 881 | * | |
878 | * Returns -1 if the end of the character constant or string is reached, | 882 | * Returns -1 if the end of the character constant or string is reached, | |
879 | * -2 if the EOF is reached, and the character otherwise. | 883 | * -2 if the EOF is reached, and the character otherwise. | |
880 | */ | 884 | */ | |
881 | static int | 885 | static int | |
882 | getescc(int d) | 886 | getescc(int d) | |
883 | { | 887 | { | |
884 | static int pbc = -1; | 888 | static int pbc = -1; | |
885 | int n, c, v; | 889 | int n, c, v; | |
886 | 890 | |||
887 | if (pbc == -1) { | 891 | if (pbc == -1) { | |
888 | c = inpc(); | 892 | c = inpc(); | |
889 | } else { | 893 | } else { | |
890 | c = pbc; | 894 | c = pbc; | |
891 | pbc = -1; | 895 | pbc = -1; | |
892 | } | 896 | } | |
893 | if (c == d) | 897 | if (c == d) | |
894 | return (-1); | 898 | return (-1); | |
895 | switch (c) { | 899 | switch (c) { | |
896 | case '\n': | 900 | case '\n': | |
897 | if (tflag) { | 901 | if (tflag) { | |
898 | /* newline in string or char constant */ | 902 | /* newline in string or char constant */ | |
899 | error(254); | 903 | error(254); | |
900 | return (-2); | 904 | return (-2); | |
901 | } | 905 | } | |
902 | return (c); | 906 | return (c); | |
903 | case EOF: | 907 | case EOF: | |
904 | return (-2); | 908 | return (-2); | |
905 | case '\\': | 909 | case '\\': | |
906 | switch (c = inpc()) { | 910 | switch (c = inpc()) { | |
907 | case '"': | 911 | case '"': | |
908 | if (tflag && d == '\'') | 912 | if (tflag && d == '\'') | |
909 | /* \" inside character constant undef. ... */ | 913 | /* \" inside character constant undef. ... */ | |
910 | warning(262); | 914 | warning(262); | |
911 | return ('"'); | 915 | return ('"'); | |
912 | case '\'': | 916 | case '\'': | |
913 | return ('\''); | 917 | return ('\''); | |
914 | case '?': | 918 | case '?': | |
915 | if (tflag) | 919 | if (tflag) | |
916 | /* \? undefined in traditional C */ | 920 | /* \? undefined in traditional C */ | |
917 | warning(263); | 921 | warning(263); | |
918 | return ('?'); | 922 | return ('?'); | |
919 | case '\\': | 923 | case '\\': | |
920 | return ('\\'); | 924 | return ('\\'); | |
921 | case 'a': | 925 | case 'a': | |
922 | if (tflag) | 926 | if (tflag) | |
923 | /* \a undefined in traditional C */ | 927 | /* \a undefined in traditional C */ | |
924 | warning(81); | 928 | warning(81); | |
925 | return ('\a'); | 929 | return ('\a'); | |
926 | case 'b': | 930 | case 'b': | |
927 | return ('\b'); | 931 | return ('\b'); | |
928 | case 'f': | 932 | case 'f': | |
929 | return ('\f'); | 933 | return ('\f'); | |
930 | case 'n': | 934 | case 'n': | |
931 | return ('\n'); | 935 | return ('\n'); | |
932 | case 'r': | 936 | case 'r': | |
933 | return ('\r'); | 937 | return ('\r'); | |
934 | case 't': | 938 | case 't': | |
935 | return ('\t'); | 939 | return ('\t'); | |
936 | case 'v': | 940 | case 'v': | |
937 | if (tflag) | 941 | if (tflag) | |
938 | /* \v undefined in traditional C */ | 942 | /* \v undefined in traditional C */ | |
939 | warning(264); | 943 | warning(264); | |
940 | return ('\v'); | 944 | return ('\v'); | |
941 | case '8': case '9': | 945 | case '8': case '9': | |
942 | /* bad octal digit %c */ | 946 | /* bad octal digit %c */ | |
943 | warning(77, c); | 947 | warning(77, c); | |
944 | /* FALLTHROUGH */ | 948 | /* FALLTHROUGH */ | |
945 | case '0': case '1': case '2': case '3': | 949 | case '0': case '1': case '2': case '3': | |
946 | case '4': case '5': case '6': case '7': | 950 | case '4': case '5': case '6': case '7': | |
947 | n = 3; | 951 | n = 3; | |
948 | v = 0; | 952 | v = 0; | |
949 | do { | 953 | do { | |
950 | v = (v << 3) + (c - '0'); | 954 | v = (v << 3) + (c - '0'); | |
951 | c = inpc(); | 955 | c = inpc(); | |
952 | } while (--n && isdigit(c) && (tflag || c <= '7')); | 956 | } while (--n && isdigit(c) && (tflag || c <= '7')); | |
953 | if (tflag && n > 0 && isdigit(c)) | 957 | if (tflag && n > 0 && isdigit(c)) | |
954 | /* bad octal digit %c */ | 958 | /* bad octal digit %c */ | |
955 | warning(77, c); | 959 | warning(77, c); | |
956 | pbc = c; | 960 | pbc = c; | |
957 | if (v > TARG_UCHAR_MAX) { | 961 | if (v > TARG_UCHAR_MAX) { | |
958 | /* character escape does not fit in char. */ | 962 | /* character escape does not fit in char. */ | |
959 | warning(76); | 963 | warning(76); | |
960 | v &= CHAR_MASK; | 964 | v &= CHAR_MASK; | |
961 | } | 965 | } | |
962 | return (v); | 966 | return (v); | |
963 | case 'x': | 967 | case 'x': | |
964 | if (tflag) | 968 | if (tflag) | |
965 | /* \x undefined in traditional C */ | 969 | /* \x undefined in traditional C */ | |
966 | warning(82); | 970 | warning(82); | |
967 | v = 0; | 971 | v = 0; | |
968 | n = 0; | 972 | n = 0; | |
969 | while ((c = inpc()) >= 0 && isxdigit(c)) { | 973 | while ((c = inpc()) >= 0 && isxdigit(c)) { | |
970 | c = isdigit(c) ? | 974 | c = isdigit(c) ? | |
971 | c - '0' : toupper(c) - 'A' + 10; | 975 | c - '0' : toupper(c) - 'A' + 10; | |
972 | v = (v << 4) + c; | 976 | v = (v << 4) + c; | |
973 | if (n >= 0) { | 977 | if (n >= 0) { | |
974 | if ((v & ~CHAR_MASK) != 0) { | 978 | if ((v & ~CHAR_MASK) != 0) { | |
975 | /* overflow in hex escape */ | 979 | /* overflow in hex escape */ | |
976 | warning(75); | 980 | warning(75); | |
977 | n = -1; | 981 | n = -1; | |
978 | } else { | 982 | } else { | |
979 | n++; | 983 | n++; | |
980 | } | 984 | } | |
981 | } | 985 | } | |
982 | } | 986 | } | |
983 | pbc = c; | 987 | pbc = c; | |
984 | if (n == 0) { | 988 | if (n == 0) { | |
985 | /* no hex digits follow \x */ | 989 | /* no hex digits follow \x */ | |
986 | error(74); | 990 | error(74); | |
987 | } if (n == -1) { | 991 | } if (n == -1) { | |
988 | v &= CHAR_MASK; | 992 | v &= CHAR_MASK; | |
989 | } | 993 | } | |
990 | return (v); | 994 | return (v); | |
991 | case '\n': | 995 | case '\n': | |
992 | return (getescc(d)); | 996 | return (getescc(d)); | |
993 | case EOF: | 997 | case EOF: | |
994 | return (-2); | 998 | return (-2); | |
995 | default: | 999 | default: | |
996 | if (isprint(c)) { | 1000 | if (isprint(c)) { | |
997 | /* dubious escape \%c */ | 1001 | /* dubious escape \%c */ | |
998 | warning(79, c); | 1002 | warning(79, c); | |
999 | } else { | 1003 | } else { | |
1000 | /* dubious escape \%o */ | 1004 | /* dubious escape \%o */ | |
1001 | warning(80, c); | 1005 | warning(80, c); | |
1002 | } | 1006 | } | |
1003 | } | 1007 | } | |
1004 | } | 1008 | } | |
1005 | return (c); | 1009 | return (c); | |
1006 | } | 1010 | } | |
1007 | 1011 | |||
1008 | /* | 1012 | /* | |
1009 | * Called for preprocessor directives. Currently implemented are: | 1013 | * Called for preprocessor directives. Currently implemented are: | |
1010 | * # lineno | 1014 | * # lineno | |
1011 | * # lineno "filename" | 1015 | * # lineno "filename" | |
1012 | */ | 1016 | */ | |
1013 | static void | 1017 | static void | |
1014 | directive(void) | 1018 | directive(void) | |
1015 | { | 1019 | { | |
1016 | const char *cp, *fn; | 1020 | const char *cp, *fn; | |
1017 | char c, *eptr; | 1021 | char c, *eptr; | |
1018 | size_t fnl; | 1022 | size_t fnl; | |
1019 | long ln; | 1023 | long ln; | |
1020 | static int first = 1; | 1024 | static int first = 1; | |
1021 | 1025 | |||
1022 | /* Go to first non-whitespace after # */ | 1026 | /* Go to first non-whitespace after # */ | |
1023 | for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) | 1027 | for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) | |
1024 | continue; | 1028 | continue; | |
1025 | 1029 | |||
1026 | if (!isdigit((unsigned char)c)) { | 1030 | if (!isdigit((unsigned char)c)) { | |
1027 | error: | 1031 | error: | |
1028 | /* undefined or invalid # directive */ | 1032 | /* undefined or invalid # directive */ | |
1029 | warning(255); | 1033 | warning(255); | |
1030 | return; | 1034 | return; | |
1031 | } | 1035 | } | |
1032 | ln = strtol(--cp, &eptr, 10); | 1036 | ln = strtol(--cp, &eptr, 10); | |
1033 | if (cp == eptr) | 1037 | if (cp == eptr) | |
1034 | goto error; | 1038 | goto error; | |
1035 | if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0') | 1039 | if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0') | |
1036 | goto error; | 1040 | goto error; | |
1037 | while ((c = *cp++) == ' ' || c == '\t') | 1041 | while ((c = *cp++) == ' ' || c == '\t') | |
1038 | continue; | 1042 | continue; | |
1039 | if (c != '\0') { | 1043 | if (c != '\0') { | |
1040 | if (c != '"') | 1044 | if (c != '"') | |
1041 | goto error; | 1045 | goto error; | |
1042 | fn = cp; | 1046 | fn = cp; | |
1043 | while ((c = *cp) != '"' && c != '\0') | 1047 | while ((c = *cp) != '"' && c != '\0') | |
1044 | cp++; | 1048 | cp++; | |
1045 | if (c != '"') | 1049 | if (c != '"') | |
1046 | goto error; | 1050 | goto error; | |
1047 | if ((fnl = cp++ - fn) > PATH_MAX) | 1051 | if ((fnl = cp++ - fn) > PATH_MAX) | |
1048 | goto error; | 1052 | goto error; | |
1049 | while ((c = *cp++) == ' ' || c == '\t') | 1053 | while ((c = *cp++) == ' ' || c == '\t') | |
1050 | continue; | 1054 | continue; | |
1051 | #if 0 | 1055 | #if 0 | |
1052 | if (c != '\0') | 1056 | if (c != '\0') | |
1053 | warning("extra character(s) after directive"); | 1057 | warning("extra character(s) after directive"); | |
1054 | #endif | 1058 | #endif | |
1055 | 1059 | |||
1056 | /* empty string means stdin */ | 1060 | /* empty string means stdin */ | |
1057 | if (fnl == 0) { | 1061 | if (fnl == 0) { | |
1058 | fn = "{standard input}"; | 1062 | fn = "{standard input}"; | |
1059 | fnl = 16; /* strlen (fn) */ | 1063 | fnl = 16; /* strlen (fn) */ | |
1060 | } | 1064 | } | |
1061 | curr_pos.p_file = fnnalloc(fn, fnl); | 1065 | curr_pos.p_file = fnnalloc(fn, fnl); | |
1062 | /* | 1066 | /* | |
1063 | * If this is the first directive, the name is the name | 1067 | * If this is the first directive, the name is the name | |
1064 | * of the C source file as specified at the command line. | 1068 | * of the C source file as specified at the command line. | |
1065 | * It is written to the output file. | 1069 | * It is written to the output file. | |
1066 | */ | 1070 | */ | |
1067 | if (first) { | 1071 | if (first) { | |
1068 | csrc_pos.p_file = curr_pos.p_file; | 1072 | csrc_pos.p_file = curr_pos.p_file; | |
1069 | outsrc(curr_pos.p_file); | 1073 | outsrc(curr_pos.p_file); | |
1070 | first = 0; | 1074 | first = 0; | |
1071 | } | 1075 | } | |
1072 | } | 1076 | } | |
1073 | curr_pos.p_line = (int)ln - 1; | 1077 | curr_pos.p_line = (int)ln - 1; | |
1074 | curr_pos.p_uniq = 0; | 1078 | curr_pos.p_uniq = 0; | |
1075 | if (curr_pos.p_file == csrc_pos.p_file) { | 1079 | if (curr_pos.p_file == csrc_pos.p_file) { | |
1076 | csrc_pos.p_line = (int)ln - 1; | 1080 | csrc_pos.p_line = (int)ln - 1; | |
1077 | csrc_pos.p_uniq = 0; | 1081 | csrc_pos.p_uniq = 0; | |
1078 | } | 1082 | } | |
1079 | } | 1083 | } | |
1080 | 1084 | |||
1081 | /* | 1085 | /* | |
1082 | * Handle lint comments. Following comments are currently understood: | 1086 | * Handle lint comments. Following comments are currently understood: | |
1083 | * ARGSUSEDn | 1087 | * ARGSUSEDn | |
1084 | * BITFIELDTYPE | 1088 | * BITFIELDTYPE | |
1085 | * CONSTCOND CONSTANTCOND CONSTANTCONDITION | 1089 | * CONSTCOND CONSTANTCOND CONSTANTCONDITION | |
1086 | * FALLTHRU FALLTHROUGH | 1090 | * FALLTHRU FALLTHROUGH | |
1087 | * LINTLIBRARY | 1091 | * LINTLIBRARY | |
1088 | * LINTEDn NOSTRICTn | 1092 | * LINTEDn NOSTRICTn | |
1089 | * LONGLONG | 1093 | * LONGLONG | |
1090 | * NOTREACHED | 1094 | * NOTREACHED | |
1091 | * PRINTFLIKEn | 1095 | * PRINTFLIKEn | |
1092 | * PROTOLIB | 1096 | * PROTOLIB | |
1093 | * SCANFLIKEn | 1097 | * SCANFLIKEn | |
1094 | * VARARGSn | 1098 | * VARARGSn | |
1095 | * If one of this comments is recognized, the arguments, if any, are | 1099 | * If one of this comments is recognized, the arguments, if any, are | |
1096 | * parsed and a function which handles this comment is called. | 1100 | * parsed and a function which handles this comment is called. | |
1097 | */ | 1101 | */ | |
1098 | static void | 1102 | static void | |
1099 | comment(void) | 1103 | comment(void) | |
1100 | { | 1104 | { | |
1101 | int c, lc; | 1105 | int c, lc; | |
1102 | static struct { | 1106 | static struct { | |
1103 | const char *keywd; | 1107 | const char *keywd; | |
1104 | int arg; | 1108 | int arg; | |
1105 | void (*func)(int); | 1109 | void (*func)(int); | |
1106 | } keywtab[] = { | 1110 | } keywtab[] = { | |
1107 | { "ARGSUSED", 1, argsused }, | 1111 | { "ARGSUSED", 1, argsused }, | |
1108 | { "BITFIELDTYPE", 0, bitfieldtype }, | 1112 | { "BITFIELDTYPE", 0, bitfieldtype }, | |
1109 | { "CONSTCOND", 0, constcond }, | 1113 | { "CONSTCOND", 0, constcond }, | |
1110 | { "CONSTANTCOND", 0, constcond }, | 1114 | { "CONSTANTCOND", 0, constcond }, | |
1111 | { "CONSTANTCONDITION", 0, constcond }, | 1115 | { "CONSTANTCONDITION", 0, constcond }, | |
1112 | { "FALLTHRU", 0, fallthru }, | 1116 | { "FALLTHRU", 0, fallthru }, | |
1113 | { "FALLTHROUGH", 0, fallthru }, | 1117 | { "FALLTHROUGH", 0, fallthru }, | |
1114 | { "LINTLIBRARY", 0, lintlib }, | 1118 | { "LINTLIBRARY", 0, lintlib }, | |
1115 | { "LINTED", 1, linted }, | 1119 | { "LINTED", 1, linted }, | |
1116 | { "LONGLONG", 0, longlong }, | 1120 | { "LONGLONG", 0, longlong }, | |
1117 | { "NOSTRICT", 1, linted }, | 1121 | { "NOSTRICT", 1, linted }, | |
1118 | { "NOTREACHED", 0, notreach }, | 1122 | { "NOTREACHED", 0, notreach }, | |
1119 | { "PRINTFLIKE", 1, printflike }, | 1123 | { "PRINTFLIKE", 1, printflike }, | |
1120 | { "PROTOLIB", 1, protolib }, | 1124 | { "PROTOLIB", 1, protolib }, | |
1121 | { "SCANFLIKE", 1, scanflike }, | 1125 | { "SCANFLIKE", 1, scanflike }, | |
1122 | { "VARARGS", 1, varargs }, | 1126 | { "VARARGS", 1, varargs }, | |
1123 | }; | 1127 | }; | |
1124 | char keywd[32]; | 1128 | char keywd[32]; | |
1125 | char arg[32]; | 1129 | char arg[32]; | |
1126 | size_t l, i; | 1130 | size_t l, i; | |
1127 | int a; | 1131 | int a; | |
1128 | int eoc; | 1132 | int eoc; | |
1129 | 1133 | |||
1130 | eoc = 0; | 1134 | eoc = 0; | |
1131 | 1135 | |||
1132 | /* Skip white spaces after the start of the comment */ | 1136 | /* Skip white spaces after the start of the comment */ | |
1133 | while ((c = inpc()) != EOF && isspace(c)) | 1137 | while ((c = inpc()) != EOF && isspace(c)) | |
1134 | continue; | 1138 | continue; | |
1135 | 1139 | |||
1136 | /* Read the potential keyword to keywd */ | 1140 | /* Read the potential keyword to keywd */ | |
1137 | l = 0; | 1141 | l = 0; | |
1138 | while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) { | 1142 | while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) { | |
1139 | keywd[l++] = (char)c; | 1143 | keywd[l++] = (char)c; | |
1140 | c = inpc(); | 1144 | c = inpc(); | |
1141 | } | 1145 | } | |
1142 | keywd[l] = '\0'; | 1146 | keywd[l] = '\0'; | |
1143 | 1147 | |||
1144 | /* look for the keyword */ | 1148 | /* look for the keyword */ | |
1145 | for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) { | 1149 | for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) { | |
1146 | if (strcmp(keywtab[i].keywd, keywd) == 0) | 1150 | if (strcmp(keywtab[i].keywd, keywd) == 0) | |
1147 | break; | 1151 | break; | |
1148 | } | 1152 | } | |
1149 | if (i == sizeof (keywtab) / sizeof (keywtab[0])) | 1153 | if (i == sizeof (keywtab) / sizeof (keywtab[0])) | |
1150 | goto skip_rest; | 1154 | goto skip_rest; | |
1151 | 1155 | |||
1152 | /* skip white spaces after the keyword */ | 1156 | /* skip white spaces after the keyword */ | |
1153 | while (c != EOF && isspace(c)) | 1157 | while (c != EOF && isspace(c)) | |
1154 | c = inpc(); | 1158 | c = inpc(); | |
1155 | 1159 | |||
1156 | /* read the argument, if the keyword accepts one and there is one */ | 1160 | /* read the argument, if the keyword accepts one and there is one */ | |
1157 | l = 0; | 1161 | l = 0; | |
1158 | if (keywtab[i].arg) { | 1162 | if (keywtab[i].arg) { | |
1159 | while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) { | 1163 | while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) { | |
1160 | arg[l++] = (char)c; | 1164 | arg[l++] = (char)c; | |
1161 | c = inpc(); | 1165 | c = inpc(); | |
1162 | } | 1166 | } | |
1163 | } | 1167 | } | |
1164 | arg[l] = '\0'; | 1168 | arg[l] = '\0'; | |
1165 | a = l != 0 ? atoi(arg) : -1; | 1169 | a = l != 0 ? atoi(arg) : -1; | |
1166 | 1170 | |||
1167 | /* skip white spaces after the argument */ | 1171 | /* skip white spaces after the argument */ | |
1168 | while (c != EOF && isspace(c)) | 1172 | while (c != EOF && isspace(c)) | |
1169 | c = inpc(); | 1173 | c = inpc(); | |
1170 | 1174 | |||
1171 | if (c != '*' || (c = inpc()) != '/') { | 1175 | if (c != '*' || (c = inpc()) != '/') { | |
1172 | if (keywtab[i].func != linted) | 1176 | if (keywtab[i].func != linted) | |
1173 | /* extra characters in lint comment */ | 1177 | /* extra characters in lint comment */ | |
1174 | warning(257); | 1178 | warning(257); | |
1175 | } else { | 1179 | } else { | |
1176 | /* | 1180 | /* | |
1177 | * remember that we have already found the end of the | 1181 | * remember that we have already found the end of the | |
1178 | * comment | 1182 | * comment | |
1179 | */ | 1183 | */ | |
1180 | eoc = 1; | 1184 | eoc = 1; | |
1181 | } | 1185 | } | |
1182 | 1186 | |||
1183 | if (keywtab[i].func != NULL) | 1187 | if (keywtab[i].func != NULL) | |
1184 | (*keywtab[i].func)(a); | 1188 | (*keywtab[i].func)(a); | |
1185 | 1189 | |||
1186 | skip_rest: | 1190 | skip_rest: | |
1187 | while (!eoc) { | 1191 | while (!eoc) { | |
1188 | lc = c; | 1192 | lc = c; | |
1189 | if ((c = inpc()) == EOF) { | 1193 | if ((c = inpc()) == EOF) { | |
1190 | /* unterminated comment */ | 1194 | /* unterminated comment */ | |
1191 | error(256); | 1195 | error(256); | |
1192 | break; | 1196 | break; | |
1193 | } | 1197 | } | |
1194 | if (lc == '*' && c == '/') | 1198 | if (lc == '*' && c == '/') | |
1195 | eoc = 1; | 1199 | eoc = 1; | |
1196 | } | 1200 | } | |
1197 | } | 1201 | } | |
1198 | 1202 | |||
1199 | /* | 1203 | /* | |
1200 | * Handle // style comments | 1204 | * Handle // style comments | |
1201 | */ | 1205 | */ | |
1202 | static void | 1206 | static void | |
1203 | slashslashcomment(void) | 1207 | slashslashcomment(void) | |
1204 | { | 1208 | { | |
1205 | int c; | 1209 | int c; | |
1206 | 1210 | |||
1207 | if (!Sflag && !gflag) | 1211 | if (!Sflag && !gflag) | |
1208 | /* // comments only supported in C99 */ | 1212 | /* // comments only supported in C99 */ | |
1209 | (void)gnuism(312, tflag ? "traditional" : "ANSI"); | 1213 | (void)gnuism(312, tflag ? "traditional" : "ANSI"); | |
1210 | 1214 | |||
1211 | while ((c = inpc()) != EOF && c != '\n') | 1215 | while ((c = inpc()) != EOF && c != '\n') | |
1212 | continue; | 1216 | continue; | |
1213 | } | 1217 | } | |
1214 | 1218 | |||
1215 | /* | 1219 | /* | |
1216 | * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND. | 1220 | * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND. | |
1217 | * clrwflgs() is called after function definitions and global and | 1221 | * clrwflgs() is called after function definitions and global and | |
1218 | * local declarations and definitions. It is also called between | 1222 | * local declarations and definitions. It is also called between | |
1219 | * the controlling expression and the body of control statements | 1223 | * the controlling expression and the body of control statements | |
1220 | * (if, switch, for, while). | 1224 | * (if, switch, for, while). | |
1221 | */ | 1225 | */ | |
1222 | void | 1226 | void | |
1223 | clrwflgs(void) | 1227 | clrwflgs(void) | |
1224 | { | 1228 | { | |
1225 | 1229 | |||
1226 | lwarn = LWARN_ALL; | 1230 | lwarn = LWARN_ALL; | |
1227 | quadflg = 0; | 1231 | quadflg = 0; | |
1228 | ccflg = 0; | 1232 | ccflg = 0; | |
1229 | } | 1233 | } | |
1230 | 1234 | |||
1231 | /* | 1235 | /* | |
1232 | * Strings are stored in a dynamically alloceted buffer and passed | 1236 | * Strings are stored in a dynamically alloceted buffer and passed | |
1233 | * in yylval.y_xstrg to the parser. The parser or the routines called | 1237 | * in yylval.y_xstrg to the parser. The parser or the routines called | |
1234 | * by the parser are responsible for freeing this buffer. | 1238 | * by the parser are responsible for freeing this buffer. | |
1235 | */ | 1239 | */ | |
1236 | static int | 1240 | static int | |
1237 | string(void) | 1241 | string(void) | |
1238 | { | 1242 | { | |
1239 | u_char *s; | 1243 | u_char *s; | |
1240 | int c; | 1244 | int c; | |
1241 | size_t len, max; | 1245 | size_t len, max; | |
1242 | strg_t *strg; | 1246 | strg_t *strg; | |
1243 | 1247 | |||
1244 | s = xmalloc(max = 64); | 1248 | s = xmalloc(max = 64); | |
1245 | 1249 | |||
1246 | len = 0; | 1250 | len = 0; | |
1247 | while ((c = getescc('"')) >= 0) { | 1251 | while ((c = getescc('"')) >= 0) { | |
1248 | /* +1 to reserve space for a trailing NUL character */ | 1252 | /* +1 to reserve space for a trailing NUL character */ | |
1249 | if (len + 1 == max) | 1253 | if (len + 1 == max) | |
1250 | s = xrealloc(s, max *= 2); | 1254 | s = xrealloc(s, max *= 2); | |
1251 | s[len++] = (char)c; | 1255 | s[len++] = (char)c; | |
1252 | } | 1256 | } | |
1253 | s[len] = '\0'; | 1257 | s[len] = '\0'; | |
1254 | if (c == -2) | 1258 | if (c == -2) | |
1255 | /* unterminated string constant */ | 1259 | /* unterminated string constant */ | |
1256 | error(258); | 1260 | error(258); | |
1257 | 1261 |
--- src/usr.bin/xlint/lint1/tree.c 2014/02/18 20:43:36 1.74
+++ src/usr.bin/xlint/lint1/tree.c 2014/02/18 22:01:36 1.75
@@ -1,1039 +1,1039 @@ | @@ -1,1039 +1,1039 @@ | |||
1 | /* $NetBSD: tree.c,v 1.74 2014/02/18 20:43:36 christos Exp $ */ | 1 | /* $NetBSD: tree.c,v 1.75 2014/02/18 22:01:36 christos Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 1994, 1995 Jochen Pohl | 4 | * Copyright (c) 1994, 1995 Jochen Pohl | |
5 | * All Rights Reserved. | 5 | * All Rights Reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
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.74 2014/02/18 20:43:36 christos Exp $"); | 40 | __RCSID("$NetBSD: tree.c,v 1.75 2014/02/18 22:01:36 christos Exp $"); | |
41 | #endif | 41 | #endif | |
42 | 42 | |||
43 | #include <stdlib.h> | 43 | #include <stdlib.h> | |
44 | #include <string.h> | 44 | #include <string.h> | |
45 | #include <float.h> | 45 | #include <float.h> | |
46 | #include <limits.h> | 46 | #include <limits.h> | |
47 | #include <math.h> | 47 | #include <math.h> | |
48 | #include <signal.h> | 48 | #include <signal.h> | |
49 | 49 | |||
50 | #include "lint1.h" | 50 | #include "lint1.h" | |
51 | #include "cgram.h" | 51 | #include "cgram.h" | |
52 | #include "externs1.h" | 52 | #include "externs1.h" | |
53 | 53 | |||
54 | static tnode_t *getinode(tspec_t, int64_t); | 54 | static tnode_t *getinode(tspec_t, int64_t); | |
55 | static void ptrcmpok(op_t, tnode_t *, tnode_t *); | 55 | static void ptrcmpok(op_t, tnode_t *, tnode_t *); | |
56 | static int asgntypok(op_t, int, tnode_t *, tnode_t *); | 56 | static int asgntypok(op_t, int, tnode_t *, tnode_t *); | |
57 | static void chkbeop(op_t, tnode_t *, tnode_t *); | 57 | static void chkbeop(op_t, tnode_t *, tnode_t *); | |
58 | static void chkeop2(op_t, int, tnode_t *, tnode_t *); | 58 | static void chkeop2(op_t, int, tnode_t *, tnode_t *); | |
59 | static void chkeop1(op_t, int, tnode_t *, tnode_t *); | 59 | static void chkeop1(op_t, int, tnode_t *, tnode_t *); | |
60 | static tnode_t *mktnode(op_t, type_t *, tnode_t *, tnode_t *); | 60 | static tnode_t *mktnode(op_t, type_t *, tnode_t *, tnode_t *); | |
61 | static void balance(op_t, tnode_t **, tnode_t **); | 61 | static void balance(op_t, tnode_t **, tnode_t **); | |
62 | static void incompat(op_t, tspec_t, tspec_t); | 62 | static void incompat(op_t, tspec_t, tspec_t); | |
63 | static void illptrc(mod_t *, type_t *, type_t *); | 63 | static void illptrc(mod_t *, type_t *, type_t *); | |
64 | static void mrgqual(type_t **, type_t *, type_t *); | 64 | static void mrgqual(type_t **, type_t *, type_t *); | |
65 | static int conmemb(type_t *); | 65 | static int conmemb(type_t *); | |
66 | static void ptconv(int, tspec_t, tspec_t, type_t *, tnode_t *); | 66 | static void ptconv(int, tspec_t, tspec_t, type_t *, tnode_t *); | |
67 | static void iiconv(op_t, int, tspec_t, tspec_t, type_t *, tnode_t *); | 67 | static void iiconv(op_t, int, tspec_t, tspec_t, type_t *, tnode_t *); | |
68 | static void piconv(op_t, tspec_t, type_t *, tnode_t *); | 68 | static void piconv(op_t, tspec_t, type_t *, tnode_t *); | |
69 | static void ppconv(op_t, tnode_t *, type_t *); | 69 | static void ppconv(op_t, tnode_t *, type_t *); | |
70 | static tnode_t *bldstr(op_t, tnode_t *, tnode_t *); | 70 | static tnode_t *bldstr(op_t, tnode_t *, tnode_t *); | |
71 | static tnode_t *bldincdec(op_t, tnode_t *); | 71 | static tnode_t *bldincdec(op_t, tnode_t *); | |
72 | static tnode_t *bldri(op_t, tnode_t *); | 72 | static tnode_t *bldri(op_t, tnode_t *); | |
73 | static tnode_t *bldamper(tnode_t *, int); | 73 | static tnode_t *bldamper(tnode_t *, int); | |
74 | static tnode_t *bldplmi(op_t, tnode_t *, tnode_t *); | 74 | static tnode_t *bldplmi(op_t, tnode_t *, tnode_t *); | |
75 | static tnode_t *bldshft(op_t, tnode_t *, tnode_t *); | 75 | static tnode_t *bldshft(op_t, tnode_t *, tnode_t *); | |
76 | static tnode_t *bldcol(tnode_t *, tnode_t *); | 76 | static tnode_t *bldcol(tnode_t *, tnode_t *); | |
77 | static tnode_t *bldasgn(op_t, tnode_t *, tnode_t *); | 77 | static tnode_t *bldasgn(op_t, tnode_t *, tnode_t *); | |
78 | static tnode_t *plength(type_t *); | 78 | static tnode_t *plength(type_t *); | |
79 | static tnode_t *fold(tnode_t *); | 79 | static tnode_t *fold(tnode_t *); | |
80 | static tnode_t *foldtst(tnode_t *); | 80 | static tnode_t *foldtst(tnode_t *); | |
81 | static tnode_t *foldflt(tnode_t *); | 81 | static tnode_t *foldflt(tnode_t *); | |
82 | static tnode_t *chkfarg(type_t *, tnode_t *); | 82 | static tnode_t *chkfarg(type_t *, tnode_t *); | |
83 | static tnode_t *parg(int, type_t *, tnode_t *); | 83 | static tnode_t *parg(int, type_t *, tnode_t *); | |
84 | static void nulleff(tnode_t *); | 84 | static void nulleff(tnode_t *); | |
85 | static void displexpr(tnode_t *, int); | 85 | static void displexpr(tnode_t *, int); | |
86 | static void chkaidx(tnode_t *, int); | 86 | static void chkaidx(tnode_t *, int); | |
87 | static void chkcomp(op_t, tnode_t *, tnode_t *); | 87 | static void chkcomp(op_t, tnode_t *, tnode_t *); | |
88 | static void precconf(tnode_t *); | 88 | static void precconf(tnode_t *); | |
89 | 89 | |||
90 | extern sig_atomic_t fpe; | 90 | extern sig_atomic_t fpe; | |
91 | 91 | |||
92 | /* | 92 | /* | |
93 | * Increase degree of reference. | 93 | * Increase degree of reference. | |
94 | * This is most often used to change type "T" in type "pointer to T". | 94 | * This is most often used to change type "T" in type "pointer to T". | |
95 | */ | 95 | */ | |
96 | type_t * | 96 | type_t * | |
97 | incref(type_t *tp, tspec_t t) | 97 | incref(type_t *tp, tspec_t t) | |
98 | { | 98 | { | |
99 | type_t *tp2; | 99 | type_t *tp2; | |
100 | 100 | |||
101 | tp2 = getblk(sizeof (type_t)); | 101 | tp2 = getblk(sizeof (type_t)); | |
102 | tp2->t_tspec = t; | 102 | tp2->t_tspec = t; | |
103 | tp2->t_subt = tp; | 103 | tp2->t_subt = tp; | |
104 | return (tp2); | 104 | return (tp2); | |
105 | } | 105 | } | |
106 | 106 | |||
107 | /* | 107 | /* | |
108 | * same for use in expressions | 108 | * same for use in expressions | |
109 | */ | 109 | */ | |
110 | type_t * | 110 | type_t * | |
111 | tincref(type_t *tp, tspec_t t) | 111 | tincref(type_t *tp, tspec_t t) | |
112 | { | 112 | { | |
113 | type_t *tp2; | 113 | type_t *tp2; | |
114 | 114 | |||
115 | tp2 = tgetblk(sizeof (type_t)); | 115 | tp2 = tgetblk(sizeof (type_t)); | |
116 | tp2->t_tspec = t; | 116 | tp2->t_tspec = t; | |
117 | tp2->t_subt = tp; | 117 | tp2->t_subt = tp; | |
118 | return (tp2); | 118 | return (tp2); | |
119 | } | 119 | } | |
120 | 120 | |||
121 | /* | 121 | /* | |
122 | * Create a node for a constant. | 122 | * Create a node for a constant. | |
123 | */ | 123 | */ | |
124 | tnode_t * | 124 | tnode_t * | |
125 | getcnode(type_t *tp, val_t *v) | 125 | getcnode(type_t *tp, val_t *v) | |
126 | { | 126 | { | |
127 | tnode_t *n; | 127 | tnode_t *n; | |
128 | 128 | |||
129 | n = getnode(); | 129 | n = getnode(); | |
130 | n->tn_op = CON; | 130 | n->tn_op = CON; | |
131 | n->tn_type = tp; | 131 | n->tn_type = tp; | |
132 | n->tn_val = tgetblk(sizeof (val_t)); | 132 | n->tn_val = tgetblk(sizeof (val_t)); | |
133 | n->tn_val->v_tspec = tp->t_tspec; | 133 | n->tn_val->v_tspec = tp->t_tspec; | |
134 | n->tn_val->v_ansiu = v->v_ansiu; | 134 | n->tn_val->v_ansiu = v->v_ansiu; | |
135 | n->tn_val->v_u = v->v_u; | 135 | n->tn_val->v_u = v->v_u; | |
136 | free(v); | 136 | free(v); | |
137 | return (n); | 137 | return (n); | |
138 | } | 138 | } | |
139 | 139 | |||
140 | /* | 140 | /* | |
141 | * Create a node for a integer constant. | 141 | * Create a node for a integer constant. | |
142 | */ | 142 | */ | |
143 | static tnode_t * | 143 | static tnode_t * | |
144 | getinode(tspec_t t, int64_t q) | 144 | getinode(tspec_t t, int64_t q) | |
145 | { | 145 | { | |
146 | tnode_t *n; | 146 | tnode_t *n; | |
147 | 147 | |||
148 | n = getnode(); | 148 | n = getnode(); | |
149 | n->tn_op = CON; | 149 | n->tn_op = CON; | |
150 | n->tn_type = gettyp(t); | 150 | n->tn_type = gettyp(t); | |
151 | n->tn_val = tgetblk(sizeof (val_t)); | 151 | n->tn_val = tgetblk(sizeof (val_t)); | |
152 | n->tn_val->v_tspec = t; | 152 | n->tn_val->v_tspec = t; | |
153 | n->tn_val->v_quad = q; | 153 | n->tn_val->v_quad = q; | |
154 | return (n); | 154 | return (n); | |
155 | } | 155 | } | |
156 | 156 | |||
157 | /* | 157 | /* | |
158 | * Create a node for a name (symbol table entry). | 158 | * Create a node for a name (symbol table entry). | |
159 | * ntok is the token which follows the name. | 159 | * ntok is the token which follows the name. | |
160 | */ | 160 | */ | |
161 | tnode_t * | 161 | tnode_t * | |
162 | getnnode(sym_t *sym, int ntok) | 162 | getnnode(sym_t *sym, int ntok) | |
163 | { | 163 | { | |
164 | tnode_t *n; | 164 | tnode_t *n; | |
165 | 165 | |||
166 | if (sym->s_scl == NOSCL) { | 166 | if (sym->s_scl == NOSCL) { | |
167 | sym->s_scl = EXTERN; | 167 | sym->s_scl = EXTERN; | |
168 | sym->s_def = DECL; | 168 | sym->s_def = DECL; | |
169 | if (ntok == T_LPARN) { | 169 | if (ntok == T_LPARN) { | |
170 | if (sflag) { | 170 | if (sflag) { | |
171 | /* function implicitly declared to ... */ | 171 | /* function implicitly declared to ... */ | |
172 | warning(215); | 172 | warning(215); | |
173 | } | 173 | } | |
174 | /* | 174 | /* | |
175 | * XXX if tflag is set the symbol should be | 175 | * XXX if tflag is set the symbol should be | |
176 | * exported to level 0 | 176 | * exported to level 0 | |
177 | */ | 177 | */ | |
178 | sym->s_type = incref(sym->s_type, FUNC); | 178 | sym->s_type = incref(sym->s_type, FUNC); | |
179 | } else { | 179 | } else { | |
180 | if (!blklev) { | 180 | if (!blklev) { | |
181 | /* %s undefined */ | 181 | /* %s undefined */ | |
182 | error(99, sym->s_name); | 182 | error(99, sym->s_name); | |
183 | } else { | 183 | } else { | |
184 | int fixtype; | 184 | int fixtype; | |
185 | if (strcmp(sym->s_name, "__FUNCTION__") == 0 || | 185 | if (strcmp(sym->s_name, "__FUNCTION__") == 0 || | |
186 | strcmp(sym->s_name, "__PRETTY_FUNCTION__") | 186 | strcmp(sym->s_name, "__PRETTY_FUNCTION__") | |
187 | == 0) { | 187 | == 0) { | |
188 | gnuism(316); | 188 | gnuism(316); | |
189 | fixtype = 1; | 189 | fixtype = 1; | |
190 | } else if (strcmp(sym->s_name, "__func__") == 0) { | 190 | } else if (strcmp(sym->s_name, "__func__") == 0) { | |
191 | if (!Sflag) | 191 | if (!Sflag) | |
192 | warning(317); | 192 | warning(317); | |
193 | fixtype = 1; | 193 | fixtype = 1; | |
194 | } else { | 194 | } else { | |
195 | error(99, sym->s_name); | 195 | error(99, sym->s_name); | |
196 | fixtype = 0; | 196 | fixtype = 0; | |
197 | } | 197 | } | |
198 | if (fixtype) { | 198 | if (fixtype) { | |
199 | sym->s_type = incref(gettyp(CHAR), PTR); | 199 | sym->s_type = incref(gettyp(CHAR), PTR); | |
200 | sym->s_type->t_const = 1; | 200 | sym->s_type->t_const = 1; | |
201 | } | 201 | } | |
202 | } | 202 | } | |
203 | } | 203 | } | |
204 | } | 204 | } | |
205 | 205 | |||
206 | if (sym->s_kind != FVFT && sym->s_kind != FMOS) | 206 | if (sym->s_kind != FVFT && sym->s_kind != FMOS) | |
207 | LERROR("getnnode()"); | 207 | LERROR("getnnode()"); | |
208 | 208 | |||
209 | n = getnode(); | 209 | n = getnode(); | |
210 | n->tn_type = sym->s_type; | 210 | n->tn_type = sym->s_type; | |
211 | if (sym->s_scl != ENUMCON) { | 211 | if (sym->s_scl != ENUMCON) { | |
212 | n->tn_op = NAME; | 212 | n->tn_op = NAME; | |
213 | n->tn_sym = sym; | 213 | n->tn_sym = sym; | |
214 | if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) | 214 | if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) | |
215 | n->tn_lvalue = 1; | 215 | n->tn_lvalue = 1; | |
216 | } else { | 216 | } else { | |
217 | n->tn_op = CON; | 217 | n->tn_op = CON; | |
218 | n->tn_val = tgetblk(sizeof (val_t)); | 218 | n->tn_val = tgetblk(sizeof (val_t)); | |
219 | *n->tn_val = sym->s_value; | 219 | *n->tn_val = sym->s_value; | |
220 | } | 220 | } | |
221 | 221 | |||
222 | return (n); | 222 | return (n); | |
223 | } | 223 | } | |
224 | 224 | |||
225 | /* | 225 | /* | |
226 | * Create a node for a string. | 226 | * Create a node for a string. | |
227 | */ | 227 | */ | |
228 | tnode_t * | 228 | tnode_t * | |
229 | getsnode(strg_t *strg) | 229 | getsnode(strg_t *strg) | |
230 | { | 230 | { | |
231 | size_t len; | 231 | size_t len; | |
232 | tnode_t *n; | 232 | tnode_t *n; | |
233 | 233 | |||
234 | len = strg->st_len; | 234 | len = strg->st_len; | |
235 | 235 | |||
236 | n = getnode(); | 236 | n = getnode(); | |
237 | 237 | |||
238 | n->tn_op = STRING; | 238 | n->tn_op = STRING; | |
239 | n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY); | 239 | n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY); | |
240 | n->tn_type->t_dim = len + 1; | 240 | n->tn_type->t_dim = len + 1; | |
241 | n->tn_lvalue = 1; | 241 | n->tn_lvalue = 1; | |
242 | 242 | |||
243 | n->tn_strg = tgetblk(sizeof (strg_t)); | 243 | n->tn_strg = tgetblk(sizeof (strg_t)); | |
244 | n->tn_strg->st_tspec = strg->st_tspec; | 244 | n->tn_strg->st_tspec = strg->st_tspec; | |
245 | n->tn_strg->st_len = len; | 245 | n->tn_strg->st_len = len; | |
246 | 246 | |||
247 | if (strg->st_tspec == CHAR) { | 247 | if (strg->st_tspec == CHAR) { | |
248 | n->tn_strg->st_cp = tgetblk(len + 1); | 248 | n->tn_strg->st_cp = tgetblk(len + 1); | |
249 | (void)memcpy(n->tn_strg->st_cp, strg->st_cp, len + 1); | 249 | (void)memcpy(n->tn_strg->st_cp, strg->st_cp, len + 1); | |
250 | free(strg->st_cp); | 250 | free(strg->st_cp); | |
251 | } else { | 251 | } else { | |
252 | n->tn_strg->st_wcp = tgetblk((len + 1) * sizeof (wchar_t)); | 252 | n->tn_strg->st_wcp = tgetblk((len + 1) * sizeof (wchar_t)); | |
253 | (void)memcpy(n->tn_strg->st_wcp, strg->st_wcp, | 253 | (void)memcpy(n->tn_strg->st_wcp, strg->st_wcp, | |
254 | (len + 1) * sizeof (wchar_t)); | 254 | (len + 1) * sizeof (wchar_t)); | |
255 | free(strg->st_wcp); | 255 | free(strg->st_wcp); | |
256 | } | 256 | } | |
257 | free(strg); | 257 | free(strg); | |
258 | 258 | |||
259 | return (n); | 259 | return (n); | |
260 | } | 260 | } | |
261 | 261 | |||
262 | /* | 262 | /* | |
263 | * Returns a symbol which has the same name as the msym argument and is a | 263 | * Returns a symbol which has the same name as the msym argument and is a | |
264 | * member of the struct or union specified by the tn argument. | 264 | * member of the struct or union specified by the tn argument. | |
265 | */ | 265 | */ | |
266 | sym_t * | 266 | sym_t * | |
267 | strmemb(tnode_t *tn, op_t op, sym_t *msym) | 267 | strmemb(tnode_t *tn, op_t op, sym_t *msym) | |
268 | { | 268 | { | |
269 | str_t *str; | 269 | str_t *str; | |
270 | type_t *tp; | 270 | type_t *tp; | |
271 | sym_t *sym, *csym; | 271 | sym_t *sym, *csym; | |
272 | int eq; | 272 | int eq; | |
273 | tspec_t t; | 273 | tspec_t t; | |
274 | 274 | |||
275 | /* | 275 | /* | |
276 | * Remove the member if it was unknown until now (Which means | 276 | * Remove the member if it was unknown until now (Which means | |
277 | * that no defined struct or union has a member with the same name). | 277 | * that no defined struct or union has a member with the same name). | |
278 | */ | 278 | */ | |
279 | if (msym->s_scl == NOSCL) { | 279 | if (msym->s_scl == NOSCL) { | |
280 | /* undefined struct/union member: %s */ | 280 | /* undefined struct/union member: %s */ | |
281 | error(101, msym->s_name); | 281 | error(101, msym->s_name); | |
282 | rmsym(msym); | 282 | rmsym(msym); | |
283 | msym->s_kind = FMOS; | 283 | msym->s_kind = FMOS; | |
284 | msym->s_scl = MOS; | 284 | msym->s_scl = MOS; | |
285 | msym->s_styp = tgetblk(sizeof (str_t)); | 285 | msym->s_styp = tgetblk(sizeof (str_t)); | |
286 | msym->s_styp->stag = tgetblk(sizeof (sym_t)); | 286 | msym->s_styp->stag = tgetblk(sizeof (sym_t)); | |
287 | msym->s_styp->stag->s_name = unnamed; | 287 | msym->s_styp->stag->s_name = unnamed; | |
288 | msym->s_value.v_tspec = INT; | 288 | msym->s_value.v_tspec = INT; | |
289 | return (msym); | 289 | return (msym); | |
290 | } | 290 | } | |
291 | 291 | |||
292 | /* Set str to the tag of which msym is expected to be a member. */ | 292 | /* Set str to the tag of which msym is expected to be a member. */ | |
293 | str = NULL; | 293 | str = NULL; | |
294 | t = (tp = tn->tn_type)->t_tspec; | 294 | t = (tp = tn->tn_type)->t_tspec; | |
295 | if (op == POINT) { | 295 | if (op == POINT) { | |
296 | if (t == STRUCT || t == UNION) | 296 | if (t == STRUCT || t == UNION) | |
297 | str = tp->t_str; | 297 | str = tp->t_str; | |
298 | } else if (op == ARROW && t == PTR) { | 298 | } else if (op == ARROW && t == PTR) { | |
299 | t = (tp = tp->t_subt)->t_tspec; | 299 | t = (tp = tp->t_subt)->t_tspec; | |
300 | if (t == STRUCT || t == UNION) | 300 | if (t == STRUCT || t == UNION) | |
301 | str = tp->t_str; | 301 | str = tp->t_str; | |
302 | } | 302 | } | |
303 | 303 | |||
304 | /* | 304 | /* | |
305 | * If this struct/union has a member with the name of msym, return | 305 | * If this struct/union has a member with the name of msym, return | |
306 | * return this it. | 306 | * return this it. | |
307 | */ | 307 | */ | |
308 | if (str != NULL) { | 308 | if (str != NULL) { | |
309 | for (sym = msym; sym != NULL; sym = sym->s_link) { | 309 | for (sym = msym; sym != NULL; sym = sym->s_link) { | |
310 | if (sym->s_scl != MOS && sym->s_scl != MOU) | 310 | if (sym->s_scl != MOS && sym->s_scl != MOU) | |
311 | continue; | 311 | continue; | |
312 | if (sym->s_styp != str) | 312 | if (sym->s_styp != str) | |
313 | continue; | 313 | continue; | |
314 | if (strcmp(sym->s_name, msym->s_name) != 0) | 314 | if (strcmp(sym->s_name, msym->s_name) != 0) | |
315 | continue; | 315 | continue; | |
316 | return (sym); | 316 | return (sym); | |
317 | } | 317 | } | |
318 | } | 318 | } | |
319 | 319 | |||
320 | /* | 320 | /* | |
321 | * Set eq to 0 if there are struct/union members with the same name | 321 | * Set eq to 0 if there are struct/union members with the same name | |
322 | * and different types and/or offsets. | 322 | * and different types and/or offsets. | |
323 | */ | 323 | */ | |
324 | eq = 1; | 324 | eq = 1; | |
325 | for (csym = msym; csym != NULL; csym = csym->s_link) { | 325 | for (csym = msym; csym != NULL; csym = csym->s_link) { | |
326 | if (csym->s_scl != MOS && csym->s_scl != MOU) | 326 | if (csym->s_scl != MOS && csym->s_scl != MOU) | |
327 | continue; | 327 | continue; | |
328 | if (strcmp(msym->s_name, csym->s_name) != 0) | 328 | if (strcmp(msym->s_name, csym->s_name) != 0) | |
329 | continue; | 329 | continue; | |
330 | for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { | 330 | for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { | |
331 | int w; | 331 | int w; | |
332 | 332 | |||
333 | if (sym->s_scl != MOS && sym->s_scl != MOU) | 333 | if (sym->s_scl != MOS && sym->s_scl != MOU) | |
334 | continue; | 334 | continue; | |
335 | if (strcmp(csym->s_name, sym->s_name) != 0) | 335 | if (strcmp(csym->s_name, sym->s_name) != 0) | |
336 | continue; | 336 | continue; | |
337 | if (csym->s_value.v_quad != sym->s_value.v_quad) { | 337 | if (csym->s_value.v_quad != sym->s_value.v_quad) { | |
338 | eq = 0; | 338 | eq = 0; | |
339 | break; | 339 | break; | |
340 | } | 340 | } | |
341 | w = 0; | 341 | w = 0; | |
342 | eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w; | 342 | eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w; | |
343 | if (!eq) | 343 | if (!eq) | |
344 | break; | 344 | break; | |
345 | if (csym->s_field != sym->s_field) { | 345 | if (csym->s_field != sym->s_field) { | |
346 | eq = 0; | 346 | eq = 0; | |
347 | break; | 347 | break; | |
348 | } | 348 | } | |
349 | if (csym->s_field) { | 349 | if (csym->s_field) { | |
350 | type_t *tp1, *tp2; | 350 | type_t *tp1, *tp2; | |
351 | 351 | |||
352 | tp1 = csym->s_type; | 352 | tp1 = csym->s_type; | |
353 | tp2 = sym->s_type; | 353 | tp2 = sym->s_type; | |
354 | if (tp1->t_flen != tp2->t_flen) { | 354 | if (tp1->t_flen != tp2->t_flen) { | |
355 | eq = 0; | 355 | eq = 0; | |
356 | break; | 356 | break; | |
357 | } | 357 | } | |
358 | if (tp1->t_foffs != tp2->t_foffs) { | 358 | if (tp1->t_foffs != tp2->t_foffs) { | |
359 | eq = 0; | 359 | eq = 0; | |
360 | break; | 360 | break; | |
361 | } | 361 | } | |
362 | } | 362 | } | |
363 | } | 363 | } | |
364 | if (!eq) | 364 | if (!eq) | |
365 | break; | 365 | break; | |
366 | } | 366 | } | |
367 | 367 | |||
368 | /* | 368 | /* | |
369 | * Now handle the case in which the left operand refers really | 369 | * Now handle the case in which the left operand refers really | |
370 | * to a struct/union, but the right operand is not member of it. | 370 | * to a struct/union, but the right operand is not member of it. | |
371 | */ | 371 | */ | |
372 | if (str != NULL) { | 372 | if (str != NULL) { | |
373 | /* illegal member use: %s */ | 373 | /* illegal member use: %s */ | |
374 | if (eq && tflag) { | 374 | if (eq && tflag) { | |
375 | warning(102, msym->s_name); | 375 | warning(102, msym->s_name); | |
376 | } else { | 376 | } else { | |
377 | error(102, msym->s_name); | 377 | error(102, msym->s_name); | |
378 | } | 378 | } | |
379 | return (msym); | 379 | return (msym); | |
380 | } | 380 | } | |
381 | 381 | |||
382 | /* | 382 | /* | |
383 | * Now the left operand of ARROW does not point to a struct/union | 383 | * Now the left operand of ARROW does not point to a struct/union | |
384 | * or the left operand of POINT is no struct/union. | 384 | * or the left operand of POINT is no struct/union. | |
385 | */ | 385 | */ | |
386 | if (eq) { | 386 | if (eq) { | |
387 | if (op == POINT) { | 387 | if (op == POINT) { | |
388 | /* left operand of "." must be struct/union object */ | 388 | /* left operand of "." must be struct/union object */ | |
389 | if (tflag) { | 389 | if (tflag) { | |
390 | warning(103); | 390 | warning(103); | |
391 | } else { | 391 | } else { | |
392 | error(103); | 392 | error(103); | |
393 | } | 393 | } | |
394 | } else { | 394 | } else { | |
395 | /* left operand of "->" must be pointer to ... */ | 395 | /* left operand of "->" must be pointer to ... */ | |
396 | if (tflag && tn->tn_type->t_tspec == PTR) { | 396 | if (tflag && tn->tn_type->t_tspec == PTR) { | |
397 | warning(104); | 397 | warning(104); | |
398 | } else { | 398 | } else { | |
399 | error(104); | 399 | error(104); | |
400 | } | 400 | } | |
401 | } | 401 | } | |
402 | } else { | 402 | } else { | |
403 | if (tflag) { | 403 | if (tflag) { | |
404 | /* non-unique member requires struct/union %s */ | 404 | /* non-unique member requires struct/union %s */ | |
405 | error(105, op == POINT ? "object" : "pointer"); | 405 | error(105, op == POINT ? "object" : "pointer"); | |
406 | } else { | 406 | } else { | |
407 | /* unacceptable operand of %s */ | 407 | /* unacceptable operand of %s */ | |
408 | error(111, modtab[op].m_name); | 408 | error(111, modtab[op].m_name); | |
409 | } | 409 | } | |
410 | } | 410 | } | |
411 | 411 | |||
412 | return (msym); | 412 | return (msym); | |
413 | } | 413 | } | |
414 | 414 | |||
415 | /* | 415 | /* | |
416 | * Create a tree node. Called for most operands except function calls, | 416 | * Create a tree node. Called for most operands except function calls, | |
417 | * sizeof and casts. | 417 | * sizeof and casts. | |
418 | * | 418 | * | |
419 | * op operator | 419 | * op operator | |
420 | * ln left operand | 420 | * ln left operand | |
421 | * rn if not NULL, right operand | 421 | * rn if not NULL, right operand | |
422 | */ | 422 | */ | |
423 | tnode_t * | 423 | tnode_t * | |
424 | build(op_t op, tnode_t *ln, tnode_t *rn) | 424 | build(op_t op, tnode_t *ln, tnode_t *rn) | |
425 | { | 425 | { | |
426 | mod_t *mp; | 426 | mod_t *mp; | |
427 | tnode_t *ntn; | 427 | tnode_t *ntn; | |
428 | type_t *rtp; | 428 | type_t *rtp; | |
429 | 429 | |||
430 | mp = &modtab[op]; | 430 | mp = &modtab[op]; | |
431 | 431 | |||
432 | /* If there was an error in one of the operands, return. */ | 432 | /* If there was an error in one of the operands, return. */ | |
433 | if (ln == NULL || (mp->m_binary && rn == NULL)) | 433 | if (ln == NULL || (mp->m_binary && rn == NULL)) | |
434 | return (NULL); | 434 | return (NULL); | |
435 | 435 | |||
436 | /* | 436 | /* | |
437 | * Apply class conversions to the left operand, but only if its | 437 | * Apply class conversions to the left operand, but only if its | |
438 | * value is needed or it is compaired with null. | 438 | * value is needed or it is compaired with null. | |
439 | */ | 439 | */ | |
440 | if (mp->m_vctx || mp->m_tctx) | 440 | if (mp->m_vctx || mp->m_tctx) | |
441 | ln = cconv(ln); | 441 | ln = cconv(ln); | |
442 | /* | 442 | /* | |
443 | * The right operand is almost always in a test or value context, | 443 | * The right operand is almost always in a test or value context, | |
444 | * except if it is a struct or union member. | 444 | * except if it is a struct or union member. | |
445 | */ | 445 | */ | |
446 | if (mp->m_binary && op != ARROW && op != POINT) | 446 | if (mp->m_binary && op != ARROW && op != POINT) | |
447 | rn = cconv(rn); | 447 | rn = cconv(rn); | |
448 | 448 | |||
449 | /* | 449 | /* | |
450 | * Print some warnings for comparisons of unsigned values with | 450 | * Print some warnings for comparisons of unsigned values with | |
451 | * constants lower than or equal to null. This must be done | 451 | * constants lower than or equal to null. This must be done | |
452 | * before promote() because otherwise unsigned char and unsigned | 452 | * before promote() because otherwise unsigned char and unsigned | |
453 | * short would be promoted to int. Also types are tested to be | 453 | * short would be promoted to int. Also types are tested to be | |
454 | * CHAR, which would also become int. | 454 | * CHAR, which would also become int. | |
455 | */ | 455 | */ | |
456 | if (mp->m_comp) | 456 | if (mp->m_comp) | |
457 | chkcomp(op, ln, rn); | 457 | chkcomp(op, ln, rn); | |
458 | 458 | |||
459 | /* | 459 | /* | |
460 | * Promote the left operand if it is in a test or value context | 460 | * Promote the left operand if it is in a test or value context | |
461 | */ | 461 | */ | |
462 | if (mp->m_vctx || mp->m_tctx) | 462 | if (mp->m_vctx || mp->m_tctx) | |
463 | ln = promote(op, 0, ln); | 463 | ln = promote(op, 0, ln); | |
464 | /* | 464 | /* | |
465 | * Promote the right operand, but only if it is no struct or | 465 | * Promote the right operand, but only if it is no struct or | |
466 | * union member, or if it is not to be assigned to the left operand | 466 | * union member, or if it is not to be assigned to the left operand | |
467 | */ | 467 | */ | |
468 | if (mp->m_binary && op != ARROW && op != POINT && | 468 | if (mp->m_binary && op != ARROW && op != POINT && | |
469 | op != ASSIGN && op != RETURN) { | 469 | op != ASSIGN && op != RETURN) { | |
470 | rn = promote(op, 0, rn); | 470 | rn = promote(op, 0, rn); | |
471 | } | 471 | } | |
472 | 472 | |||
473 | /* | 473 | /* | |
474 | * If the result of the operation is different for signed or | 474 | * If the result of the operation is different for signed or | |
475 | * unsigned operands and one of the operands is signed only in | 475 | * unsigned operands and one of the operands is signed only in | |
476 | * ANSI C, print a warning. | 476 | * ANSI C, print a warning. | |
477 | */ | 477 | */ | |
478 | if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) { | 478 | if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) { | |
479 | /* ANSI C treats constant as unsigned, op %s */ | 479 | /* ANSI C treats constant as unsigned, op %s */ | |
480 | warning(218, mp->m_name); | 480 | warning(218, mp->m_name); | |
481 | ln->tn_val->v_ansiu = 0; | 481 | ln->tn_val->v_ansiu = 0; | |
482 | } | 482 | } | |
483 | if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) { | 483 | if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) { | |
484 | /* ANSI C treats constant as unsigned, op %s */ | 484 | /* ANSI C treats constant as unsigned, op %s */ | |
485 | warning(218, mp->m_name); | 485 | warning(218, mp->m_name); | |
486 | rn->tn_val->v_ansiu = 0; | 486 | rn->tn_val->v_ansiu = 0; | |
487 | } | 487 | } | |
488 | 488 | |||
489 | /* Make sure both operands are of the same type */ | 489 | /* Make sure both operands are of the same type */ | |
490 | if (mp->m_balance || (tflag && (op == SHL || op == SHR))) | 490 | if (mp->m_balance || (tflag && (op == SHL || op == SHR))) | |
491 | balance(op, &ln, &rn); | 491 | balance(op, &ln, &rn); | |
492 | 492 | |||
493 | /* | 493 | /* | |
494 | * Check types for compatibility with the operation and mutual | 494 | * Check types for compatibility with the operation and mutual | |
495 | * compatibility. Return if there are serios problems. | 495 | * compatibility. Return if there are serios problems. | |
496 | */ | 496 | */ | |
497 | if (!typeok(op, 0, ln, rn)) | 497 | if (!typeok(op, 0, ln, rn)) | |
498 | return (NULL); | 498 | return (NULL); | |
499 | 499 | |||
500 | /* And now create the node. */ | 500 | /* And now create the node. */ | |
501 | switch (op) { | 501 | switch (op) { | |
502 | case POINT: | 502 | case POINT: | |
503 | case ARROW: | 503 | case ARROW: | |
504 | ntn = bldstr(op, ln, rn); | 504 | ntn = bldstr(op, ln, rn); | |
505 | break; | 505 | break; | |
506 | case INCAFT: | 506 | case INCAFT: | |
507 | case DECAFT: | 507 | case DECAFT: | |
508 | case INCBEF: | 508 | case INCBEF: | |
509 | case DECBEF: | 509 | case DECBEF: | |
510 | ntn = bldincdec(op, ln); | 510 | ntn = bldincdec(op, ln); | |
511 | break; | 511 | break; | |
512 | case AMPER: | 512 | case AMPER: | |
513 | ntn = bldamper(ln, 0); | 513 | ntn = bldamper(ln, 0); | |
514 | break; | 514 | break; | |
515 | case STAR: | 515 | case STAR: | |
516 | ntn = mktnode(STAR, ln->tn_type->t_subt, ln, NULL); | 516 | ntn = mktnode(STAR, ln->tn_type->t_subt, ln, NULL); | |
517 | break; | 517 | break; | |
518 | case PLUS: | 518 | case PLUS: | |
519 | case MINUS: | 519 | case MINUS: | |
520 | ntn = bldplmi(op, ln, rn); | 520 | ntn = bldplmi(op, ln, rn); | |
521 | break; | 521 | break; | |
522 | case SHL: | 522 | case SHL: | |
523 | case SHR: | 523 | case SHR: | |
524 | ntn = bldshft(op, ln, rn); | 524 | ntn = bldshft(op, ln, rn); | |
525 | break; | 525 | break; | |
526 | case COLON: | 526 | case COLON: | |
527 | ntn = bldcol(ln, rn); | 527 | ntn = bldcol(ln, rn); | |
528 | break; | 528 | break; | |
529 | case ASSIGN: | 529 | case ASSIGN: | |
530 | case MULASS: | 530 | case MULASS: | |
531 | case DIVASS: | 531 | case DIVASS: | |
532 | case MODASS: | 532 | case MODASS: | |
533 | case ADDASS: | 533 | case ADDASS: | |
534 | case SUBASS: | 534 | case SUBASS: | |
535 | case SHLASS: | 535 | case SHLASS: | |
536 | case SHRASS: | 536 | case SHRASS: | |
537 | case ANDASS: | 537 | case ANDASS: | |
538 | case XORASS: | 538 | case XORASS: | |
539 | case ORASS: | 539 | case ORASS: | |
540 | case RETURN: | 540 | case RETURN: | |
541 | ntn = bldasgn(op, ln, rn); | 541 | ntn = bldasgn(op, ln, rn); | |
542 | break; | 542 | break; | |
543 | case COMMA: | 543 | case COMMA: | |
544 | case QUEST: | 544 | case QUEST: | |
545 | ntn = mktnode(op, rn->tn_type, ln, rn); | 545 | ntn = mktnode(op, rn->tn_type, ln, rn); | |
546 | break; | 546 | break; | |
547 | case REAL: | 547 | case REAL: | |
548 | case IMAG: | 548 | case IMAG: | |
549 | ntn = bldri(op, ln); | 549 | ntn = bldri(op, ln); | |
550 | break; | 550 | break; | |
551 | default: | 551 | default: | |
552 | rtp = mp->m_logop ? gettyp(INT) : ln->tn_type; | 552 | rtp = mp->m_logop ? gettyp(INT) : ln->tn_type; | |
553 | if (!mp->m_binary && rn != NULL) | 553 | if (!mp->m_binary && rn != NULL) | |
554 | LERROR("build()"); | 554 | LERROR("build()"); | |
555 | ntn = mktnode(op, rtp, ln, rn); | 555 | ntn = mktnode(op, rtp, ln, rn); | |
556 | break; | 556 | break; | |
557 | } | 557 | } | |
558 | 558 | |||
559 | /* Return if an error occurred. */ | 559 | /* Return if an error occurred. */ | |
560 | if (ntn == NULL) | 560 | if (ntn == NULL) | |
561 | return (NULL); | 561 | return (NULL); | |
562 | 562 | |||
563 | /* Print a warning if precedence confusion is possible */ | 563 | /* Print a warning if precedence confusion is possible */ | |
564 | if (mp->m_tpconf) | 564 | if (mp->m_tpconf) | |
565 | precconf(ntn); | 565 | precconf(ntn); | |
566 | 566 | |||
567 | /* | 567 | /* | |
568 | * Print a warning if one of the operands is in a context where | 568 | * Print a warning if one of the operands is in a context where | |
569 | * it is compared with null and if this operand is a constant. | 569 | * it is compared with null and if this operand is a constant. | |
570 | */ | 570 | */ | |
571 | if (mp->m_tctx) { | 571 | if (mp->m_tctx) { | |
572 | if (ln->tn_op == CON || | 572 | if (ln->tn_op == CON || | |
573 | ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { | 573 | ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { | |
574 | if (hflag && !ccflg) | 574 | if (hflag && !ccflg) | |
575 | /* constant in conditional context */ | 575 | /* constant in conditional context */ | |
576 | warning(161); | 576 | warning(161); | |
577 | } | 577 | } | |
578 | } | 578 | } | |
579 | 579 | |||
580 | /* Fold if the operator requires it */ | 580 | /* Fold if the operator requires it */ | |
581 | if (mp->m_fold) { | 581 | if (mp->m_fold) { | |
582 | if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { | 582 | if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { | |
583 | if (mp->m_tctx) { | 583 | if (mp->m_tctx) { | |
584 | ntn = foldtst(ntn); | 584 | ntn = foldtst(ntn); | |
585 | } else if (isftyp(ntn->tn_type->t_tspec)) { | 585 | } else if (isftyp(ntn->tn_type->t_tspec)) { | |
586 | ntn = foldflt(ntn); | 586 | ntn = foldflt(ntn); | |
587 | } else { | 587 | } else { | |
588 | ntn = fold(ntn); | 588 | ntn = fold(ntn); | |
589 | } | 589 | } | |
590 | } else if (op == QUEST && ln->tn_op == CON) { | 590 | } else if (op == QUEST && ln->tn_op == CON) { | |
591 | ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right; | 591 | ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right; | |
592 | } | 592 | } | |
593 | } | 593 | } | |
594 | 594 | |||
595 | return (ntn); | 595 | return (ntn); | |
596 | } | 596 | } | |
597 | 597 | |||
598 | /* | 598 | /* | |
599 | * Perform class conversions. | 599 | * Perform class conversions. | |
600 | * | 600 | * | |
601 | * Arrays of type T are converted into pointers to type T. | 601 | * Arrays of type T are converted into pointers to type T. | |
602 | * Functions are converted to pointers to functions. | 602 | * Functions are converted to pointers to functions. | |
603 | * Lvalues are converted to rvalues. | 603 | * Lvalues are converted to rvalues. | |
604 | */ | 604 | */ | |
605 | tnode_t * | 605 | tnode_t * | |
606 | cconv(tnode_t *tn) | 606 | cconv(tnode_t *tn) | |
607 | { | 607 | { | |
608 | type_t *tp; | 608 | type_t *tp; | |
609 | 609 | |||
610 | /* | 610 | /* | |
611 | * Array-lvalue (array of type T) is converted into rvalue | 611 | * Array-lvalue (array of type T) is converted into rvalue | |
612 | * (pointer to type T) | 612 | * (pointer to type T) | |
613 | */ | 613 | */ | |
614 | if (tn->tn_type->t_tspec == ARRAY) { | 614 | if (tn->tn_type->t_tspec == ARRAY) { | |
615 | if (!tn->tn_lvalue) { | 615 | if (!tn->tn_lvalue) { | |
616 | /* %soperand of '%s' must be lvalue */ | 616 | /* %soperand of '%s' must be lvalue */ | |
617 | /* XXX print correct operator */ | 617 | /* XXX print correct operator */ | |
618 | (void)gnuism(114, "", modtab[AMPER].m_name); | 618 | (void)gnuism(114, "", modtab[AMPER].m_name); | |
619 | } | 619 | } | |
620 | tn = mktnode(AMPER, tincref(tn->tn_type->t_subt, PTR), | 620 | tn = mktnode(AMPER, tincref(tn->tn_type->t_subt, PTR), | |
621 | tn, NULL); | 621 | tn, NULL); | |
622 | } | 622 | } | |
623 | 623 | |||
624 | /* | 624 | /* | |
625 | * Expression of type function (function with return value of type T) | 625 | * Expression of type function (function with return value of type T) | |
626 | * in rvalue-expression (pointer to function with return value | 626 | * in rvalue-expression (pointer to function with return value | |
627 | * of type T) | 627 | * of type T) | |
628 | */ | 628 | */ | |
629 | if (tn->tn_type->t_tspec == FUNC) | 629 | if (tn->tn_type->t_tspec == FUNC) | |
630 | tn = bldamper(tn, 1); | 630 | tn = bldamper(tn, 1); | |
631 | 631 | |||
632 | /* lvalue to rvalue */ | 632 | /* lvalue to rvalue */ | |
633 | if (tn->tn_lvalue) { | 633 | if (tn->tn_lvalue) { | |
634 | tp = tduptyp(tn->tn_type); | 634 | tp = tduptyp(tn->tn_type); | |
635 | tp->t_const = tp->t_volatile = 0; | 635 | tp->t_const = tp->t_volatile = 0; | |
636 | tn = mktnode(LOAD, tp, tn, NULL); | 636 | tn = mktnode(LOAD, tp, tn, NULL); | |
637 | } | 637 | } | |
638 | 638 | |||
639 | return (tn); | 639 | return (tn); | |
640 | } | 640 | } | |
641 | 641 | |||
642 | /* | 642 | /* | |
643 | * Perform most type checks. First the types are checked using | 643 | * Perform most type checks. First the types are checked using | |
644 | * informations from modtab[]. After that it is done by hand for | 644 | * informations from modtab[]. After that it is done by hand for | |
645 | * more complicated operators and type combinations. | 645 | * more complicated operators and type combinations. | |
646 | * | 646 | * | |
647 | * If the types are ok, typeok() returns 1, otherwise 0. | 647 | * If the types are ok, typeok() returns 1, otherwise 0. | |
648 | */ | 648 | */ | |
649 | int | 649 | int | |
650 | typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) | 650 | typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) | |
651 | { | 651 | { | |
652 | mod_t *mp; | 652 | mod_t *mp; | |
653 | tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC, | 653 | tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC, | |
654 | ort = NOTSPEC; | 654 | ort = NOTSPEC; | |
655 | type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL; | 655 | type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL; | |
656 | tnode_t *tn; | 656 | tnode_t *tn; | |
657 | 657 | |||
658 | mp = &modtab[op]; | 658 | mp = &modtab[op]; | |
659 | 659 | |||
660 | if ((ltp = ln->tn_type) == NULL) | 660 | if ((ltp = ln->tn_type) == NULL) | |
661 | LERROR("typeok()"); | 661 | LERROR("typeok()"); | |
662 | 662 | |||
663 | if ((lt = ltp->t_tspec) == PTR) | 663 | if ((lt = ltp->t_tspec) == PTR) | |
664 | lst = (lstp = ltp->t_subt)->t_tspec; | 664 | lst = (lstp = ltp->t_subt)->t_tspec; | |
665 | if (mp->m_binary) { | 665 | if (mp->m_binary) { | |
666 | if ((rtp = rn->tn_type) == NULL) | 666 | if ((rtp = rn->tn_type) == NULL) | |
667 | LERROR("typeok()"); | 667 | LERROR("typeok()"); | |
668 | if ((rt = rtp->t_tspec) == PTR) | 668 | if ((rt = rtp->t_tspec) == PTR) | |
669 | rst = (rstp = rtp->t_subt)->t_tspec; | 669 | rst = (rstp = rtp->t_subt)->t_tspec; | |
670 | } | 670 | } | |
671 | 671 | |||
672 | if (mp->m_rqint) { | 672 | if (mp->m_rqint) { | |
673 | /* integertypes required */ | 673 | /* integertypes required */ | |
674 | if (!isityp(lt) || (mp->m_binary && !isityp(rt))) { | 674 | if (!isityp(lt) || (mp->m_binary && !isityp(rt))) { | |
675 | incompat(op, lt, rt); | 675 | incompat(op, lt, rt); | |
676 | return (0); | 676 | return (0); | |
677 | } | 677 | } | |
678 | } else if (mp->m_rqintcomp) { | 678 | } else if (mp->m_rqintcomp) { | |
679 | /* integertypes required */ | 679 | /* integertypes required */ | |
680 | if ((!isityp(lt) && !isctyp(lt)) || | 680 | if ((!isityp(lt) && !isctyp(lt)) || | |
681 | (mp->m_binary && (!isityp(rt) && !isctyp(rt)))) { | 681 | (mp->m_binary && (!isityp(rt) && !isctyp(rt)))) { | |
682 | incompat(op, lt, rt); | 682 | incompat(op, lt, rt); | |
683 | return (0); | 683 | return (0); | |
684 | } | 684 | } | |
685 | } else if (mp->m_rqsclt) { | 685 | } else if (mp->m_rqsclt) { | |
686 | /* scalar types required */ | 686 | /* scalar types required */ | |
687 | if (!issclt(lt) || (mp->m_binary && !issclt(rt))) { | 687 | if (!issclt(lt) || (mp->m_binary && !issclt(rt))) { | |
688 | incompat(op, lt, rt); | 688 | incompat(op, lt, rt); | |
689 | return (0); | 689 | return (0); | |
690 | } | 690 | } | |
691 | } else if (mp->m_rqatyp) { | 691 | } else if (mp->m_rqatyp) { | |
692 | /* arithmetic types required */ | 692 | /* arithmetic types required */ | |
693 | if (!isatyp(lt) || (mp->m_binary && !isatyp(rt))) { | 693 | if (!isatyp(lt) || (mp->m_binary && !isatyp(rt))) { | |
694 | incompat(op, lt, rt); | 694 | incompat(op, lt, rt); | |
695 | return (0); | 695 | return (0); | |
696 | } | 696 | } | |
697 | } | 697 | } | |
698 | 698 | |||
699 | if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) { | 699 | if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) { | |
700 | /* | 700 | /* | |
701 | * For these operations we need the types before promotion | 701 | * For these operations we need the types before promotion | |
702 | * and balancing. | 702 | * and balancing. | |
703 | */ | 703 | */ | |
704 | for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) | 704 | for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) | |
705 | continue; | 705 | continue; | |
706 | olt = tn->tn_type->t_tspec; | 706 | olt = tn->tn_type->t_tspec; | |
707 | for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) | 707 | for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) | |
708 | continue; | 708 | continue; | |
709 | ort = tn->tn_type->t_tspec; | 709 | ort = tn->tn_type->t_tspec; | |
710 | } | 710 | } | |
711 | 711 | |||
712 | switch (op) { | 712 | switch (op) { | |
713 | case POINT: | 713 | case POINT: | |
714 | /* | 714 | /* | |
715 | * Most errors required by ANSI C are reported in strmemb(). | 715 | * Most errors required by ANSI C are reported in strmemb(). | |
716 | * Here we only must check for totaly wrong things. | 716 | * Here we only must check for totaly wrong things. | |
717 | */ | 717 | */ | |
718 | if (lt == FUNC || lt == VOID || ltp->t_isfield || | 718 | if (lt == FUNC || lt == VOID || ltp->t_isfield || | |
719 | ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { | 719 | ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { | |
720 | /* Without tflag we got already an error */ | 720 | /* Without tflag we got already an error */ | |
721 | if (tflag) | 721 | if (tflag) | |
722 | /* unacceptable operand of %s */ | 722 | /* unacceptable operand of %s */ | |
723 | error(111, mp->m_name); | 723 | error(111, mp->m_name); | |
724 | return (0); | 724 | return (0); | |
725 | } | 725 | } | |
726 | /* Now we have an object we can create a pointer to */ | 726 | /* Now we have an object we can create a pointer to */ | |
727 | break; | 727 | break; | |
728 | case ARROW: | 728 | case ARROW: | |
729 | if (lt != PTR && !(tflag && isityp(lt))) { | 729 | if (lt != PTR && !(tflag && isityp(lt))) { | |
730 | /* Without tflag we got already an error */ | 730 | /* Without tflag we got already an error */ | |
731 | if (tflag) | 731 | if (tflag) | |
732 | /* unacceptabel operand of %s */ | 732 | /* unacceptabel operand of %s */ | |
733 | error(111, mp->m_name); | 733 | error(111, mp->m_name); | |
734 | return (0); | 734 | return (0); | |
735 | } | 735 | } | |
736 | break; | 736 | break; | |
737 | case INCAFT: | 737 | case INCAFT: | |
738 | case DECAFT: | 738 | case DECAFT: | |
739 | case INCBEF: | 739 | case INCBEF: | |
740 | case DECBEF: | 740 | case DECBEF: | |
741 | /* operands have scalar types (checked above) */ | 741 | /* operands have scalar types (checked above) */ | |
742 | if (!ln->tn_lvalue) { | 742 | if (!ln->tn_lvalue) { | |
743 | if (ln->tn_op == CVT && ln->tn_cast && | 743 | if (ln->tn_op == CVT && ln->tn_cast && | |
744 | ln->tn_left->tn_op == LOAD) { | 744 | ln->tn_left->tn_op == LOAD) { | |
745 | /* a cast to non-ptr does not yield an lvalue */ | 745 | /* a cast to non-ptr does not yield an lvalue */ | |
746 | if (ln->tn_type->t_tspec == PTR) | 746 | if (ln->tn_type->t_tspec == PTR) | |
747 | break; | 747 | break; | |
748 | error(163); | 748 | error(163); | |
749 | } | 749 | } | |
750 | /* %soperand of %s must be lvalue */ | 750 | /* %soperand of %s must be lvalue */ | |
751 | error(114, "", mp->m_name); | 751 | error(114, "", mp->m_name); | |
752 | return (0); | 752 | return (0); | |
753 | } else if (ltp->t_const) { | 753 | } else if (ltp->t_const) { | |
754 | /* %soperand of %s must be modifiable lvalue */ | 754 | /* %soperand of %s must be modifiable lvalue */ | |
755 | if (!tflag) | 755 | if (!tflag) | |
756 | warning(115, "", mp->m_name); | 756 | warning(115, "", mp->m_name); | |
757 | } | 757 | } | |
758 | break; | 758 | break; | |
759 | case AMPER: | 759 | case AMPER: | |
760 | if (lt == ARRAY || lt == FUNC) { | 760 | if (lt == ARRAY || lt == FUNC) { | |
761 | /* ok, a warning comes later (in bldamper()) */ | 761 | /* ok, a warning comes later (in bldamper()) */ | |
762 | } else if (!ln->tn_lvalue) { | 762 | } else if (!ln->tn_lvalue) { | |
763 | if (ln->tn_op == CVT && ln->tn_cast && | 763 | if (ln->tn_op == CVT && ln->tn_cast && | |
764 | ln->tn_left->tn_op == LOAD) { | 764 | ln->tn_left->tn_op == LOAD) { | |
765 | /* a cast to non-ptr does not yield an lvalue */ | 765 | /* a cast to non-ptr does not yield an lvalue */ | |
766 | if (ln->tn_type->t_tspec == PTR) | 766 | if (ln->tn_type->t_tspec == PTR) | |
767 | break; | 767 | break; | |
768 | error(163); | 768 | error(163); | |
769 | } | 769 | } | |
770 | /* %soperand of %s must be lvalue */ | 770 | /* %soperand of %s must be lvalue */ | |
771 | error(114, "", mp->m_name); | 771 | error(114, "", mp->m_name); | |
772 | return (0); | 772 | return (0); | |
773 | } else if (issclt(lt)) { | 773 | } else if (issclt(lt)) { | |
774 | if (ltp->t_isfield) { | 774 | if (ltp->t_isfield) { | |
775 | /* cannot take address of bit-field */ | 775 | /* cannot take address of bit-field */ | |
776 | error(112); | 776 | error(112); | |
777 | return (0); | 777 | return (0); | |
778 | } | 778 | } | |
779 | } else if (lt != STRUCT && lt != UNION) { | 779 | } else if (lt != STRUCT && lt != UNION) { | |
780 | /* unacceptable operand of %s */ | 780 | /* unacceptable operand of %s */ | |
781 | error(111, mp->m_name); | 781 | error(111, mp->m_name); | |
782 | return (0); | 782 | return (0); | |
783 | } | 783 | } | |
784 | if (ln->tn_op == NAME && ln->tn_sym->s_reg) { | 784 | if (ln->tn_op == NAME && ln->tn_sym->s_reg) { | |
785 | /* cannot take address of register %s */ | 785 | /* cannot take address of register %s */ | |
786 | error(113, ln->tn_sym->s_name); | 786 | error(113, ln->tn_sym->s_name); | |
787 | return (0); | 787 | return (0); | |
788 | } | 788 | } | |
789 | break; | 789 | break; | |
790 | case STAR: | 790 | case STAR: | |
791 | /* until now there were no type checks for this operator */ | 791 | /* until now there were no type checks for this operator */ | |
792 | if (lt != PTR) { | 792 | if (lt != PTR) { | |
793 | /* cannot dereference non-pointer type */ | 793 | /* cannot dereference non-pointer type */ | |
794 | error(96); | 794 | error(96); | |
795 | return (0); | 795 | return (0); | |
796 | } | 796 | } | |
797 | break; | 797 | break; | |
798 | case PLUS: | 798 | case PLUS: | |
799 | /* operands have scalar types (checked above) */ | 799 | /* operands have scalar types (checked above) */ | |
800 | if ((lt == PTR && !isityp(rt)) || (rt == PTR && !isityp(lt))) { | 800 | if ((lt == PTR && !isityp(rt)) || (rt == PTR && !isityp(lt))) { | |
801 | incompat(op, lt, rt); | 801 | incompat(op, lt, rt); | |
802 | return (0); | 802 | return (0); | |
803 | } | 803 | } | |
804 | break; | 804 | break; | |
805 | case MINUS: | 805 | case MINUS: | |
806 | /* operands have scalar types (checked above) */ | 806 | /* operands have scalar types (checked above) */ | |
807 | if (lt == PTR && (!isityp(rt) && rt != PTR)) { | 807 | if (lt == PTR && (!isityp(rt) && rt != PTR)) { | |
808 | incompat(op, lt, rt); | 808 | incompat(op, lt, rt); | |
809 | return (0); | 809 | return (0); | |
810 | } else if (rt == PTR && lt != PTR) { | 810 | } else if (rt == PTR && lt != PTR) { | |
811 | incompat(op, lt, rt); | 811 | incompat(op, lt, rt); | |
812 | return (0); | 812 | return (0); | |
813 | } | 813 | } | |
814 | if (lt == PTR && rt == PTR) { | 814 | if (lt == PTR && rt == PTR) { | |
815 | if (!eqtype(lstp, rstp, 1, 0, NULL)) { | 815 | if (!eqtype(lstp, rstp, 1, 0, NULL)) { | |
816 | /* illegal pointer subtraction */ | 816 | /* illegal pointer subtraction */ | |
817 | error(116); | 817 | error(116); | |
818 | } | 818 | } | |
819 | } | 819 | } | |
820 | break; | 820 | break; | |
821 | case SHR: | 821 | case SHR: | |
822 | /* operands have integer types (checked above) */ | 822 | /* operands have integer types (checked above) */ | |
823 | if (pflag && !isutyp(lt)) { | 823 | if (pflag && !isutyp(lt)) { | |
824 | /* | 824 | /* | |
825 | * The left operand is signed. This means that | 825 | * The left operand is signed. This means that | |
826 | * the operation is (possibly) nonportable. | 826 | * the operation is (possibly) nonportable. | |
827 | */ | 827 | */ | |
828 | /* bitwise operation on signed value nonportable */ | 828 | /* bitwise operation on signed value nonportable */ | |
829 | if (ln->tn_op != CON) { | 829 | if (ln->tn_op != CON) { | |
830 | /* possibly nonportable */ | 830 | /* possibly nonportable */ | |
831 | warning(117); | 831 | warning(117); | |
832 | } else if (ln->tn_val->v_quad < 0) { | 832 | } else if (ln->tn_val->v_quad < 0) { | |
833 | warning(120); | 833 | warning(120); | |
834 | } | 834 | } | |
835 | } else if (!tflag && !sflag && !isutyp(olt) && isutyp(ort)) { | 835 | } else if (!tflag && !sflag && !isutyp(olt) && isutyp(ort)) { | |
836 | /* | 836 | /* | |
837 | * The left operand would become unsigned in | 837 | * The left operand would become unsigned in | |
838 | * traditional C. | 838 | * traditional C. | |
839 | */ | 839 | */ | |
840 | if (hflag && | 840 | if (hflag && | |
841 | (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { | 841 | (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { | |
842 | /* semantics of %s change in ANSI C; use ... */ | 842 | /* semantics of %s change in ANSI C; use ... */ | |
843 | warning(118, mp->m_name); | 843 | warning(118, mp->m_name); | |
844 | } | 844 | } | |
845 | } else if (!tflag && !sflag && !isutyp(olt) && !isutyp(ort) && | 845 | } else if (!tflag && !sflag && !isutyp(olt) && !isutyp(ort) && | |
846 | psize(lt) < psize(rt)) { | 846 | psize(lt) < psize(rt)) { | |
847 | /* | 847 | /* | |
848 | * In traditional C the left operand would be extended, | 848 | * In traditional C the left operand would be extended, | |
849 | * possibly with 1, and then shifted. | 849 | * possibly with 1, and then shifted. | |
850 | */ | 850 | */ | |
851 | if (hflag && | 851 | if (hflag && | |
852 | (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { | 852 | (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { | |
853 | /* semantics of %s change in ANSI C; use ... */ | 853 | /* semantics of %s change in ANSI C; use ... */ | |
854 | warning(118, mp->m_name); | 854 | warning(118, mp->m_name); | |
855 | } | 855 | } | |
856 | } | 856 | } | |
857 | goto shift; | 857 | goto shift; | |
858 | case SHL: | 858 | case SHL: | |
859 | /* | 859 | /* | |
860 | * ANSI C does not perform balancing for shift operations, | 860 | * ANSI C does not perform balancing for shift operations, | |
861 | * but traditional C does. If the width of the right operand | 861 | * but traditional C does. If the width of the right operand | |
862 | * is greather than the width of the left operand, than in | 862 | * is greather than the width of the left operand, than in | |
863 | * traditional C the left operand would be extendet to the | 863 | * traditional C the left operand would be extendet to the | |
864 | * width of the right operand. For SHL this may result in | 864 | * width of the right operand. For SHL this may result in | |
865 | * different results. | 865 | * different results. | |
866 | */ | 866 | */ | |
867 | if (psize(lt) < psize(rt)) { | 867 | if (psize(lt) < psize(rt)) { | |
868 | /* | 868 | /* | |
869 | * XXX If both operands are constant make sure | 869 | * XXX If both operands are constant make sure | |
870 | * that there is really a differencs between | 870 | * that there is really a differencs between | |
871 | * ANSI C and traditional C. | 871 | * ANSI C and traditional C. | |
872 | */ | 872 | */ | |
873 | if (hflag) | 873 | if (hflag) | |
874 | /* semantics of %s change in ANSI C; use ... */ | 874 | /* semantics of %s change in ANSI C; use ... */ | |
875 | warning(118, mp->m_name); | 875 | warning(118, mp->m_name); | |
876 | } | 876 | } | |
877 | shift: | 877 | shift: | |
878 | if (rn->tn_op == CON) { | 878 | if (rn->tn_op == CON) { | |
879 | if (!isutyp(rt) && rn->tn_val->v_quad < 0) { | 879 | if (!isutyp(rt) && rn->tn_val->v_quad < 0) { | |
880 | /* negative shift */ | 880 | /* negative shift */ | |
881 | warning(121); | 881 | warning(121); | |
882 | } else if ((uint64_t)rn->tn_val->v_quad == (uint64_t)size(lt)) { | 882 | } else if ((uint64_t)rn->tn_val->v_quad == (uint64_t)size(lt)) { | |
883 | /* shift equal to size fo object */ | 883 | /* shift equal to size fo object */ | |
884 | warning(267); | 884 | warning(267); | |
885 | } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size(lt)) { | 885 | } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size(lt)) { | |
886 | /* shift greater than size of object */ | 886 | /* shift greater than size of object */ | |
887 | warning(122); | 887 | warning(122); | |
888 | } | 888 | } | |
889 | } | 889 | } | |
890 | break; | 890 | break; | |
891 | case EQ: | 891 | case EQ: | |
892 | case NE: | 892 | case NE: | |
893 | /* | 893 | /* | |
894 | * Accept some things which are allowed with EQ and NE, | 894 | * Accept some things which are allowed with EQ and NE, | |
895 | * but not with ordered comparisons. | 895 | * but not with ordered comparisons. | |
896 | */ | 896 | */ | |
897 | if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { | 897 | if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { | |
898 | if (rn->tn_op == CON && rn->tn_val->v_quad == 0) | 898 | if (rn->tn_op == CON && rn->tn_val->v_quad == 0) | |
899 | break; | 899 | break; | |
900 | } | 900 | } | |
901 | if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { | 901 | if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { | |
902 | if (ln->tn_op == CON && ln->tn_val->v_quad == 0) | 902 | if (ln->tn_op == CON && ln->tn_val->v_quad == 0) | |
903 | break; | 903 | break; | |
904 | } | 904 | } | |
905 | /* FALLTHROUGH */ | 905 | /* FALLTHROUGH */ | |
906 | case LT: | 906 | case LT: | |
907 | case GT: | 907 | case GT: | |
908 | case LE: | 908 | case LE: | |
909 | case GE: | 909 | case GE: | |
910 | if ((lt == PTR || rt == PTR) && lt != rt) { | 910 | if ((lt == PTR || rt == PTR) && lt != rt) { | |
911 | if (isityp(lt) || isityp(rt)) { | 911 | if (isityp(lt) || isityp(rt)) { | |
912 | /* illegal comb. of pointer and int., op %s */ | 912 | /* illegal comb. of pointer and int., op %s */ | |
913 | warning(123, mp->m_name); | 913 | warning(123, mp->m_name); | |
914 | } else { | 914 | } else { | |
915 | incompat(op, lt, rt); | 915 | incompat(op, lt, rt); | |
916 | return (0); | 916 | return (0); | |
917 | } | 917 | } | |
918 | } else if (lt == PTR && rt == PTR) { | 918 | } else if (lt == PTR && rt == PTR) { | |
919 | ptrcmpok(op, ln, rn); | 919 | ptrcmpok(op, ln, rn); | |
920 | } | 920 | } | |
921 | break; | 921 | break; | |
922 | case QUEST: | 922 | case QUEST: | |
923 | if (!issclt(lt)) { | 923 | if (!issclt(lt)) { | |
924 | /* first operand must have scalar type, op ? : */ | 924 | /* first operand must have scalar type, op ? : */ | |
925 | error(170); | 925 | error(170); | |
926 | return (0); | 926 | return (0); | |
927 | } | 927 | } | |
928 | while (rn->tn_op == CVT) | 928 | while (rn->tn_op == CVT) | |
929 | rn = rn->tn_left; | 929 | rn = rn->tn_left; | |
930 | if (rn->tn_op != COLON) | 930 | if (rn->tn_op != COLON) | |
931 | LERROR("typeok()"); | 931 | LERROR("typeok()"); | |
932 | break; | 932 | break; | |
933 | case COLON: | 933 | case COLON: | |
934 | 934 | |||
935 | if (isatyp(lt) && isatyp(rt)) | 935 | if (isatyp(lt) && isatyp(rt)) | |
936 | break; | 936 | break; | |
937 | 937 | |||
938 | if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) | 938 | if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) | |
939 | break; | 939 | break; | |
940 | if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) | 940 | if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) | |
941 | break; | 941 | break; | |
942 | 942 | |||
943 | /* combination of any pointer and 0, 0L or (void *)0 is ok */ | 943 | /* combination of any pointer and 0, 0L or (void *)0 is ok */ | |
944 | if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { | 944 | if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { | |
945 | if (rn->tn_op == CON && rn->tn_val->v_quad == 0) | 945 | if (rn->tn_op == CON && rn->tn_val->v_quad == 0) | |
946 | break; | 946 | break; | |
947 | } | 947 | } | |
948 | if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { | 948 | if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { | |
949 | if (ln->tn_op == CON && ln->tn_val->v_quad == 0) | 949 | if (ln->tn_op == CON && ln->tn_val->v_quad == 0) | |
950 | break; | 950 | break; | |
951 | } | 951 | } | |
952 | 952 | |||
953 | if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) { | 953 | if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) { | |
954 | /* illegal comb. of ptr. and int., op %s */ | 954 | /* illegal comb. of ptr. and int., op %s */ | |
955 | warning(123, mp->m_name); | 955 | warning(123, mp->m_name); | |
956 | break; | 956 | break; | |
957 | } | 957 | } | |
958 | 958 | |||
959 | if (lt == VOID || rt == VOID) { | 959 | if (lt == VOID || rt == VOID) { | |
960 | if (lt != VOID || rt != VOID) | 960 | if (lt != VOID || rt != VOID) | |
961 | /* incompatible types in conditional */ | 961 | /* incompatible types in conditional */ | |
962 | warning(126); | 962 | warning(126); | |
963 | break; | 963 | break; | |
964 | } | 964 | } | |
965 | 965 | |||
966 | if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || | 966 | if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || | |
967 | (lst == FUNC && rst == VOID))) { | 967 | (lst == FUNC && rst == VOID))) { | |
968 | /* (void *)0 handled above */ | 968 | /* (void *)0 handled above */ | |
969 | if (sflag) | 969 | if (sflag) | |
970 | /* ANSI C forbids conv. of %s to %s, op %s */ | 970 | /* ANSI C forbids conv. of %s to %s, op %s */ | |
971 | warning(305, "function pointer", "'void *'", | 971 | warning(305, "function pointer", "'void *'", | |
972 | mp->m_name); | 972 | mp->m_name); | |
973 | break; | 973 | break; | |
974 | } | 974 | } | |
975 | 975 | |||
976 | if (rt == PTR && lt == PTR) { | 976 | if (rt == PTR && lt == PTR) { | |
977 | if (eqptrtype(lstp, rstp, 1)) | 977 | if (eqptrtype(lstp, rstp, 1)) | |
978 | break; | 978 | break; | |
979 | if (!eqtype(lstp, rstp, 1, 0, NULL)) | 979 | if (!eqtype(lstp, rstp, 1, 0, NULL)) | |
980 | illptrc(mp, ltp, rtp); | 980 | illptrc(mp, ltp, rtp); | |
981 | break; | 981 | break; | |
982 | } | 982 | } | |
983 | 983 | |||
984 | /* incompatible types in conditional */ | 984 | /* incompatible types in conditional */ | |
985 | error(126); | 985 | error(126); | |
986 | return (0); | 986 | return (0); | |
987 | 987 | |||
988 | case ASSIGN: | 988 | case ASSIGN: | |
989 | case INIT: | 989 | case INIT: | |
990 | case FARG: | 990 | case FARG: | |
991 | case RETURN: | 991 | case RETURN: | |
992 | if (!asgntypok(op, arg, ln, rn)) | 992 | if (!asgntypok(op, arg, ln, rn)) | |
993 | return (0); | 993 | return (0); | |
994 | goto assign; | 994 | goto assign; | |
995 | case MULASS: | 995 | case MULASS: | |
996 | case DIVASS: | 996 | case DIVASS: | |
997 | case MODASS: | 997 | case MODASS: | |
998 | goto assign; | 998 | goto assign; | |
999 | case ADDASS: | 999 | case ADDASS: | |
1000 | case SUBASS: | 1000 | case SUBASS: | |
1001 | /* operands have scalar types (checked above) */ | 1001 | /* operands have scalar types (checked above) */ | |
1002 | if ((lt == PTR && !isityp(rt)) || rt == PTR) { | 1002 | if ((lt == PTR && !isityp(rt)) || rt == PTR) { | |
1003 | incompat(op, lt, rt); | 1003 | incompat(op, lt, rt); | |
1004 | return (0); | 1004 | return (0); | |
1005 | } | 1005 | } | |
1006 | goto assign; | 1006 | goto assign; | |
1007 | case SHLASS: | 1007 | case SHLASS: | |
1008 | goto assign; | 1008 | goto assign; | |
1009 | case SHRASS: | 1009 | case SHRASS: | |
1010 | if (pflag && !isutyp(lt) && !(tflag && isutyp(rt))) { | 1010 | if (pflag && !isutyp(lt) && !(tflag && isutyp(rt))) { | |
1011 | /* bitwise operation on s.v. possibly nonportable */ | 1011 | /* bitwise operation on s.v. possibly nonportable */ | |
1012 | warning(117); | 1012 | warning(117); | |
1013 | } | 1013 | } | |
1014 | goto assign; | 1014 | goto assign; | |
1015 | case ANDASS: | 1015 | case ANDASS: | |
1016 | case XORASS: | 1016 | case XORASS: | |
1017 | case ORASS: | 1017 | case ORASS: | |
1018 | goto assign; | 1018 | goto assign; | |
1019 | assign: | 1019 | assign: | |
1020 | if (!ln->tn_lvalue) { | 1020 | if (!ln->tn_lvalue) { | |
1021 | if (ln->tn_op == CVT && ln->tn_cast && | 1021 | if (ln->tn_op == CVT && ln->tn_cast && | |
1022 | ln->tn_left->tn_op == LOAD) { | 1022 | ln->tn_left->tn_op == LOAD) { | |
1023 | /* a cast to non-ptr does not yield an lvalue */ | 1023 | /* a cast to non-ptr does not yield an lvalue */ | |
1024 | if (ln->tn_type->t_tspec == PTR) | 1024 | if (ln->tn_type->t_tspec == PTR) | |
1025 | break; | 1025 | break; | |
1026 | error(163); | 1026 | error(163); | |
1027 | } | 1027 | } | |
1028 | /* %soperand of %s must be lvalue */ | 1028 | /* %soperand of %s must be lvalue */ | |
1029 | error(114, "left ", mp->m_name); | 1029 | error(114, "left ", mp->m_name); | |
1030 | return (0); | 1030 | return (0); | |
1031 | } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) && | 1031 | } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) && | |
1032 | conmemb(ltp))) { | 1032 | conmemb(ltp))) { | |
1033 | /* %soperand of %s must be modifiable lvalue */ | 1033 | /* %soperand of %s must be modifiable lvalue */ | |
1034 | if (!tflag) | 1034 | if (!tflag) | |
1035 | warning(115, "left ", mp->m_name); | 1035 | warning(115, "left ", mp->m_name); | |
1036 | } | 1036 | } | |
1037 | break; | 1037 | break; | |
1038 | case COMMA: | 1038 | case COMMA: | |
1039 | if (!modtab[ln->tn_op].m_sideeff) | 1039 | if (!modtab[ln->tn_op].m_sideeff) | |
@@ -2175,1864 +2175,1865 @@ illptrc(mod_t *mp, type_t *ltp, type_t * | @@ -2175,1864 +2175,1865 @@ illptrc(mod_t *mp, type_t *ltp, type_t * | |||
2175 | } else { | 2175 | } else { | |
2176 | /* illegal pointer combination, op %s */ | 2176 | /* illegal pointer combination, op %s */ | |
2177 | warning(124, mp->m_name); | 2177 | warning(124, mp->m_name); | |
2178 | } | 2178 | } | |
2179 | } | 2179 | } | |
2180 | } | 2180 | } | |
2181 | 2181 | |||
2182 | /* | 2182 | /* | |
2183 | * Make sure type (*tpp)->t_subt has at least the qualifiers | 2183 | * Make sure type (*tpp)->t_subt has at least the qualifiers | |
2184 | * of tp1->t_subt and tp2->t_subt. | 2184 | * of tp1->t_subt and tp2->t_subt. | |
2185 | */ | 2185 | */ | |
2186 | static void | 2186 | static void | |
2187 | mrgqual(type_t **tpp, type_t *tp1, type_t *tp2) | 2187 | mrgqual(type_t **tpp, type_t *tp1, type_t *tp2) | |
2188 | { | 2188 | { | |
2189 | 2189 | |||
2190 | if ((*tpp)->t_tspec != PTR || | 2190 | if ((*tpp)->t_tspec != PTR || | |
2191 | tp1->t_tspec != PTR || tp2->t_tspec != PTR) { | 2191 | tp1->t_tspec != PTR || tp2->t_tspec != PTR) { | |
2192 | LERROR("mrgqual()"); | 2192 | LERROR("mrgqual()"); | |
2193 | } | 2193 | } | |
2194 | 2194 | |||
2195 | if ((*tpp)->t_subt->t_const == | 2195 | if ((*tpp)->t_subt->t_const == | |
2196 | (tp1->t_subt->t_const | tp2->t_subt->t_const) && | 2196 | (tp1->t_subt->t_const | tp2->t_subt->t_const) && | |
2197 | (*tpp)->t_subt->t_volatile == | 2197 | (*tpp)->t_subt->t_volatile == | |
2198 | (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) { | 2198 | (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) { | |
2199 | return; | 2199 | return; | |
2200 | } | 2200 | } | |
2201 | 2201 | |||
2202 | *tpp = tduptyp(*tpp); | 2202 | *tpp = tduptyp(*tpp); | |
2203 | (*tpp)->t_subt = tduptyp((*tpp)->t_subt); | 2203 | (*tpp)->t_subt = tduptyp((*tpp)->t_subt); | |
2204 | (*tpp)->t_subt->t_const = | 2204 | (*tpp)->t_subt->t_const = | |
2205 | tp1->t_subt->t_const | tp2->t_subt->t_const; | 2205 | tp1->t_subt->t_const | tp2->t_subt->t_const; | |
2206 | (*tpp)->t_subt->t_volatile = | 2206 | (*tpp)->t_subt->t_volatile = | |
2207 | tp1->t_subt->t_volatile | tp2->t_subt->t_volatile; | 2207 | tp1->t_subt->t_volatile | tp2->t_subt->t_volatile; | |
2208 | } | 2208 | } | |
2209 | 2209 | |||
2210 | /* | 2210 | /* | |
2211 | * Returns 1 if the given structure or union has a constant member | 2211 | * Returns 1 if the given structure or union has a constant member | |
2212 | * (maybe recursively). | 2212 | * (maybe recursively). | |
2213 | */ | 2213 | */ | |
2214 | static int | 2214 | static int | |
2215 | conmemb(type_t *tp) | 2215 | conmemb(type_t *tp) | |
2216 | { | 2216 | { | |
2217 | sym_t *m; | 2217 | sym_t *m; | |
2218 | tspec_t t; | 2218 | tspec_t t; | |
2219 | 2219 | |||
2220 | if ((t = tp->t_tspec) != STRUCT && t != UNION) | 2220 | if ((t = tp->t_tspec) != STRUCT && t != UNION) | |
2221 | LERROR("conmemb()"); | 2221 | LERROR("conmemb()"); | |
2222 | for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) { | 2222 | for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) { | |
2223 | tp = m->s_type; | 2223 | tp = m->s_type; | |
2224 | if (tp->t_const) | 2224 | if (tp->t_const) | |
2225 | return (1); | 2225 | return (1); | |
2226 | if ((t = tp->t_tspec) == STRUCT || t == UNION) { | 2226 | if ((t = tp->t_tspec) == STRUCT || t == UNION) { | |
2227 | if (conmemb(m->s_type)) | 2227 | if (conmemb(m->s_type)) | |
2228 | return (1); | 2228 | return (1); | |
2229 | } | 2229 | } | |
2230 | } | 2230 | } | |
2231 | return (0); | 2231 | return (0); | |
2232 | } | 2232 | } | |
2233 | 2233 | |||
2234 | /* | 2234 | /* | |
2235 | * Create a new node for one of the operators POINT and ARROW. | 2235 | * Create a new node for one of the operators POINT and ARROW. | |
2236 | */ | 2236 | */ | |
2237 | static tnode_t * | 2237 | static tnode_t * | |
2238 | bldstr(op_t op, tnode_t *ln, tnode_t *rn) | 2238 | bldstr(op_t op, tnode_t *ln, tnode_t *rn) | |
2239 | { | 2239 | { | |
2240 | tnode_t *ntn, *ctn; | 2240 | tnode_t *ntn, *ctn; | |
2241 | int nolval; | 2241 | int nolval; | |
2242 | 2242 | |||
2243 | if (rn->tn_op != NAME) | 2243 | if (rn->tn_op != NAME) | |
2244 | LERROR("bldstr()"); | 2244 | LERROR("bldstr()"); | |
2245 | if (rn->tn_sym->s_value.v_tspec != INT) | 2245 | if (rn->tn_sym->s_value.v_tspec != INT) | |
2246 | LERROR("bldstr()"); | 2246 | LERROR("bldstr()"); | |
2247 | if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU) | 2247 | if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU) | |
2248 | LERROR("bldstr()"); | 2248 | LERROR("bldstr()"); | |
2249 | 2249 | |||
2250 | /* | 2250 | /* | |
2251 | * Remember if the left operand is an lvalue (structure members | 2251 | * Remember if the left operand is an lvalue (structure members | |
2252 | * are lvalues if and only if the structure itself is an lvalue). | 2252 | * are lvalues if and only if the structure itself is an lvalue). | |
2253 | */ | 2253 | */ | |
2254 | nolval = op == POINT && !ln->tn_lvalue; | 2254 | nolval = op == POINT && !ln->tn_lvalue; | |
2255 | 2255 | |||
2256 | if (op == POINT) { | 2256 | if (op == POINT) { | |
2257 | ln = bldamper(ln, 1); | 2257 | ln = bldamper(ln, 1); | |
2258 | } else if (ln->tn_type->t_tspec != PTR) { | 2258 | } else if (ln->tn_type->t_tspec != PTR) { | |
2259 | if (!tflag || !isityp(ln->tn_type->t_tspec)) | 2259 | if (!tflag || !isityp(ln->tn_type->t_tspec)) | |
2260 | LERROR("bldstr()"); | 2260 | LERROR("bldstr()"); | |
2261 | ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); | 2261 | ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); | |
2262 | } | 2262 | } | |
2263 | 2263 | |||
2264 | #if PTRDIFF_IS_LONG | 2264 | #if PTRDIFF_IS_LONG | |
2265 | ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT); | 2265 | ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT); | |
2266 | #else | 2266 | #else | |
2267 | ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT); | 2267 | ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT); | |
2268 | #endif | 2268 | #endif | |
2269 | 2269 | |||
2270 | ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn); | 2270 | ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn); | |
2271 | if (ln->tn_op == CON) | 2271 | if (ln->tn_op == CON) | |
2272 | ntn = fold(ntn); | 2272 | ntn = fold(ntn); | |
2273 | 2273 | |||
2274 | if (rn->tn_type->t_isfield) { | 2274 | if (rn->tn_type->t_isfield) { | |
2275 | ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL); | 2275 | ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL); | |
2276 | } else { | 2276 | } else { | |
2277 | ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL); | 2277 | ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL); | |
2278 | } | 2278 | } | |
2279 | 2279 | |||
2280 | if (nolval) | 2280 | if (nolval) | |
2281 | ntn->tn_lvalue = 0; | 2281 | ntn->tn_lvalue = 0; | |
2282 | 2282 | |||
2283 | return (ntn); | 2283 | return (ntn); | |
2284 | } | 2284 | } | |
2285 | 2285 | |||
2286 | /* | 2286 | /* | |
2287 | * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. | 2287 | * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. | |
2288 | */ | 2288 | */ | |
2289 | static tnode_t * | 2289 | static tnode_t * | |
2290 | bldincdec(op_t op, tnode_t *ln) | 2290 | bldincdec(op_t op, tnode_t *ln) | |
2291 | { | 2291 | { | |
2292 | tnode_t *cn, *ntn; | 2292 | tnode_t *cn, *ntn; | |
2293 | 2293 | |||
2294 | if (ln == NULL) | 2294 | if (ln == NULL) | |
2295 | LERROR("bldincdec()"); | 2295 | LERROR("bldincdec()"); | |
2296 | 2296 | |||
2297 | if (ln->tn_type->t_tspec == PTR) { | 2297 | if (ln->tn_type->t_tspec == PTR) { | |
2298 | cn = plength(ln->tn_type); | 2298 | cn = plength(ln->tn_type); | |
2299 | } else { | 2299 | } else { | |
2300 | cn = getinode(INT, (int64_t)1); | 2300 | cn = getinode(INT, (int64_t)1); | |
2301 | } | 2301 | } | |
2302 | ntn = mktnode(op, ln->tn_type, ln, cn); | 2302 | ntn = mktnode(op, ln->tn_type, ln, cn); | |
2303 | 2303 | |||
2304 | return (ntn); | 2304 | return (ntn); | |
2305 | } | 2305 | } | |
2306 | 2306 | |||
2307 | /* | 2307 | /* | |
2308 | * Create a node for REAL, IMAG | 2308 | * Create a node for REAL, IMAG | |
2309 | */ | 2309 | */ | |
2310 | static tnode_t * | 2310 | static tnode_t * | |
2311 | bldri(op_t op, tnode_t *ln) | 2311 | bldri(op_t op, tnode_t *ln) | |
2312 | { | 2312 | { | |
2313 | tnode_t *cn, *ntn; | 2313 | tnode_t *cn, *ntn; | |
2314 | char buf[64]; | 2314 | char buf[64]; | |
2315 | 2315 | |||
2316 | if (ln == NULL) | 2316 | if (ln == NULL) | |
2317 | LERROR("bldincdec()"); | 2317 | LERROR("bldincdec()"); | |
2318 | 2318 | |||
2319 | switch (ln->tn_type->t_tspec) { | 2319 | switch (ln->tn_type->t_tspec) { | |
2320 | case LCOMPLEX: | 2320 | case LCOMPLEX: | |
2321 | cn = getinode(LDOUBLE, (int64_t)1); | 2321 | cn = getinode(LDOUBLE, (int64_t)1); | |
2322 | break; | 2322 | break; | |
2323 | case DCOMPLEX: | 2323 | case DCOMPLEX: | |
2324 | cn = getinode(DOUBLE, (int64_t)1); | 2324 | cn = getinode(DOUBLE, (int64_t)1); | |
2325 | break; | 2325 | break; | |
2326 | case FCOMPLEX: | 2326 | case FCOMPLEX: | |
2327 | cn = getinode(FLOAT, (int64_t)1); | 2327 | cn = getinode(FLOAT, (int64_t)1); | |
2328 | break; | 2328 | break; | |
2329 | default: | 2329 | default: | |
2330 | error(276, op == REAL ? "real" : "imag", | 2330 | error(276, op == REAL ? "real" : "imag", | |
2331 | tyname(buf, sizeof(buf), ln->tn_type)); | 2331 | tyname(buf, sizeof(buf), ln->tn_type)); | |
2332 | return NULL; | 2332 | return NULL; | |
2333 | } | 2333 | } | |
2334 | ntn = mktnode(op, cn->tn_type, ln, cn); | 2334 | ntn = mktnode(op, cn->tn_type, ln, cn); | |
2335 | ntn->tn_lvalue = 1; | 2335 | ntn->tn_lvalue = 1; | |
2336 | 2336 | |||
2337 | return (ntn); | 2337 | return (ntn); | |
2338 | } | 2338 | } | |
2339 | /* | 2339 | /* | |
2340 | * Create a tree node for the & operator | 2340 | * Create a tree node for the & operator | |
2341 | */ | 2341 | */ | |
2342 | static tnode_t * | 2342 | static tnode_t * | |
2343 | bldamper(tnode_t *tn, int noign) | 2343 | bldamper(tnode_t *tn, int noign) | |
2344 | { | 2344 | { | |
2345 | tnode_t *ntn; | 2345 | tnode_t *ntn; | |
2346 | tspec_t t; | 2346 | tspec_t t; | |
2347 | 2347 | |||
2348 | if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { | 2348 | if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { | |
2349 | /* & before array or function: ignored */ | 2349 | /* & before array or function: ignored */ | |
2350 | if (tflag) | 2350 | if (tflag) | |
2351 | warning(127); | 2351 | warning(127); | |
2352 | return (tn); | 2352 | return (tn); | |
2353 | } | 2353 | } | |
2354 | 2354 | |||
2355 | /* eliminate &* */ | 2355 | /* eliminate &* */ | |
2356 | if (tn->tn_op == STAR && | 2356 | if (tn->tn_op == STAR && | |
2357 | tn->tn_left->tn_type->t_tspec == PTR && | 2357 | tn->tn_left->tn_type->t_tspec == PTR && | |
2358 | tn->tn_left->tn_type->t_subt == tn->tn_type) { | 2358 | tn->tn_left->tn_type->t_subt == tn->tn_type) { | |
2359 | return (tn->tn_left); | 2359 | return (tn->tn_left); | |
2360 | } | 2360 | } | |
2361 | 2361 | |||
2362 | ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL); | 2362 | ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL); | |
2363 | 2363 | |||
2364 | return (ntn); | 2364 | return (ntn); | |
2365 | } | 2365 | } | |
2366 | 2366 | |||
2367 | /* | 2367 | /* | |
2368 | * Create a node for operators PLUS and MINUS. | 2368 | * Create a node for operators PLUS and MINUS. | |
2369 | */ | 2369 | */ | |
2370 | static tnode_t * | 2370 | static tnode_t * | |
2371 | bldplmi(op_t op, tnode_t *ln, tnode_t *rn) | 2371 | bldplmi(op_t op, tnode_t *ln, tnode_t *rn) | |
2372 | { | 2372 | { | |
2373 | tnode_t *ntn, *ctn; | 2373 | tnode_t *ntn, *ctn; | |
2374 | type_t *tp; | 2374 | type_t *tp; | |
2375 | 2375 | |||
2376 | /* If pointer and integer, then pointer to the lhs. */ | 2376 | /* If pointer and integer, then pointer to the lhs. */ | |
2377 | if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) { | 2377 | if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) { | |
2378 | ntn = ln; | 2378 | ntn = ln; | |
2379 | ln = rn; | 2379 | ln = rn; | |
2380 | rn = ntn; | 2380 | rn = ntn; | |
2381 | } | 2381 | } | |
2382 | 2382 | |||
2383 | if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { | 2383 | if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { | |
2384 | 2384 | |||
2385 | if (!isityp(rn->tn_type->t_tspec)) | 2385 | if (!isityp(rn->tn_type->t_tspec)) | |
2386 | LERROR("bldplmi()"); | 2386 | LERROR("bldplmi()"); | |
2387 | 2387 | |||
2388 | ctn = plength(ln->tn_type); | 2388 | ctn = plength(ln->tn_type); | |
2389 | if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) | 2389 | if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) | |
2390 | rn = convert(NOOP, 0, ctn->tn_type, rn); | 2390 | rn = convert(NOOP, 0, ctn->tn_type, rn); | |
2391 | rn = mktnode(MULT, rn->tn_type, rn, ctn); | 2391 | rn = mktnode(MULT, rn->tn_type, rn, ctn); | |
2392 | if (rn->tn_left->tn_op == CON) | 2392 | if (rn->tn_left->tn_op == CON) | |
2393 | rn = fold(rn); | 2393 | rn = fold(rn); | |
2394 | ntn = mktnode(op, ln->tn_type, ln, rn); | 2394 | ntn = mktnode(op, ln->tn_type, ln, rn); | |
2395 | 2395 | |||
2396 | } else if (rn->tn_type->t_tspec == PTR) { | 2396 | } else if (rn->tn_type->t_tspec == PTR) { | |
2397 | 2397 | |||
2398 | if (ln->tn_type->t_tspec != PTR || op != MINUS) | 2398 | if (ln->tn_type->t_tspec != PTR || op != MINUS) | |
2399 | LERROR("bldplmi()"); | 2399 | LERROR("bldplmi()"); | |
2400 | #if PTRDIFF_IS_LONG | 2400 | #if PTRDIFF_IS_LONG | |
2401 | tp = gettyp(LONG); | 2401 | tp = gettyp(LONG); | |
2402 | #else | 2402 | #else | |
2403 | tp = gettyp(INT); | 2403 | tp = gettyp(INT); | |
2404 | #endif | 2404 | #endif | |
2405 | ntn = mktnode(op, tp, ln, rn); | 2405 | ntn = mktnode(op, tp, ln, rn); | |
2406 | if (ln->tn_op == CON && rn->tn_op == CON) | 2406 | if (ln->tn_op == CON && rn->tn_op == CON) | |
2407 | ntn = fold(ntn); | 2407 | ntn = fold(ntn); | |
2408 | ctn = plength(ln->tn_type); | 2408 | ctn = plength(ln->tn_type); | |
2409 | balance(NOOP, &ntn, &ctn); | 2409 | balance(NOOP, &ntn, &ctn); | |
2410 | ntn = mktnode(DIV, tp, ntn, ctn); | 2410 | ntn = mktnode(DIV, tp, ntn, ctn); | |
2411 | 2411 | |||
2412 | } else { | 2412 | } else { | |
2413 | 2413 | |||
2414 | ntn = mktnode(op, ln->tn_type, ln, rn); | 2414 | ntn = mktnode(op, ln->tn_type, ln, rn); | |
2415 | 2415 | |||
2416 | } | 2416 | } | |
2417 | return (ntn); | 2417 | return (ntn); | |
2418 | } | 2418 | } | |
2419 | 2419 | |||
2420 | /* | 2420 | /* | |
2421 | * Create a node for operators SHL and SHR. | 2421 | * Create a node for operators SHL and SHR. | |
2422 | */ | 2422 | */ | |
2423 | static tnode_t * | 2423 | static tnode_t * | |
2424 | bldshft(op_t op, tnode_t *ln, tnode_t *rn) | 2424 | bldshft(op_t op, tnode_t *ln, tnode_t *rn) | |
2425 | { | 2425 | { | |
2426 | tspec_t t; | 2426 | tspec_t t; | |
2427 | tnode_t *ntn; | 2427 | tnode_t *ntn; | |
2428 | 2428 | |||
2429 | if ((t = rn->tn_type->t_tspec) != INT && t != UINT) | 2429 | if ((t = rn->tn_type->t_tspec) != INT && t != UINT) | |
2430 | rn = convert(CVT, 0, gettyp(INT), rn); | 2430 | rn = convert(CVT, 0, gettyp(INT), rn); | |
2431 | ntn = mktnode(op, ln->tn_type, ln, rn); | 2431 | ntn = mktnode(op, ln->tn_type, ln, rn); | |
2432 | return (ntn); | 2432 | return (ntn); | |
2433 | } | 2433 | } | |
2434 | 2434 | |||
2435 | /* | 2435 | /* | |
2436 | * Create a node for COLON. | 2436 | * Create a node for COLON. | |
2437 | */ | 2437 | */ | |
2438 | static tnode_t * | 2438 | static tnode_t * | |
2439 | bldcol(tnode_t *ln, tnode_t *rn) | 2439 | bldcol(tnode_t *ln, tnode_t *rn) | |
2440 | { | 2440 | { | |
2441 | tspec_t lt, rt, pdt; | 2441 | tspec_t lt, rt, pdt; | |
2442 | type_t *rtp; | 2442 | type_t *rtp; | |
2443 | tnode_t *ntn; | 2443 | tnode_t *ntn; | |
2444 | 2444 | |||
2445 | lt = ln->tn_type->t_tspec; | 2445 | lt = ln->tn_type->t_tspec; | |
2446 | rt = rn->tn_type->t_tspec; | 2446 | rt = rn->tn_type->t_tspec; | |
2447 | #if PTRDIFF_IS_LONG | 2447 | #if PTRDIFF_IS_LONG | |
2448 | pdt = LONG; | 2448 | pdt = LONG; | |
2449 | #else | 2449 | #else | |
2450 | pdt = INT; | 2450 | pdt = INT; | |
2451 | #endif | 2451 | #endif | |
2452 | 2452 | |||
2453 | /* | 2453 | /* | |
2454 | * Arithmetic types are balanced, all other type combinations | 2454 | * Arithmetic types are balanced, all other type combinations | |
2455 | * still need to be handled. | 2455 | * still need to be handled. | |
2456 | */ | 2456 | */ | |
2457 | if (isatyp(lt) && isatyp(rt)) { | 2457 | if (isatyp(lt) && isatyp(rt)) { | |
2458 | rtp = ln->tn_type; | 2458 | rtp = ln->tn_type; | |
2459 | } else if (lt == VOID || rt == VOID) { | 2459 | } else if (lt == VOID || rt == VOID) { | |
2460 | rtp = gettyp(VOID); | 2460 | rtp = gettyp(VOID); | |
2461 | } else if (lt == STRUCT || lt == UNION) { | 2461 | } else if (lt == STRUCT || lt == UNION) { | |
2462 | /* Both types must be identical. */ | 2462 | /* Both types must be identical. */ | |
2463 | if (rt != STRUCT && rt != UNION) | 2463 | if (rt != STRUCT && rt != UNION) | |
2464 | LERROR("bldcol()"); | 2464 | LERROR("bldcol()"); | |
2465 | if (ln->tn_type->t_str != rn->tn_type->t_str) | 2465 | if (ln->tn_type->t_str != rn->tn_type->t_str) | |
2466 | LERROR("bldcol()"); | 2466 | LERROR("bldcol()"); | |
2467 | if (incompl(ln->tn_type)) { | 2467 | if (incompl(ln->tn_type)) { | |
2468 | /* unknown operand size, op %s */ | 2468 | /* unknown operand size, op %s */ | |
2469 | error(138, modtab[COLON].m_name); | 2469 | error(138, modtab[COLON].m_name); | |
2470 | return (NULL); | 2470 | return (NULL); | |
2471 | } | 2471 | } | |
2472 | rtp = ln->tn_type; | 2472 | rtp = ln->tn_type; | |
2473 | } else if (lt == PTR && isityp(rt)) { | 2473 | } else if (lt == PTR && isityp(rt)) { | |
2474 | if (rt != pdt) { | 2474 | if (rt != pdt) { | |
2475 | rn = convert(NOOP, 0, gettyp(pdt), rn); | 2475 | rn = convert(NOOP, 0, gettyp(pdt), rn); | |
2476 | rt = pdt; | 2476 | rt = pdt; | |
2477 | } | 2477 | } | |
2478 | rtp = ln->tn_type; | 2478 | rtp = ln->tn_type; | |
2479 | } else if (rt == PTR && isityp(lt)) { | 2479 | } else if (rt == PTR && isityp(lt)) { | |
2480 | if (lt != pdt) { | 2480 | if (lt != pdt) { | |
2481 | ln = convert(NOOP, 0, gettyp(pdt), ln); | 2481 | ln = convert(NOOP, 0, gettyp(pdt), ln); | |
2482 | lt = pdt; | 2482 | lt = pdt; | |
2483 | } | 2483 | } | |
2484 | rtp = rn->tn_type; | 2484 | rtp = rn->tn_type; | |
2485 | } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { | 2485 | } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { | |
2486 | if (rt != PTR) | 2486 | if (rt != PTR) | |
2487 | LERROR("bldcol()"); | 2487 | LERROR("bldcol()"); | |
2488 | rtp = ln->tn_type; | 2488 | rtp = ln->tn_type; | |
2489 | mrgqual(&rtp, ln->tn_type, rn->tn_type); | 2489 | mrgqual(&rtp, ln->tn_type, rn->tn_type); | |
2490 | } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { | 2490 | } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { | |
2491 | if (lt != PTR) | 2491 | if (lt != PTR) | |
2492 | LERROR("bldcol()"); | 2492 | LERROR("bldcol()"); | |
2493 | rtp = rn->tn_type; | 2493 | rtp = rn->tn_type; | |
2494 | mrgqual(&rtp, ln->tn_type, rn->tn_type); | 2494 | mrgqual(&rtp, ln->tn_type, rn->tn_type); | |
2495 | } else { | 2495 | } else { | |
2496 | if (lt != PTR || rt != PTR) | 2496 | if (lt != PTR || rt != PTR) | |
2497 | LERROR("bldcol()"); | 2497 | LERROR("bldcol()"); | |
2498 | /* | 2498 | /* | |
2499 | * XXX For now we simply take the left type. This is | 2499 | * XXX For now we simply take the left type. This is | |
2500 | * probably wrong, if one type contains a functionprototype | 2500 | * probably wrong, if one type contains a functionprototype | |
2501 | * and the other one, at the same place, only an old style | 2501 | * and the other one, at the same place, only an old style | |
2502 | * declaration. | 2502 | * declaration. | |
2503 | */ | 2503 | */ | |
2504 | rtp = ln->tn_type; | 2504 | rtp = ln->tn_type; | |
2505 | mrgqual(&rtp, ln->tn_type, rn->tn_type); | 2505 | mrgqual(&rtp, ln->tn_type, rn->tn_type); | |
2506 | } | 2506 | } | |
2507 | 2507 | |||
2508 | ntn = mktnode(COLON, rtp, ln, rn); | 2508 | ntn = mktnode(COLON, rtp, ln, rn); | |
2509 | 2509 | |||
2510 | return (ntn); | 2510 | return (ntn); | |
2511 | } | 2511 | } | |
2512 | 2512 | |||
2513 | /* | 2513 | /* | |
2514 | * Create a node for an assignment operator (both = and op= ). | 2514 | * Create a node for an assignment operator (both = and op= ). | |
2515 | */ | 2515 | */ | |
2516 | static tnode_t * | 2516 | static tnode_t * | |
2517 | bldasgn(op_t op, tnode_t *ln, tnode_t *rn) | 2517 | bldasgn(op_t op, tnode_t *ln, tnode_t *rn) | |
2518 | { | 2518 | { | |
2519 | tspec_t lt, rt; | 2519 | tspec_t lt, rt; | |
2520 | tnode_t *ntn, *ctn; | 2520 | tnode_t *ntn, *ctn; | |
2521 | 2521 | |||
2522 | if (ln == NULL || rn == NULL) | 2522 | if (ln == NULL || rn == NULL) | |
2523 | LERROR("bldasgn()"); | 2523 | LERROR("bldasgn()"); | |
2524 | 2524 | |||
2525 | lt = ln->tn_type->t_tspec; | 2525 | lt = ln->tn_type->t_tspec; | |
2526 | rt = rn->tn_type->t_tspec; | 2526 | rt = rn->tn_type->t_tspec; | |
2527 | 2527 | |||
2528 | if ((op == ADDASS || op == SUBASS) && lt == PTR) { | 2528 | if ((op == ADDASS || op == SUBASS) && lt == PTR) { | |
2529 | if (!isityp(rt)) | 2529 | if (!isityp(rt)) | |
2530 | LERROR("bldasgn()"); | 2530 | LERROR("bldasgn()"); | |
2531 | ctn = plength(ln->tn_type); | 2531 | ctn = plength(ln->tn_type); | |
2532 | if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) | 2532 | if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) | |
2533 | rn = convert(NOOP, 0, ctn->tn_type, rn); | 2533 | rn = convert(NOOP, 0, ctn->tn_type, rn); | |
2534 | rn = mktnode(MULT, rn->tn_type, rn, ctn); | 2534 | rn = mktnode(MULT, rn->tn_type, rn, ctn); | |
2535 | if (rn->tn_left->tn_op == CON) | 2535 | if (rn->tn_left->tn_op == CON) | |
2536 | rn = fold(rn); | 2536 | rn = fold(rn); | |
2537 | } | 2537 | } | |
2538 | 2538 | |||
2539 | if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { | 2539 | if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { | |
2540 | if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str) | 2540 | if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str) | |
2541 | LERROR("bldasgn()"); | 2541 | LERROR("bldasgn()"); | |
2542 | if (incompl(ln->tn_type)) { | 2542 | if (incompl(ln->tn_type)) { | |
2543 | if (op == RETURN) { | 2543 | if (op == RETURN) { | |
2544 | /* cannot return incomplete type */ | 2544 | /* cannot return incomplete type */ | |
2545 | error(212); | 2545 | error(212); | |
2546 | } else { | 2546 | } else { | |
2547 | /* unknown operand size, op %s */ | 2547 | /* unknown operand size, op %s */ | |
2548 | error(138, modtab[op].m_name); | 2548 | error(138, modtab[op].m_name); | |
2549 | } | 2549 | } | |
2550 | return (NULL); | 2550 | return (NULL); | |
2551 | } | 2551 | } | |
2552 | } | 2552 | } | |
2553 | 2553 | |||
2554 | if (op == SHLASS) { | 2554 | if (op == SHLASS) { | |
2555 | if (psize(lt) < psize(rt)) { | 2555 | if (psize(lt) < psize(rt)) { | |
2556 | if (hflag) | 2556 | if (hflag) | |
2557 | /* semantics of %s change in ANSI C; use ... */ | 2557 | /* semantics of %s change in ANSI C; use ... */ | |
2558 | warning(118, "<<="); | 2558 | warning(118, "<<="); | |
2559 | } | 2559 | } | |
2560 | } else if (op != SHRASS) { | 2560 | } else if (op != SHRASS) { | |
2561 | if (op == ASSIGN || lt != PTR) { | 2561 | if (op == ASSIGN || lt != PTR) { | |
2562 | if (lt != rt || | 2562 | if (lt != rt || | |
2563 | (ln->tn_type->t_isfield && rn->tn_op == CON)) { | 2563 | (ln->tn_type->t_isfield && rn->tn_op == CON)) { | |
2564 | rn = convert(op, 0, ln->tn_type, rn); | 2564 | rn = convert(op, 0, ln->tn_type, rn); | |
2565 | rt = lt; | 2565 | rt = lt; | |
2566 | } | 2566 | } | |
2567 | } | 2567 | } | |
2568 | } | 2568 | } | |
2569 | 2569 | |||
2570 | ntn = mktnode(op, ln->tn_type, ln, rn); | 2570 | ntn = mktnode(op, ln->tn_type, ln, rn); | |
2571 | 2571 | |||
2572 | return (ntn); | 2572 | return (ntn); | |
2573 | } | 2573 | } | |
2574 | 2574 | |||
2575 | /* | 2575 | /* | |
2576 | * Get length of type tp->t_subt. | 2576 | * Get length of type tp->t_subt. | |
2577 | */ | 2577 | */ | |
2578 | static tnode_t * | 2578 | static tnode_t * | |
2579 | plength(type_t *tp) | 2579 | plength(type_t *tp) | |
2580 | { | 2580 | { | |
2581 | int elem, elsz; | 2581 | int elem, elsz; | |
2582 | tspec_t st; | 2582 | tspec_t st; | |
2583 | 2583 | |||
2584 | if (tp->t_tspec != PTR) | 2584 | if (tp->t_tspec != PTR) | |
2585 | LERROR("plength()"); | 2585 | LERROR("plength()"); | |
2586 | tp = tp->t_subt; | 2586 | tp = tp->t_subt; | |
2587 | 2587 | |||
2588 | elem = 1; | 2588 | elem = 1; | |
2589 | elsz = 0; | 2589 | elsz = 0; | |
2590 | 2590 | |||
2591 | while (tp->t_tspec == ARRAY) { | 2591 | while (tp->t_tspec == ARRAY) { | |
2592 | elem *= tp->t_dim; | 2592 | elem *= tp->t_dim; | |
2593 | tp = tp->t_subt; | 2593 | tp = tp->t_subt; | |
2594 | } | 2594 | } | |
2595 | 2595 | |||
2596 | switch (tp->t_tspec) { | 2596 | switch (tp->t_tspec) { | |
2597 | case FUNC: | 2597 | case FUNC: | |
2598 | /* pointer to function is not allowed here */ | 2598 | /* pointer to function is not allowed here */ | |
2599 | error(110); | 2599 | error(110); | |
2600 | break; | 2600 | break; | |
2601 | case VOID: | 2601 | case VOID: | |
2602 | /* cannot do pointer arithmetic on operand of ... */ | 2602 | /* cannot do pointer arithmetic on operand of ... */ | |
2603 | (void)gnuism(136); | 2603 | (void)gnuism(136); | |
2604 | break; | 2604 | break; | |
2605 | case STRUCT: | 2605 | case STRUCT: | |
2606 | case UNION: | 2606 | case UNION: | |
2607 | if ((elsz = tp->t_str->size) == 0) | 2607 | if ((elsz = tp->t_str->size) == 0) | |
2608 | /* cannot do pointer arithmetic on operand of ... */ | 2608 | /* cannot do pointer arithmetic on operand of ... */ | |
2609 | error(136); | 2609 | error(136); | |
2610 | break; | 2610 | break; | |
2611 | case ENUM: | 2611 | case ENUM: | |
2612 | if (incompl(tp)) { | 2612 | if (incompl(tp)) { | |
2613 | /* cannot do pointer arithmetic on operand of ... */ | 2613 | /* cannot do pointer arithmetic on operand of ... */ | |
2614 | warning(136); | 2614 | warning(136); | |
2615 | } | 2615 | } | |
2616 | /* FALLTHROUGH */ | 2616 | /* FALLTHROUGH */ | |
2617 | default: | 2617 | default: | |
2618 | if ((elsz = size(tp->t_tspec)) == 0) { | 2618 | if ((elsz = size(tp->t_tspec)) == 0) { | |
2619 | /* cannot do pointer arithmetic on operand of ... */ | 2619 | /* cannot do pointer arithmetic on operand of ... */ | |
2620 | error(136); | 2620 | error(136); | |
2621 | } else if (elsz == -1) { | 2621 | } else if (elsz == -1) { | |
2622 | LERROR("plength()"); | 2622 | LERROR("plength()"); | |
2623 | } | 2623 | } | |
2624 | break; | 2624 | break; | |
2625 | } | 2625 | } | |
2626 | 2626 | |||
2627 | if (elem == 0 && elsz != 0) { | 2627 | if (elem == 0 && elsz != 0) { | |
2628 | /* cannot do pointer arithmetic on operand of ... */ | 2628 | /* cannot do pointer arithmetic on operand of ... */ | |
2629 | error(136); | 2629 | error(136); | |
2630 | } | 2630 | } | |
2631 | 2631 | |||
2632 | if (elsz == 0) | 2632 | if (elsz == 0) | |
2633 | elsz = CHAR_BIT; | 2633 | elsz = CHAR_BIT; | |
2634 | 2634 | |||
2635 | #if PTRDIFF_IS_LONG | 2635 | #if PTRDIFF_IS_LONG | |
2636 | st = LONG; | 2636 | st = LONG; | |
2637 | #else | 2637 | #else | |
2638 | st = INT; | 2638 | st = INT; | |
2639 | #endif | 2639 | #endif | |
2640 | 2640 | |||
2641 | return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); | 2641 | return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); | |
2642 | } | 2642 | } | |
2643 | 2643 | |||
2644 | /* | 2644 | /* | |
2645 | * XXX | 2645 | * XXX | |
2646 | * Note: There appear to be a number of bugs in detecting overflow in | 2646 | * Note: There appear to be a number of bugs in detecting overflow in | |
2647 | * this function. An audit and a set of proper regression tests are needed. | 2647 | * this function. An audit and a set of proper regression tests are needed. | |
2648 | * --Perry Metzger, Nov. 16, 2001 | 2648 | * --Perry Metzger, Nov. 16, 2001 | |
2649 | */ | 2649 | */ | |
2650 | /* | 2650 | /* | |
2651 | * Do only as much as necessary to compute constant expressions. | 2651 | * Do only as much as necessary to compute constant expressions. | |
2652 | * Called only if the operator allows folding and (both) operands | 2652 | * Called only if the operator allows folding and (both) operands | |
2653 | * are constants. | 2653 | * are constants. | |
2654 | */ | 2654 | */ | |
2655 | static tnode_t * | 2655 | static tnode_t * | |
2656 | fold(tnode_t *tn) | 2656 | fold(tnode_t *tn) | |
2657 | { | 2657 | { | |
2658 | val_t *v; | 2658 | val_t *v; | |
2659 | tspec_t t; | 2659 | tspec_t t; | |
2660 | int utyp, ovfl; | 2660 | int utyp, ovfl; | |
2661 | int64_t sl, sr = 0, q = 0, mask; | 2661 | int64_t sl, sr = 0, q = 0, mask; | |
2662 | uint64_t ul, ur = 0; | 2662 | uint64_t ul, ur = 0; | |
2663 | tnode_t *cn; | 2663 | tnode_t *cn; | |
2664 | 2664 | |||
2665 | v = xcalloc(1, sizeof (val_t)); | 2665 | v = xcalloc(1, sizeof (val_t)); | |
2666 | v->v_tspec = t = tn->tn_type->t_tspec; | 2666 | v->v_tspec = t = tn->tn_type->t_tspec; | |
2667 | 2667 | |||
2668 | utyp = t == PTR || isutyp(t); | 2668 | utyp = t == PTR || isutyp(t); | |
2669 | ul = sl = tn->tn_left->tn_val->v_quad; | 2669 | ul = sl = tn->tn_left->tn_val->v_quad; | |
2670 | if (modtab[tn->tn_op].m_binary) | 2670 | if (modtab[tn->tn_op].m_binary) | |
2671 | ur = sr = tn->tn_right->tn_val->v_quad; | 2671 | ur = sr = tn->tn_right->tn_val->v_quad; | |
2672 | 2672 | |||
2673 | mask = qlmasks[size(t)]; | 2673 | mask = qlmasks[size(t)]; | |
2674 | ovfl = 0; | 2674 | ovfl = 0; | |
2675 | 2675 | |||
2676 | switch (tn->tn_op) { | 2676 | switch (tn->tn_op) { | |
2677 | case UPLUS: | 2677 | case UPLUS: | |
2678 | q = sl; | 2678 | q = sl; | |
2679 | break; | 2679 | break; | |
2680 | case UMINUS: | 2680 | case UMINUS: | |
2681 | q = -sl; | 2681 | q = -sl; | |
2682 | if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1)) | 2682 | if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1)) | |
2683 | ovfl = 1; | 2683 | ovfl = 1; | |
2684 | break; | 2684 | break; | |
2685 | case COMPL: | 2685 | case COMPL: | |
2686 | q = ~sl; | 2686 | q = ~sl; | |
2687 | break; | 2687 | break; | |
2688 | case MULT: | 2688 | case MULT: | |
2689 | if (utyp) { | 2689 | if (utyp) { | |
2690 | q = ul * ur; | 2690 | q = ul * ur; | |
2691 | if (q != (q & mask)) | 2691 | if (q != (q & mask)) | |
2692 | ovfl = 1; | 2692 | ovfl = 1; | |
2693 | else if ((ul != 0) && ((q / ul) != ur)) | 2693 | else if ((ul != 0) && ((q / ul) != ur)) | |
2694 | ovfl = 1; | 2694 | ovfl = 1; | |
2695 | } else { | 2695 | } else { | |
2696 | q = sl * sr; | 2696 | q = sl * sr; | |
2697 | if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) | 2697 | if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) | |
2698 | ovfl = 1; | 2698 | ovfl = 1; | |
2699 | } | 2699 | } | |
2700 | break; | 2700 | break; | |
2701 | case DIV: | 2701 | case DIV: | |
2702 | if (sr == 0) { | 2702 | if (sr == 0) { | |
2703 | /* division by 0 */ | 2703 | /* division by 0 */ | |
2704 | error(139); | 2704 | error(139); | |
2705 | q = utyp ? UQUAD_MAX : QUAD_MAX; | 2705 | q = utyp ? UQUAD_MAX : QUAD_MAX; | |
2706 | } else { | 2706 | } else { | |
2707 | q = utyp ? (int64_t)(ul / ur) : sl / sr; | 2707 | q = utyp ? (int64_t)(ul / ur) : sl / sr; | |
2708 | } | 2708 | } | |
2709 | break; | 2709 | break; | |
2710 | case MOD: | 2710 | case MOD: | |
2711 | if (sr == 0) { | 2711 | if (sr == 0) { | |
2712 | /* modulus by 0 */ | 2712 | /* modulus by 0 */ | |
2713 | error(140); | 2713 | error(140); | |
2714 | q = 0; | 2714 | q = 0; | |
2715 | } else { | 2715 | } else { | |
2716 | q = utyp ? (int64_t)(ul % ur) : sl % sr; | 2716 | q = utyp ? (int64_t)(ul % ur) : sl % sr; | |
2717 | } | 2717 | } | |
2718 | break; | 2718 | break; | |
2719 | case PLUS: | 2719 | case PLUS: | |
2720 | q = utyp ? (int64_t)(ul + ur) : sl + sr; | 2720 | q = utyp ? (int64_t)(ul + ur) : sl + sr; | |
2721 | if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { | 2721 | if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { | |
2722 | if (msb(q, t, -1) == 0) | 2722 | if (msb(q, t, -1) == 0) | |
2723 | ovfl = 1; | 2723 | ovfl = 1; | |
2724 | } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { | 2724 | } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { | |
2725 | if (msb(q, t, -1) != 0) | 2725 | if (msb(q, t, -1) != 0) | |
2726 | ovfl = 1; | 2726 | ovfl = 1; | |
2727 | } | 2727 | } | |
2728 | break; | 2728 | break; | |
2729 | case MINUS: | 2729 | case MINUS: | |
2730 | q = utyp ? (int64_t)(ul - ur) : sl - sr; | 2730 | q = utyp ? (int64_t)(ul - ur) : sl - sr; | |
2731 | if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { | 2731 | if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { | |
2732 | if (msb(q, t, -1) == 0) | 2732 | if (msb(q, t, -1) == 0) | |
2733 | ovfl = 1; | 2733 | ovfl = 1; | |
2734 | } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { | 2734 | } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { | |
2735 | if (msb(q, t, -1) != 0) | 2735 | if (msb(q, t, -1) != 0) | |
2736 | ovfl = 1; | 2736 | ovfl = 1; | |
2737 | } | 2737 | } | |
2738 | break; | 2738 | break; | |
2739 | case SHL: | 2739 | case SHL: | |
2740 | q = utyp ? (int64_t)(ul << sr) : sl << sr; | 2740 | q = utyp ? (int64_t)(ul << sr) : sl << sr; | |
2741 | break; | 2741 | break; | |
2742 | case SHR: | 2742 | case SHR: | |
2743 | /* | 2743 | /* | |
2744 | * The sign must be explicitly extended because | 2744 | * The sign must be explicitly extended because | |
2745 | * shifts of signed values are implementation dependent. | 2745 | * shifts of signed values are implementation dependent. | |
2746 | */ | 2746 | */ | |
2747 | q = ul >> sr; | 2747 | q = ul >> sr; | |
2748 | q = xsign(q, t, size(t) - (int)sr); | 2748 | q = xsign(q, t, size(t) - (int)sr); | |
2749 | break; | 2749 | break; | |
2750 | case LT: | 2750 | case LT: | |
2751 | q = utyp ? ul < ur : sl < sr; | 2751 | q = utyp ? ul < ur : sl < sr; | |
2752 | break; | 2752 | break; | |
2753 | case LE: | 2753 | case LE: | |
2754 | q = utyp ? ul <= ur : sl <= sr; | 2754 | q = utyp ? ul <= ur : sl <= sr; | |
2755 | break; | 2755 | break; | |
2756 | case GE: | 2756 | case GE: | |
2757 | q = utyp ? ul >= ur : sl >= sr; | 2757 | q = utyp ? ul >= ur : sl >= sr; | |
2758 | break; | 2758 | break; | |
2759 | case GT: | 2759 | case GT: | |
2760 | q = utyp ? ul > ur : sl > sr; | 2760 | q = utyp ? ul > ur : sl > sr; | |
2761 | break; | 2761 | break; | |
2762 | case EQ: | 2762 | case EQ: | |
2763 | q = utyp ? ul == ur : sl == sr; | 2763 | q = utyp ? ul == ur : sl == sr; | |
2764 | break; | 2764 | break; | |
2765 | case NE: | 2765 | case NE: | |
2766 | q = utyp ? ul != ur : sl != sr; | 2766 | q = utyp ? ul != ur : sl != sr; | |
2767 | break; | 2767 | break; | |
2768 | case AND: | 2768 | case AND: | |
2769 | q = utyp ? (int64_t)(ul & ur) : sl & sr; | 2769 | q = utyp ? (int64_t)(ul & ur) : sl & sr; | |
2770 | break; | 2770 | break; | |
2771 | case XOR: | 2771 | case XOR: | |
2772 | q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr; | 2772 | q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr; | |
2773 | break; | 2773 | break; | |
2774 | case OR: | 2774 | case OR: | |
2775 | q = utyp ? (int64_t)(ul | ur) : sl | sr; | 2775 | q = utyp ? (int64_t)(ul | ur) : sl | sr; | |
2776 | break; | 2776 | break; | |
2777 | default: | 2777 | default: | |
2778 | LERROR("fold()"); | 2778 | LERROR("fold()"); | |
2779 | } | 2779 | } | |
2780 | 2780 | |||
2781 | /* XXX does not work for quads. */ | 2781 | /* XXX does not work for quads. */ | |
2782 | if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && | 2782 | if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && | |
2783 | (q & ~mask) != 0)) { | 2783 | (q & ~mask) != 0)) { | |
2784 | if (hflag) | 2784 | if (hflag) | |
2785 | /* integer overflow detected, op %s */ | 2785 | /* integer overflow detected, op %s */ | |
2786 | warning(141, modtab[tn->tn_op].m_name); | 2786 | warning(141, modtab[tn->tn_op].m_name); | |
2787 | } | 2787 | } | |
2788 | 2788 | |||
2789 | v->v_quad = xsign(q, t, -1); | 2789 | v->v_quad = xsign(q, t, -1); | |
2790 | 2790 | |||
2791 | cn = getcnode(tn->tn_type, v); | 2791 | cn = getcnode(tn->tn_type, v); | |
2792 | 2792 | |||
2793 | return (cn); | 2793 | return (cn); | |
2794 | } | 2794 | } | |
2795 | 2795 | |||
2796 | /* | 2796 | /* | |
2797 | * Same for operators whose operands are compared with 0 (test context). | 2797 | * Same for operators whose operands are compared with 0 (test context). | |
2798 | */ | 2798 | */ | |
2799 | static tnode_t * | 2799 | static tnode_t * | |
2800 | foldtst(tnode_t *tn) | 2800 | foldtst(tnode_t *tn) | |
2801 | { | 2801 | { | |
2802 | int l, r = 0; | 2802 | int l, r = 0; | |
2803 | val_t *v; | 2803 | val_t *v; | |
2804 | 2804 | |||
2805 | v = xcalloc(1, sizeof (val_t)); | 2805 | v = xcalloc(1, sizeof (val_t)); | |
2806 | v->v_tspec = tn->tn_type->t_tspec; | 2806 | v->v_tspec = tn->tn_type->t_tspec; | |
2807 | if (tn->tn_type->t_tspec != INT) | 2807 | if (tn->tn_type->t_tspec != INT) | |
2808 | LERROR("foldtst()"); | 2808 | LERROR("foldtst()"); | |
2809 | 2809 | |||
2810 | if (isftyp(tn->tn_left->tn_type->t_tspec)) { | 2810 | if (isftyp(tn->tn_left->tn_type->t_tspec)) { | |
2811 | l = tn->tn_left->tn_val->v_ldbl != 0.0; | 2811 | l = tn->tn_left->tn_val->v_ldbl != 0.0; | |
2812 | } else { | 2812 | } else { | |
2813 | l = tn->tn_left->tn_val->v_quad != 0; | 2813 | l = tn->tn_left->tn_val->v_quad != 0; | |
2814 | } | 2814 | } | |
2815 | 2815 | |||
2816 | if (modtab[tn->tn_op].m_binary) { | 2816 | if (modtab[tn->tn_op].m_binary) { | |
2817 | if (isftyp(tn->tn_right->tn_type->t_tspec)) { | 2817 | if (isftyp(tn->tn_right->tn_type->t_tspec)) { | |
2818 | r = tn->tn_right->tn_val->v_ldbl != 0.0; | 2818 | r = tn->tn_right->tn_val->v_ldbl != 0.0; | |
2819 | } else { | 2819 | } else { | |
2820 | r = tn->tn_right->tn_val->v_quad != 0; | 2820 | r = tn->tn_right->tn_val->v_quad != 0; | |
2821 | } | 2821 | } | |
2822 | } | 2822 | } | |
2823 | 2823 | |||
2824 | switch (tn->tn_op) { | 2824 | switch (tn->tn_op) { | |
2825 | case NOT: | 2825 | case NOT: | |
2826 | if (hflag && !ccflg) | 2826 | if (hflag && !ccflg) | |
2827 | /* constant argument to NOT */ | 2827 | /* constant argument to NOT */ | |
2828 | warning(239); | 2828 | warning(239); | |
2829 | v->v_quad = !l; | 2829 | v->v_quad = !l; | |
2830 | break; | 2830 | break; | |
2831 | case LOGAND: | 2831 | case LOGAND: | |
2832 | v->v_quad = l && r; | 2832 | v->v_quad = l && r; | |
2833 | break; | 2833 | break; | |
2834 | case LOGOR: | 2834 | case LOGOR: | |
2835 | v->v_quad = l || r; | 2835 | v->v_quad = l || r; | |
2836 | break; | 2836 | break; | |
2837 | default: | 2837 | default: | |
2838 | LERROR("foldtst()"); | 2838 | LERROR("foldtst()"); | |
2839 | } | 2839 | } | |
2840 | 2840 | |||
2841 | return (getcnode(tn->tn_type, v)); | 2841 | return (getcnode(tn->tn_type, v)); | |
2842 | } | 2842 | } | |
2843 | 2843 | |||
2844 | /* | 2844 | /* | |
2845 | * Same for operands with floating point type. | 2845 | * Same for operands with floating point type. | |
2846 | */ | 2846 | */ | |
2847 | static tnode_t * | 2847 | static tnode_t * | |
2848 | foldflt(tnode_t *tn) | 2848 | foldflt(tnode_t *tn) | |
2849 | { | 2849 | { | |
2850 | val_t *v; | 2850 | val_t *v; | |
2851 | tspec_t t; | 2851 | tspec_t t; | |
2852 | ldbl_t l, r = 0; | 2852 | ldbl_t l, r = 0; | |
2853 | 2853 | |||
2854 | fpe = 0; | 2854 | fpe = 0; | |
2855 | v = xcalloc(1, sizeof (val_t)); | 2855 | v = xcalloc(1, sizeof (val_t)); | |
2856 | v->v_tspec = t = tn->tn_type->t_tspec; | 2856 | v->v_tspec = t = tn->tn_type->t_tspec; | |
2857 | 2857 | |||
2858 | if (!isftyp(t)) | 2858 | if (!isftyp(t)) | |
2859 | LERROR("foldflt()"); | 2859 | LERROR("foldflt()"); | |
2860 | 2860 | |||
2861 | if (t != tn->tn_left->tn_type->t_tspec) | 2861 | if (t != tn->tn_left->tn_type->t_tspec) | |
2862 | LERROR("foldflt()"); | 2862 | LERROR("foldflt()"); | |
2863 | if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) | 2863 | if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) | |
2864 | LERROR("foldflt()"); | 2864 | LERROR("foldflt()"); | |
2865 | 2865 | |||
2866 | l = tn->tn_left->tn_val->v_ldbl; | 2866 | l = tn->tn_left->tn_val->v_ldbl; | |
2867 | if (modtab[tn->tn_op].m_binary) | 2867 | if (modtab[tn->tn_op].m_binary) | |
2868 | r = tn->tn_right->tn_val->v_ldbl; | 2868 | r = tn->tn_right->tn_val->v_ldbl; | |
2869 | 2869 | |||
2870 | switch (tn->tn_op) { | 2870 | switch (tn->tn_op) { | |
2871 | case UPLUS: | 2871 | case UPLUS: | |
2872 | v->v_ldbl = l; | 2872 | v->v_ldbl = l; | |
2873 | break; | 2873 | break; | |
2874 | case UMINUS: | 2874 | case UMINUS: | |
2875 | v->v_ldbl = -l; | 2875 | v->v_ldbl = -l; | |
2876 | break; | 2876 | break; | |
2877 | case MULT: | 2877 | case MULT: | |
2878 | v->v_ldbl = l * r; | 2878 | v->v_ldbl = l * r; | |
2879 | break; | 2879 | break; | |
2880 | case DIV: | 2880 | case DIV: | |
2881 | if (r == 0.0) { | 2881 | if (r == 0.0) { | |
2882 | /* division by 0 */ | 2882 | /* division by 0 */ | |
2883 | error(139); | 2883 | error(139); | |
2884 | if (t == FLOAT) { | 2884 | if (t == FLOAT) { | |
2885 | v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; | 2885 | v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; | |
2886 | } else if (t == DOUBLE) { | 2886 | } else if (t == DOUBLE) { | |
2887 | v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; | 2887 | v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; | |
2888 | } else { | 2888 | } else { | |
2889 | v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; | 2889 | v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; | |
2890 | } | 2890 | } | |
2891 | } else { | 2891 | } else { | |
2892 | v->v_ldbl = l / r; | 2892 | v->v_ldbl = l / r; | |
2893 | } | 2893 | } | |
2894 | break; | 2894 | break; | |
2895 | case PLUS: | 2895 | case PLUS: | |
2896 | v->v_ldbl = l + r; | 2896 | v->v_ldbl = l + r; | |
2897 | break; | 2897 | break; | |
2898 | case MINUS: | 2898 | case MINUS: | |
2899 | v->v_ldbl = l - r; | 2899 | v->v_ldbl = l - r; | |
2900 | break; | 2900 | break; | |
2901 | case LT: | 2901 | case LT: | |
2902 | v->v_quad = l < r; | 2902 | v->v_quad = l < r; | |
2903 | break; | 2903 | break; | |
2904 | case LE: | 2904 | case LE: | |
2905 | v->v_quad = l <= r; | 2905 | v->v_quad = l <= r; | |
2906 | break; | 2906 | break; | |
2907 | case GE: | 2907 | case GE: | |
2908 | v->v_quad = l >= r; | 2908 | v->v_quad = l >= r; | |
2909 | break; | 2909 | break; | |
2910 | case GT: | 2910 | case GT: | |
2911 | v->v_quad = l > r; | 2911 | v->v_quad = l > r; | |
2912 | break; | 2912 | break; | |
2913 | case EQ: | 2913 | case EQ: | |
2914 | v->v_quad = l == r; | 2914 | v->v_quad = l == r; | |
2915 | break; | 2915 | break; | |
2916 | case NE: | 2916 | case NE: | |
2917 | v->v_quad = l != r; | 2917 | v->v_quad = l != r; | |
2918 | break; | 2918 | break; | |
2919 | default: | 2919 | default: | |
2920 | LERROR("foldflt()"); | 2920 | LERROR("foldflt()"); | |
2921 | } | 2921 | } | |
2922 | 2922 | |||
2923 | if (!fpe && isnan((double)v->v_ldbl)) | 2923 | if (!fpe && isnan((double)v->v_ldbl)) | |
2924 | LERROR("foldflt()"); | 2924 | LERROR("foldflt()"); | |
2925 | if (fpe || !finite((double)v->v_ldbl) || | 2925 | if (fpe || !finite((double)v->v_ldbl) || | |
2926 | (t == FLOAT && | 2926 | (t == FLOAT && | |
2927 | (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || | 2927 | (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || | |
2928 | (t == DOUBLE && | 2928 | (t == DOUBLE && | |
2929 | (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { | 2929 | (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { | |
2930 | /* floating point overflow detected, op %s */ | 2930 | /* floating point overflow detected, op %s */ | |
2931 | warning(142, modtab[tn->tn_op].m_name); | 2931 | warning(142, modtab[tn->tn_op].m_name); | |
2932 | if (t == FLOAT) { | 2932 | if (t == FLOAT) { | |
2933 | v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; | 2933 | v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; | |
2934 | } else if (t == DOUBLE) { | 2934 | } else if (t == DOUBLE) { | |
2935 | v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; | 2935 | v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; | |
2936 | } else { | 2936 | } else { | |
2937 | v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; | 2937 | v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; | |
2938 | } | 2938 | } | |
2939 | fpe = 0; | 2939 | fpe = 0; | |
2940 | } | 2940 | } | |
2941 | 2941 | |||
2942 | return (getcnode(tn->tn_type, v)); | 2942 | return (getcnode(tn->tn_type, v)); | |
2943 | } | 2943 | } | |
2944 | 2944 | |||
2945 | 2945 | |||
2946 | /* | 2946 | /* | |
2947 | * Create a constant node for sizeof. | 2947 | * Create a constant node for sizeof. | |
2948 | */ | 2948 | */ | |
2949 | tnode_t * | 2949 | tnode_t * | |
2950 | bldszof(type_t *tp) | 2950 | bldszof(type_t *tp) | |
2951 | { | 2951 | { | |
2952 | tspec_t st; | 2952 | tspec_t st; | |
2953 | #if SIZEOF_IS_ULONG | 2953 | #if SIZEOF_IS_ULONG | |
2954 | st = ULONG; | 2954 | st = ULONG; | |
2955 | #else | 2955 | #else | |
2956 | st = UINT; | 2956 | st = UINT; | |
2957 | #endif | 2957 | #endif | |
2958 | return getinode(st, tsize(tp) / CHAR_BIT); | 2958 | return getinode(st, tsize(tp) / CHAR_BIT); | |
2959 | } | 2959 | } | |
2960 | 2960 | |||
2961 | int64_t | 2961 | int64_t | |
2962 | tsize(type_t *tp) | 2962 | tsize(type_t *tp) | |
2963 | { | 2963 | { | |
2964 | int elem, elsz; | 2964 | int elem, elsz; | |
2965 | 2965 | |||
2966 | elem = 1; | 2966 | elem = 1; | |
2967 | while (tp->t_tspec == ARRAY) { | 2967 | while (tp->t_tspec == ARRAY) { | |
2968 | elem *= tp->t_dim; | 2968 | elem *= tp->t_dim; | |
2969 | tp = tp->t_subt; | 2969 | tp = tp->t_subt; | |
2970 | } | 2970 | } | |
2971 | if (elem == 0) { | 2971 | if (elem == 0) { | |
2972 | /* cannot take size of incomplete type */ | 2972 | /* cannot take size of incomplete type */ | |
2973 | error(143); | 2973 | error(143); | |
2974 | elem = 1; | 2974 | elem = 1; | |
2975 | } | 2975 | } | |
2976 | switch (tp->t_tspec) { | 2976 | switch (tp->t_tspec) { | |
2977 | case FUNC: | 2977 | case FUNC: | |
2978 | /* cannot take size of function */ | 2978 | /* cannot take size of function */ | |
2979 | error(144); | 2979 | error(144); | |
2980 | elsz = 1; | 2980 | elsz = 1; | |
2981 | break; | 2981 | break; | |
2982 | case STRUCT: | 2982 | case STRUCT: | |
2983 | case UNION: | 2983 | case UNION: | |
2984 | if (incompl(tp)) { | 2984 | if (incompl(tp)) { | |
2985 | /* cannot take size of incomplete type */ | 2985 | /* cannot take size of incomplete type */ | |
2986 | error(143); | 2986 | error(143); | |
2987 | elsz = 1; | 2987 | elsz = 1; | |
2988 | } else { | 2988 | } else { | |
2989 | elsz = tp->t_str->size; | 2989 | elsz = tp->t_str->size; | |
2990 | } | 2990 | } | |
2991 | break; | 2991 | break; | |
2992 | case ENUM: | 2992 | case ENUM: | |
2993 | if (incompl(tp)) { | 2993 | if (incompl(tp)) { | |
2994 | /* cannot take size of incomplete type */ | 2994 | /* cannot take size of incomplete type */ | |
2995 | warning(143); | 2995 | warning(143); | |
2996 | } | 2996 | } | |
2997 | /* FALLTHROUGH */ | 2997 | /* FALLTHROUGH */ | |
2998 | default: | 2998 | default: | |
2999 | if (tp->t_isfield) { | 2999 | if (tp->t_isfield) { | |
3000 | /* cannot take size of bit-field */ | 3000 | /* cannot take size of bit-field */ | |
3001 | error(145); | 3001 | error(145); | |
3002 | } | 3002 | } | |
3003 | if (tp->t_tspec == VOID) { | 3003 | if (tp->t_tspec == VOID) { | |
3004 | /* cannot take size of void */ | 3004 | /* cannot take size of void */ | |
3005 | error(146); | 3005 | error(146); | |
3006 | elsz = 1; | 3006 | elsz = 1; | |
3007 | } else { | 3007 | } else { | |
3008 | elsz = size(tp->t_tspec); | 3008 | elsz = size(tp->t_tspec); | |
3009 | if (elsz <= 0) | 3009 | if (elsz <= 0) | |
3010 | LERROR("bldszof()"); | 3010 | LERROR("bldszof()"); | |
3011 | } | 3011 | } | |
3012 | break; | 3012 | break; | |
3013 | } | 3013 | } | |
3014 | 3014 | |||
3015 | return (int64_t)(elem * elsz); | 3015 | return (int64_t)(elem * elsz); | |
3016 | } | 3016 | } | |
3017 | 3017 | |||
3018 | /* | 3018 | /* | |
3019 | */ | 3019 | */ | |
3020 | tnode_t * | 3020 | tnode_t * | |
3021 | bldalof(type_t *tp) | 3021 | bldalof(type_t *tp) | |
3022 | { | 3022 | { | |
3023 | tspec_t st; | 3023 | tspec_t st; | |
3024 | 3024 | |||
3025 | switch (tp->t_tspec) { | 3025 | switch (tp->t_tspec) { | |
3026 | case ARRAY: | 3026 | case ARRAY: | |
3027 | break; | 3027 | break; | |
3028 | 3028 | |||
3029 | case FUNC: | 3029 | case FUNC: | |
3030 | /* cannot take align of function */ | 3030 | /* cannot take align of function */ | |
3031 | error(144); | 3031 | error(144); | |
3032 | return 0; | 3032 | return 0; | |
3033 | 3033 | |||
3034 | case STRUCT: | 3034 | case STRUCT: | |
3035 | case UNION: | 3035 | case UNION: | |
3036 | if (incompl(tp)) { | 3036 | if (incompl(tp)) { | |
3037 | /* cannot take align of incomplete type */ | 3037 | /* cannot take align of incomplete type */ | |
3038 | error(143); | 3038 | error(143); | |
3039 | return 0; | 3039 | return 0; | |
3040 | } | 3040 | } | |
3041 | break; | 3041 | break; | |
3042 | case ENUM: | 3042 | case ENUM: | |
3043 | break; | 3043 | break; | |
3044 | default: | 3044 | default: | |
3045 | if (tp->t_isfield) { | 3045 | if (tp->t_isfield) { | |
3046 | /* cannot take align of bit-field */ | 3046 | /* cannot take align of bit-field */ | |
3047 | error(145); | 3047 | error(145); | |
3048 | return 0; | 3048 | return 0; | |
3049 | } | 3049 | } | |
3050 | if (tp->t_tspec == VOID) { | 3050 | if (tp->t_tspec == VOID) { | |
3051 | /* cannot take alignsize of void */ | 3051 | /* cannot take alignsize of void */ | |
3052 | error(146); | 3052 | error(146); | |
3053 | return 0; | 3053 | return 0; | |
3054 | } | 3054 | } | |
3055 | break; | 3055 | break; | |
3056 | } | 3056 | } | |
3057 | 3057 | |||
3058 | #if SIZEOF_IS_ULONG | 3058 | #if SIZEOF_IS_ULONG | |
3059 | st = ULONG; | 3059 | st = ULONG; | |
3060 | #else | 3060 | #else | |
3061 | st = UINT; | 3061 | st = UINT; | |
3062 | #endif | 3062 | #endif | |
3063 | 3063 | |||
3064 | return getinode(st, (int64_t)getbound(tp)); | 3064 | return getinode(st, (int64_t)getbound(tp)); | |
3065 | } | 3065 | } | |
3066 | 3066 | |||
3067 | /* | 3067 | /* | |
3068 | * Type casts. | 3068 | * Type casts. | |
3069 | */ | 3069 | */ | |
3070 | tnode_t * | 3070 | tnode_t * | |
3071 | cast(tnode_t *tn, type_t *tp) | 3071 | cast(tnode_t *tn, type_t *tp) | |
3072 | { | 3072 | { | |
3073 | tspec_t nt, ot; | 3073 | tspec_t nt, ot; | |
3074 | 3074 | |||
3075 | if (tn == NULL) | 3075 | if (tn == NULL) | |
3076 | return (NULL); | 3076 | return (NULL); | |
3077 | 3077 | |||
3078 | tn = cconv(tn); | 3078 | tn = cconv(tn); | |
3079 | 3079 | |||
3080 | nt = tp->t_tspec; | 3080 | nt = tp->t_tspec; | |
3081 | ot = tn->tn_type->t_tspec; | 3081 | ot = tn->tn_type->t_tspec; | |
3082 | 3082 | |||
3083 | if (nt == VOID) { | 3083 | if (nt == VOID) { | |
3084 | /* | 3084 | /* | |
3085 | * XXX ANSI C requires scalar types or void (Plauger&Brodie). | 3085 | * XXX ANSI C requires scalar types or void (Plauger&Brodie). | |
3086 | * But this seams really questionable. | 3086 | * But this seams really questionable. | |
3087 | */ | 3087 | */ | |
3088 | } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) { | 3088 | } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) { | |
3089 | /* invalid cast expression */ | 3089 | /* invalid cast expression */ | |
3090 | error(147); | 3090 | error(147); | |
3091 | return (NULL); | 3091 | return (NULL); | |
3092 | } else if (ot == STRUCT || ot == UNION) { | 3092 | } else if (ot == STRUCT || ot == UNION) { | |
3093 | /* invalid cast expression */ | 3093 | /* invalid cast expression */ | |
3094 | error(147); | 3094 | error(147); | |
3095 | return (NULL); | 3095 | return (NULL); | |
3096 | } else if (ot == VOID) { | 3096 | } else if (ot == VOID) { | |
3097 | /* improper cast of void expression */ | 3097 | /* improper cast of void expression */ | |
3098 | error(148); | 3098 | error(148); | |
3099 | return (NULL); | 3099 | return (NULL); | |
3100 | } else if (isityp(nt) && issclt(ot)) { | 3100 | } else if (isityp(nt) && issclt(ot)) { | |
3101 | /* ok */ | 3101 | /* ok */ | |
3102 | } else if (isftyp(nt) && isatyp(ot)) { | 3102 | } else if (isftyp(nt) && isatyp(ot)) { | |
3103 | /* ok */ | 3103 | /* ok */ | |
3104 | } else if (nt == PTR && isityp(ot)) { | 3104 | } else if (nt == PTR && isityp(ot)) { | |
3105 | /* ok */ | 3105 | /* ok */ | |
3106 | } else if (nt == PTR && ot == PTR) { | 3106 | } else if (nt == PTR && ot == PTR) { | |
3107 | if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { | 3107 | if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { | |
3108 | if (hflag) | 3108 | if (hflag) | |
3109 | /* cast discards 'const' from ... */ | 3109 | /* cast discards 'const' from ... */ | |
3110 | warning(275); | 3110 | warning(275); | |
3111 | } | 3111 | } | |
3112 | } else { | 3112 | } else { | |
3113 | /* invalid cast expression */ | 3113 | /* invalid cast expression */ | |
3114 | error(147); | 3114 | error(147); | |
3115 | return (NULL); | 3115 | return (NULL); | |
3116 | } | 3116 | } | |
3117 | 3117 | |||
3118 | tn = convert(CVT, 0, tp, tn); | 3118 | tn = convert(CVT, 0, tp, tn); | |
3119 | tn->tn_cast = 1; | 3119 | tn->tn_cast = 1; | |
3120 | 3120 | |||
3121 | return (tn); | 3121 | return (tn); | |
3122 | } | 3122 | } | |
3123 | 3123 | |||
3124 | /* | 3124 | /* | |
3125 | * Create the node for a function argument. | 3125 | * Create the node for a function argument. | |
3126 | * All necessary conversions and type checks are done in funccall(), because | 3126 | * All necessary conversions and type checks are done in funccall(), because | |
3127 | * in funcarg() we have no information about expected argument types. | 3127 | * in funcarg() we have no information about expected argument types. | |
3128 | */ | 3128 | */ | |
3129 | tnode_t * | 3129 | tnode_t * | |
3130 | funcarg(tnode_t *args, tnode_t *arg) | 3130 | funcarg(tnode_t *args, tnode_t *arg) | |
3131 | { | 3131 | { | |
3132 | tnode_t *ntn; | 3132 | tnode_t *ntn; | |
3133 | 3133 | |||
3134 | /* | 3134 | /* | |
3135 | * If there was a serious error in the expression for the argument, | 3135 | * If there was a serious error in the expression for the argument, | |
3136 | * create a dummy argument so the positions of the remaining arguments | 3136 | * create a dummy argument so the positions of the remaining arguments | |
3137 | * will not change. | 3137 | * will not change. | |
3138 | */ | 3138 | */ | |
3139 | if (arg == NULL) | 3139 | if (arg == NULL) | |
3140 | arg = getinode(INT, (int64_t)0); | 3140 | arg = getinode(INT, (int64_t)0); | |
3141 | 3141 | |||
3142 | ntn = mktnode(PUSH, arg->tn_type, arg, args); | 3142 | ntn = mktnode(PUSH, arg->tn_type, arg, args); | |
3143 | 3143 | |||
3144 | return (ntn); | 3144 | return (ntn); | |
3145 | } | 3145 | } | |
3146 | 3146 | |||
3147 | /* | 3147 | /* | |
3148 | * Create the node for a function call. Also check types of | 3148 | * Create the node for a function call. Also check types of | |
3149 | * function arguments and insert conversions, if necessary. | 3149 | * function arguments and insert conversions, if necessary. | |
3150 | */ | 3150 | */ | |
3151 | tnode_t * | 3151 | tnode_t * | |
3152 | funccall(tnode_t *func, tnode_t *args) | 3152 | funccall(tnode_t *func, tnode_t *args) | |
3153 | { | 3153 | { | |
3154 | tnode_t *ntn; | 3154 | tnode_t *ntn; | |
3155 | op_t fcop; | 3155 | op_t fcop; | |
3156 | 3156 | |||
3157 | if (func == NULL) | 3157 | if (func == NULL) | |
3158 | return (NULL); | 3158 | return (NULL); | |
3159 | 3159 | |||
3160 | if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { | 3160 | if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { | |
3161 | fcop = CALL; | 3161 | fcop = CALL; | |
3162 | } else { | 3162 | } else { | |
3163 | fcop = ICALL; | 3163 | fcop = ICALL; | |
3164 | } | 3164 | } | |
3165 | 3165 | |||
3166 | /* | 3166 | /* | |
3167 | * after cconv() func will always be a pointer to a function | 3167 | * after cconv() func will always be a pointer to a function | |
3168 | * if it is a valid function designator. | 3168 | * if it is a valid function designator. | |
3169 | */ | 3169 | */ | |
3170 | func = cconv(func); | 3170 | func = cconv(func); | |
3171 | 3171 | |||
3172 | if (func->tn_type->t_tspec != PTR || | 3172 | if (func->tn_type->t_tspec != PTR || | |
3173 | func->tn_type->t_subt->t_tspec != FUNC) { | 3173 | func->tn_type->t_subt->t_tspec != FUNC) { | |
3174 | char buf[256]; | |||
3174 | /* illegal function */ | 3175 | /* illegal function */ | |
3175 | error(149); | 3176 | error(149, tyname(buf, sizeof(buf), func->tn_type)); | |
3176 | return (NULL); | 3177 | return (NULL); | |
3177 | } | 3178 | } | |
3178 | 3179 | |||
3179 | args = chkfarg(func->tn_type->t_subt, args); | 3180 | args = chkfarg(func->tn_type->t_subt, args); | |
3180 | 3181 | |||
3181 | ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args); | 3182 | ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args); | |
3182 | 3183 | |||
3183 | return (ntn); | 3184 | return (ntn); | |
3184 | } | 3185 | } | |
3185 | 3186 | |||
3186 | /* | 3187 | /* | |
3187 | * Check types of all function arguments and insert conversions, | 3188 | * Check types of all function arguments and insert conversions, | |
3188 | * if necessary. | 3189 | * if necessary. | |
3189 | */ | 3190 | */ | |
3190 | static tnode_t * | 3191 | static tnode_t * | |
3191 | chkfarg(type_t *ftp, tnode_t *args) | 3192 | chkfarg(type_t *ftp, tnode_t *args) | |
3192 | { | 3193 | { | |
3193 | tnode_t *arg; | 3194 | tnode_t *arg; | |
3194 | sym_t *asym; | 3195 | sym_t *asym; | |
3195 | tspec_t at; | 3196 | tspec_t at; | |
3196 | int narg, npar, n, i; | 3197 | int narg, npar, n, i; | |
3197 | 3198 | |||
3198 | /* get # of args in the prototype */ | 3199 | /* get # of args in the prototype */ | |
3199 | npar = 0; | 3200 | npar = 0; | |
3200 | for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt) | 3201 | for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt) | |
3201 | npar++; | 3202 | npar++; | |
3202 | 3203 | |||
3203 | /* get # of args in function call */ | 3204 | /* get # of args in function call */ | |
3204 | narg = 0; | 3205 | narg = 0; | |
3205 | for (arg = args; arg != NULL; arg = arg->tn_right) | 3206 | for (arg = args; arg != NULL; arg = arg->tn_right) | |
3206 | narg++; | 3207 | narg++; | |
3207 | 3208 | |||
3208 | asym = ftp->t_args; | 3209 | asym = ftp->t_args; | |
3209 | if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { | 3210 | if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { | |
3210 | /* argument mismatch: %d arg%s passed, %d expected */ | 3211 | /* argument mismatch: %d arg%s passed, %d expected */ | |
3211 | error(150, narg, narg > 1 ? "s" : "", npar); | 3212 | error(150, narg, narg > 1 ? "s" : "", npar); | |
3212 | asym = NULL; | 3213 | asym = NULL; | |
3213 | } | 3214 | } | |
3214 | 3215 | |||
3215 | for (n = 1; n <= narg; n++) { | 3216 | for (n = 1; n <= narg; n++) { | |
3216 | 3217 | |||
3217 | /* | 3218 | /* | |
3218 | * The rightmost argument is at the top of the argument | 3219 | * The rightmost argument is at the top of the argument | |
3219 | * subtree. | 3220 | * subtree. | |
3220 | */ | 3221 | */ | |
3221 | for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) | 3222 | for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) | |
3222 | continue; | 3223 | continue; | |
3223 | 3224 | |||
3224 | /* some things which are always not allowd */ | 3225 | /* some things which are always not allowd */ | |
3225 | if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { | 3226 | if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { | |
3226 | /* void expressions may not be arguments, arg #%d */ | 3227 | /* void expressions may not be arguments, arg #%d */ | |
3227 | error(151, n); | 3228 | error(151, n); | |
3228 | return (NULL); | 3229 | return (NULL); | |
3229 | } else if ((at == STRUCT || at == UNION) && | 3230 | } else if ((at == STRUCT || at == UNION) && | |
3230 | incompl(arg->tn_left->tn_type)) { | 3231 | incompl(arg->tn_left->tn_type)) { | |
3231 | /* argument cannot have unknown size, arg #%d */ | 3232 | /* argument cannot have unknown size, arg #%d */ | |
3232 | error(152, n); | 3233 | error(152, n); | |
3233 | return (NULL); | 3234 | return (NULL); | |
3234 | } else if (isityp(at) && arg->tn_left->tn_type->t_isenum && | 3235 | } else if (isityp(at) && arg->tn_left->tn_type->t_isenum && | |
3235 | incompl(arg->tn_left->tn_type)) { | 3236 | incompl(arg->tn_left->tn_type)) { | |
3236 | /* argument cannot have unknown size, arg #%d */ | 3237 | /* argument cannot have unknown size, arg #%d */ | |
3237 | warning(152, n); | 3238 | warning(152, n); | |
3238 | } | 3239 | } | |
3239 | 3240 | |||
3240 | /* class conversions (arg in value context) */ | 3241 | /* class conversions (arg in value context) */ | |
3241 | arg->tn_left = cconv(arg->tn_left); | 3242 | arg->tn_left = cconv(arg->tn_left); | |
3242 | 3243 | |||
3243 | if (asym != NULL) { | 3244 | if (asym != NULL) { | |
3244 | arg->tn_left = parg(n, asym->s_type, arg->tn_left); | 3245 | arg->tn_left = parg(n, asym->s_type, arg->tn_left); | |
3245 | } else { | 3246 | } else { | |
3246 | arg->tn_left = promote(NOOP, 1, arg->tn_left); | 3247 | arg->tn_left = promote(NOOP, 1, arg->tn_left); | |
3247 | } | 3248 | } | |
3248 | arg->tn_type = arg->tn_left->tn_type; | 3249 | arg->tn_type = arg->tn_left->tn_type; | |
3249 | 3250 | |||
3250 | if (asym != NULL) | 3251 | if (asym != NULL) | |
3251 | asym = asym->s_nxt; | 3252 | asym = asym->s_nxt; | |
3252 | } | 3253 | } | |
3253 | 3254 | |||
3254 | return (args); | 3255 | return (args); | |
3255 | } | 3256 | } | |
3256 | 3257 | |||
3257 | /* | 3258 | /* | |
3258 | * Compare the type of an argument with the corresponding type of a | 3259 | * Compare the type of an argument with the corresponding type of a | |
3259 | * prototype parameter. If it is a valid combination, but both types | 3260 | * prototype parameter. If it is a valid combination, but both types | |
3260 | * are not the same, insert a conversion to convert the argument into | 3261 | * are not the same, insert a conversion to convert the argument into | |
3261 | * the type of the parameter. | 3262 | * the type of the parameter. | |
3262 | */ | 3263 | */ | |
3263 | static tnode_t * | 3264 | static tnode_t * | |
3264 | parg( int n, /* pos of arg */ | 3265 | parg( int n, /* pos of arg */ | |
3265 | type_t *tp, /* expected type (from prototype) */ | 3266 | type_t *tp, /* expected type (from prototype) */ | |
3266 | tnode_t *tn) /* argument */ | 3267 | tnode_t *tn) /* argument */ | |
3267 | { | 3268 | { | |
3268 | tnode_t *ln; | 3269 | tnode_t *ln; | |
3269 | int dowarn; | 3270 | int dowarn; | |
3270 | 3271 | |||
3271 | ln = xcalloc(1, sizeof (tnode_t)); | 3272 | ln = xcalloc(1, sizeof (tnode_t)); | |
3272 | ln->tn_type = tduptyp(tp); | 3273 | ln->tn_type = tduptyp(tp); | |
3273 | ln->tn_type->t_const = 0; | 3274 | ln->tn_type->t_const = 0; | |
3274 | ln->tn_lvalue = 1; | 3275 | ln->tn_lvalue = 1; | |
3275 | if (typeok(FARG, n, ln, tn)) { | 3276 | if (typeok(FARG, n, ln, tn)) { | |
3276 | if (!eqtype(tp, tn->tn_type, 1, 0, (dowarn = 0, &dowarn)) || dowarn) | 3277 | if (!eqtype(tp, tn->tn_type, 1, 0, (dowarn = 0, &dowarn)) || dowarn) | |
3277 | tn = convert(FARG, n, tp, tn); | 3278 | tn = convert(FARG, n, tp, tn); | |
3278 | } | 3279 | } | |
3279 | free(ln); | 3280 | free(ln); | |
3280 | return (tn); | 3281 | return (tn); | |
3281 | } | 3282 | } | |
3282 | 3283 | |||
3283 | /* | 3284 | /* | |
3284 | * Return the value of an integral constant expression. | 3285 | * Return the value of an integral constant expression. | |
3285 | * If the expression is not constant or its type is not an integer | 3286 | * If the expression is not constant or its type is not an integer | |
3286 | * type, an error message is printed. | 3287 | * type, an error message is printed. | |
3287 | */ | 3288 | */ | |
3288 | val_t * | 3289 | val_t * | |
3289 | constant(tnode_t *tn, int required) | 3290 | constant(tnode_t *tn, int required) | |
3290 | { | 3291 | { | |
3291 | val_t *v; | 3292 | val_t *v; | |
3292 | 3293 | |||
3293 | if (tn != NULL) | 3294 | if (tn != NULL) | |
3294 | tn = cconv(tn); | 3295 | tn = cconv(tn); | |
3295 | if (tn != NULL) | 3296 | if (tn != NULL) | |
3296 | tn = promote(NOOP, 0, tn); | 3297 | tn = promote(NOOP, 0, tn); | |
3297 | 3298 | |||
3298 | v = xcalloc(1, sizeof (val_t)); | 3299 | v = xcalloc(1, sizeof (val_t)); | |
3299 | 3300 | |||
3300 | if (tn == NULL) { | 3301 | if (tn == NULL) { | |
3301 | if (nerr == 0) | 3302 | if (nerr == 0) | |
3302 | LERROR("constant()"); | 3303 | LERROR("constant()"); | |
3303 | v->v_tspec = INT; | 3304 | v->v_tspec = INT; | |
3304 | v->v_quad = 1; | 3305 | v->v_quad = 1; | |
3305 | return (v); | 3306 | return (v); | |
3306 | } | 3307 | } | |
3307 | 3308 | |||
3308 | v->v_tspec = tn->tn_type->t_tspec; | 3309 | v->v_tspec = tn->tn_type->t_tspec; | |
3309 | 3310 | |||
3310 | if (tn->tn_op == CON) { | 3311 | if (tn->tn_op == CON) { | |
3311 | if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) | 3312 | if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) | |
3312 | LERROR("constant()"); | 3313 | LERROR("constant()"); | |
3313 | if (isityp(tn->tn_val->v_tspec)) { | 3314 | if (isityp(tn->tn_val->v_tspec)) { | |
3314 | v->v_ansiu = tn->tn_val->v_ansiu; | 3315 | v->v_ansiu = tn->tn_val->v_ansiu; | |
3315 | v->v_quad = tn->tn_val->v_quad; | 3316 | v->v_quad = tn->tn_val->v_quad; | |
3316 | return (v); | 3317 | return (v); | |
3317 | } | 3318 | } | |
3318 | v->v_quad = tn->tn_val->v_ldbl; | 3319 | v->v_quad = tn->tn_val->v_ldbl; | |
3319 | } else { | 3320 | } else { | |
3320 | v->v_quad = 1; | 3321 | v->v_quad = 1; | |
3321 | } | 3322 | } | |
3322 | 3323 | |||
3323 | /* integral constant expression expected */ | 3324 | /* integral constant expression expected */ | |
3324 | if (required) | 3325 | if (required) | |
3325 | error(55); | 3326 | error(55); | |
3326 | else | 3327 | else | |
3327 | c99ism(318); | 3328 | c99ism(318); | |
3328 | 3329 | |||
3329 | if (!isityp(v->v_tspec)) | 3330 | if (!isityp(v->v_tspec)) | |
3330 | v->v_tspec = INT; | 3331 | v->v_tspec = INT; | |
3331 | 3332 | |||
3332 | return (v); | 3333 | return (v); | |
3333 | } | 3334 | } | |
3334 | 3335 | |||
3335 | /* | 3336 | /* | |
3336 | * Perform some tests on expressions which can't be done in build() and | 3337 | * Perform some tests on expressions which can't be done in build() and | |
3337 | * functions called by build(). These tests must be done here because | 3338 | * functions called by build(). These tests must be done here because | |
3338 | * we need some information about the context in which the operations | 3339 | * we need some information about the context in which the operations | |
3339 | * are performed. | 3340 | * are performed. | |
3340 | * After all tests are performed, expr() frees the memory which is used | 3341 | * After all tests are performed, expr() frees the memory which is used | |
3341 | * for the expression. | 3342 | * for the expression. | |
3342 | */ | 3343 | */ | |
3343 | void | 3344 | void | |
3344 | expr(tnode_t *tn, int vctx, int tctx, int dofreeblk) | 3345 | expr(tnode_t *tn, int vctx, int tctx, int dofreeblk) | |
3345 | { | 3346 | { | |
3346 | 3347 | |||
3347 | if (tn == NULL && nerr == 0) | 3348 | if (tn == NULL && nerr == 0) | |
3348 | LERROR("expr()"); | 3349 | LERROR("expr()"); | |
3349 | 3350 | |||
3350 | if (tn == NULL) { | 3351 | if (tn == NULL) { | |
3351 | tfreeblk(); | 3352 | tfreeblk(); | |
3352 | return; | 3353 | return; | |
3353 | } | 3354 | } | |
3354 | 3355 | |||
3355 | /* expr() is also called in global initialisations */ | 3356 | /* expr() is also called in global initialisations */ | |
3356 | if (dcs->d_ctx != EXTERN) | 3357 | if (dcs->d_ctx != EXTERN) | |
3357 | chkreach(); | 3358 | chkreach(); | |
3358 | 3359 | |||
3359 | chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0); | 3360 | chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0); | |
3360 | if (tn->tn_op == ASSIGN) { | 3361 | if (tn->tn_op == ASSIGN) { | |
3361 | if (hflag && tctx) | 3362 | if (hflag && tctx) | |
3362 | /* assignment in conditional context */ | 3363 | /* assignment in conditional context */ | |
3363 | warning(159); | 3364 | warning(159); | |
3364 | } else if (tn->tn_op == CON) { | 3365 | } else if (tn->tn_op == CON) { | |
3365 | if (hflag && tctx && !ccflg) | 3366 | if (hflag && tctx && !ccflg) | |
3366 | /* constant in conditional context */ | 3367 | /* constant in conditional context */ | |
3367 | warning(161); | 3368 | warning(161); | |
3368 | } | 3369 | } | |
3369 | if (!modtab[tn->tn_op].m_sideeff) { | 3370 | if (!modtab[tn->tn_op].m_sideeff) { | |
3370 | /* | 3371 | /* | |
3371 | * for left operands of COMMA this warning is already | 3372 | * for left operands of COMMA this warning is already | |
3372 | * printed | 3373 | * printed | |
3373 | */ | 3374 | */ | |
3374 | if (tn->tn_op != COMMA && !vctx && !tctx) | 3375 | if (tn->tn_op != COMMA && !vctx && !tctx) | |
3375 | nulleff(tn); | 3376 | nulleff(tn); | |
3376 | } | 3377 | } | |
3377 | if (dflag) | 3378 | if (dflag) | |
3378 | displexpr(tn, 0); | 3379 | displexpr(tn, 0); | |
3379 | 3380 | |||
3380 | /* free the tree memory */ | 3381 | /* free the tree memory */ | |
3381 | if (dofreeblk) | 3382 | if (dofreeblk) | |
3382 | tfreeblk(); | 3383 | tfreeblk(); | |
3383 | } | 3384 | } | |
3384 | 3385 | |||
3385 | static void | 3386 | static void | |
3386 | nulleff(tnode_t *tn) | 3387 | nulleff(tnode_t *tn) | |
3387 | { | 3388 | { | |
3388 | 3389 | |||
3389 | if (!hflag) | 3390 | if (!hflag) | |
3390 | return; | 3391 | return; | |
3391 | 3392 | |||
3392 | while (!modtab[tn->tn_op].m_sideeff) { | 3393 | while (!modtab[tn->tn_op].m_sideeff) { | |
3393 | if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { | 3394 | if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { | |
3394 | tn = tn->tn_left; | 3395 | tn = tn->tn_left; | |
3395 | } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { | 3396 | } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { | |
3396 | /* | 3397 | /* | |
3397 | * && and || have a side effect if the right operand | 3398 | * && and || have a side effect if the right operand | |
3398 | * has a side effect. | 3399 | * has a side effect. | |
3399 | */ | 3400 | */ | |
3400 | tn = tn->tn_right; | 3401 | tn = tn->tn_right; | |
3401 | } else if (tn->tn_op == QUEST) { | 3402 | } else if (tn->tn_op == QUEST) { | |
3402 | /* | 3403 | /* | |
3403 | * ? has a side effect if at least one of its right | 3404 | * ? has a side effect if at least one of its right | |
3404 | * operands has a side effect | 3405 | * operands has a side effect | |
3405 | */ | 3406 | */ | |
3406 | tn = tn->tn_right; | 3407 | tn = tn->tn_right; | |
3407 | } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { | 3408 | } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { | |
3408 | /* | 3409 | /* | |
3409 | * : has a side effect if at least one of its operands | 3410 | * : has a side effect if at least one of its operands | |
3410 | * has a side effect | 3411 | * has a side effect | |
3411 | */ | 3412 | */ | |
3412 | if (modtab[tn->tn_left->tn_op].m_sideeff) { | 3413 | if (modtab[tn->tn_left->tn_op].m_sideeff) { | |
3413 | tn = tn->tn_left; | 3414 | tn = tn->tn_left; | |
3414 | } else if (modtab[tn->tn_right->tn_op].m_sideeff) { | 3415 | } else if (modtab[tn->tn_right->tn_op].m_sideeff) { | |
3415 | tn = tn->tn_right; | 3416 | tn = tn->tn_right; | |
3416 | } else { | 3417 | } else { | |
3417 | break; | 3418 | break; | |
3418 | } | 3419 | } | |
3419 | } else { | 3420 | } else { | |
3420 | break; | 3421 | break; | |
3421 | } | 3422 | } | |
3422 | } | 3423 | } | |
3423 | if (!modtab[tn->tn_op].m_sideeff) | 3424 | if (!modtab[tn->tn_op].m_sideeff) | |
3424 | /* expression has null effect */ | 3425 | /* expression has null effect */ | |
3425 | warning(129); | 3426 | warning(129); | |
3426 | } | 3427 | } | |
3427 | 3428 | |||
3428 | /* | 3429 | /* | |
3429 | * Dump an expression to stdout | 3430 | * Dump an expression to stdout | |
3430 | * only used for debugging | 3431 | * only used for debugging | |
3431 | */ | 3432 | */ | |
3432 | static void | 3433 | static void | |
3433 | displexpr(tnode_t *tn, int offs) | 3434 | displexpr(tnode_t *tn, int offs) | |
3434 | { | 3435 | { | |
3435 | uint64_t uq; | 3436 | uint64_t uq; | |
3436 | 3437 | |||
3437 | if (tn == NULL) { | 3438 | if (tn == NULL) { | |
3438 | (void)printf("%*s%s\n", offs, "", "NULL"); | 3439 | (void)printf("%*s%s\n", offs, "", "NULL"); | |
3439 | return; | 3440 | return; | |
3440 | } | 3441 | } | |
3441 | (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); | 3442 | (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); | |
3442 | 3443 | |||
3443 | if (tn->tn_op == NAME) { | 3444 | if (tn->tn_op == NAME) { | |
3444 | (void)printf("%s: %s ", | 3445 | (void)printf("%s: %s ", | |
3445 | tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl)); | 3446 | tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl)); | |
3446 | } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) { | 3447 | } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) { | |
3447 | (void)printf("%#g ", (double)tn->tn_val->v_ldbl); | 3448 | (void)printf("%#g ", (double)tn->tn_val->v_ldbl); | |
3448 | } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) { | 3449 | } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) { | |
3449 | uq = tn->tn_val->v_quad; | 3450 | uq = tn->tn_val->v_quad; | |
3450 | (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl, | 3451 | (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl, | |
3451 | (long)uq & 0xffffffffl); | 3452 | (long)uq & 0xffffffffl); | |
3452 | } else if (tn->tn_op == CON) { | 3453 | } else if (tn->tn_op == CON) { | |
3453 | if (tn->tn_type->t_tspec != PTR) | 3454 | if (tn->tn_type->t_tspec != PTR) | |
3454 | LERROR("displexpr()"); | 3455 | LERROR("displexpr()"); | |
3455 | (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), | 3456 | (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), | |
3456 | (u_long)tn->tn_val->v_quad); | 3457 | (u_long)tn->tn_val->v_quad); | |
3457 | } else if (tn->tn_op == STRING) { | 3458 | } else if (tn->tn_op == STRING) { | |
3458 | if (tn->tn_strg->st_tspec == CHAR) { | 3459 | if (tn->tn_strg->st_tspec == CHAR) { | |
3459 | (void)printf("\"%s\"", tn->tn_strg->st_cp); | 3460 | (void)printf("\"%s\"", tn->tn_strg->st_cp); | |
3460 | } else { | 3461 | } else { | |
3461 | char *s; | 3462 | char *s; | |
3462 | size_t n; | 3463 | size_t n; | |
3463 | n = MB_CUR_MAX * (tn->tn_strg->st_len + 1); | 3464 | n = MB_CUR_MAX * (tn->tn_strg->st_len + 1); | |
3464 | s = xmalloc(n); | 3465 | s = xmalloc(n); | |
3465 | (void)wcstombs(s, tn->tn_strg->st_wcp, n); | 3466 | (void)wcstombs(s, tn->tn_strg->st_wcp, n); | |
3466 | (void)printf("L\"%s\"", s); | 3467 | (void)printf("L\"%s\"", s); | |
3467 | free(s); | 3468 | free(s); | |
3468 | } | 3469 | } | |
3469 | (void)printf(" "); | 3470 | (void)printf(" "); | |
3470 | } else if (tn->tn_op == FSEL) { | 3471 | } else if (tn->tn_op == FSEL) { | |
3471 | (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, | 3472 | (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, | |
3472 | tn->tn_type->t_flen); | 3473 | tn->tn_type->t_flen); | |
3473 | } | 3474 | } | |
3474 | (void)printf("%s\n", ttos(tn->tn_type)); | 3475 | (void)printf("%s\n", ttos(tn->tn_type)); | |
3475 | if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) | 3476 | if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) | |
3476 | return; | 3477 | return; | |
3477 | displexpr(tn->tn_left, offs + 2); | 3478 | displexpr(tn->tn_left, offs + 2); | |
3478 | if (modtab[tn->tn_op].m_binary || | 3479 | if (modtab[tn->tn_op].m_binary || | |
3479 | (tn->tn_op == PUSH && tn->tn_right != NULL)) { | 3480 | (tn->tn_op == PUSH && tn->tn_right != NULL)) { | |
3480 | displexpr(tn->tn_right, offs + 2); | 3481 | displexpr(tn->tn_right, offs + 2); | |
3481 | } | 3482 | } | |
3482 | } | 3483 | } | |
3483 | 3484 | |||
3484 | /* | 3485 | /* | |
3485 | * Called by expr() to recursively perform some tests. | 3486 | * Called by expr() to recursively perform some tests. | |
3486 | */ | 3487 | */ | |
3487 | /* ARGSUSED */ | 3488 | /* ARGSUSED */ | |
3488 | void | 3489 | void | |
3489 | chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, | 3490 | chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, | |
3490 | int szof) | 3491 | int szof) | |
3491 | { | 3492 | { | |
3492 | tnode_t *ln, *rn; | 3493 | tnode_t *ln, *rn; | |
3493 | mod_t *mp; | 3494 | mod_t *mp; | |
3494 | int nrvdisc, cvctx, ctctx; | 3495 | int nrvdisc, cvctx, ctctx; | |
3495 | op_t op; | 3496 | op_t op; | |
3496 | scl_t sc; | 3497 | scl_t sc; | |
3497 | dinfo_t *di; | 3498 | dinfo_t *di; | |
3498 | 3499 | |||
3499 | if (tn == NULL) | 3500 | if (tn == NULL) | |
3500 | return; | 3501 | return; | |
3501 | 3502 | |||
3502 | ln = tn->tn_left; | 3503 | ln = tn->tn_left; | |
3503 | rn = tn->tn_right; | 3504 | rn = tn->tn_right; | |
3504 | mp = &modtab[op = tn->tn_op]; | 3505 | mp = &modtab[op = tn->tn_op]; | |
3505 | 3506 | |||
3506 | switch (op) { | 3507 | switch (op) { | |
3507 | case AMPER: | 3508 | case AMPER: | |
3508 | if (ln->tn_op == NAME && (reached || rchflg)) { | 3509 | if (ln->tn_op == NAME && (reached || rchflg)) { | |
3509 | if (!szof) | 3510 | if (!szof) | |
3510 | setsflg(ln->tn_sym); | 3511 | setsflg(ln->tn_sym); | |
3511 | setuflg(ln->tn_sym, fcall, szof); | 3512 | setuflg(ln->tn_sym, fcall, szof); | |
3512 | } | 3513 | } | |
3513 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | 3514 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | |
3514 | /* check the range of array indices */ | 3515 | /* check the range of array indices */ | |
3515 | chkaidx(ln->tn_left, 1); | 3516 | chkaidx(ln->tn_left, 1); | |
3516 | break; | 3517 | break; | |
3517 | case LOAD: | 3518 | case LOAD: | |
3518 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | 3519 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | |
3519 | /* check the range of array indices */ | 3520 | /* check the range of array indices */ | |
3520 | chkaidx(ln->tn_left, 0); | 3521 | chkaidx(ln->tn_left, 0); | |
3521 | /* FALLTHROUGH */ | 3522 | /* FALLTHROUGH */ | |
3522 | case PUSH: | 3523 | case PUSH: | |
3523 | case INCBEF: | 3524 | case INCBEF: | |
3524 | case DECBEF: | 3525 | case DECBEF: | |
3525 | case INCAFT: | 3526 | case INCAFT: | |
3526 | case DECAFT: | 3527 | case DECAFT: | |
3527 | case ADDASS: | 3528 | case ADDASS: | |
3528 | case SUBASS: | 3529 | case SUBASS: | |
3529 | case MULASS: | 3530 | case MULASS: | |
3530 | case DIVASS: | 3531 | case DIVASS: | |
3531 | case MODASS: | 3532 | case MODASS: | |
3532 | case ANDASS: | 3533 | case ANDASS: | |
3533 | case ORASS: | 3534 | case ORASS: | |
3534 | case XORASS: | 3535 | case XORASS: | |
3535 | case SHLASS: | 3536 | case SHLASS: | |
3536 | case SHRASS: | 3537 | case SHRASS: | |
3537 | case REAL: | 3538 | case REAL: | |
3538 | case IMAG: | 3539 | case IMAG: | |
3539 | if (ln->tn_op == NAME && (reached || rchflg)) { | 3540 | if (ln->tn_op == NAME && (reached || rchflg)) { | |
3540 | sc = ln->tn_sym->s_scl; | 3541 | sc = ln->tn_sym->s_scl; | |
3541 | /* | 3542 | /* | |
3542 | * Look if there was a asm statement in one of the | 3543 | * Look if there was a asm statement in one of the | |
3543 | * compound statements we are in. If not, we don't | 3544 | * compound statements we are in. If not, we don't | |
3544 | * print a warning. | 3545 | * print a warning. | |
3545 | */ | 3546 | */ | |
3546 | for (di = dcs; di != NULL; di = di->d_nxt) { | 3547 | for (di = dcs; di != NULL; di = di->d_nxt) { | |
3547 | if (di->d_asm) | 3548 | if (di->d_asm) | |
3548 | break; | 3549 | break; | |
3549 | } | 3550 | } | |
3550 | if (sc != EXTERN && sc != STATIC && | 3551 | if (sc != EXTERN && sc != STATIC && | |
3551 | !ln->tn_sym->s_set && !szof && di == NULL) { | 3552 | !ln->tn_sym->s_set && !szof && di == NULL) { | |
3552 | /* %s may be used before set */ | 3553 | /* %s may be used before set */ | |
3553 | warning(158, ln->tn_sym->s_name); | 3554 | warning(158, ln->tn_sym->s_name); | |
3554 | setsflg(ln->tn_sym); | 3555 | setsflg(ln->tn_sym); | |
3555 | } | 3556 | } | |
3556 | setuflg(ln->tn_sym, 0, 0); | 3557 | setuflg(ln->tn_sym, 0, 0); | |
3557 | } | 3558 | } | |
3558 | break; | 3559 | break; | |
3559 | case ASSIGN: | 3560 | case ASSIGN: | |
3560 | if (ln->tn_op == NAME && !szof && (reached || rchflg)) { | 3561 | if (ln->tn_op == NAME && !szof && (reached || rchflg)) { | |
3561 | setsflg(ln->tn_sym); | 3562 | setsflg(ln->tn_sym); | |
3562 | if (ln->tn_sym->s_scl == EXTERN) | 3563 | if (ln->tn_sym->s_scl == EXTERN) | |
3563 | outusg(ln->tn_sym); | 3564 | outusg(ln->tn_sym); | |
3564 | } | 3565 | } | |
3565 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | 3566 | if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) | |
3566 | /* check the range of array indices */ | 3567 | /* check the range of array indices */ | |
3567 | chkaidx(ln->tn_left, 0); | 3568 | chkaidx(ln->tn_left, 0); | |
3568 | break; | 3569 | break; | |
3569 | case CALL: | 3570 | case CALL: | |
3570 | if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) | 3571 | if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) | |
3571 | LERROR("chkmisc()"); | 3572 | LERROR("chkmisc()"); | |
3572 | if (!szof) | 3573 | if (!szof) | |
3573 | outcall(tn, vctx || tctx, rvdisc); | 3574 | outcall(tn, vctx || tctx, rvdisc); | |
3574 | break; | 3575 | break; | |
3575 | case EQ: | 3576 | case EQ: | |
3576 | /* equality operator "==" found where "=" was exp. */ | 3577 | /* equality operator "==" found where "=" was exp. */ | |
3577 | if (hflag && eqwarn) | 3578 | if (hflag && eqwarn) | |
3578 | warning(160); | 3579 | warning(160); | |
3579 | break; | 3580 | break; | |
3580 | case CON: | 3581 | case CON: | |
3581 | case NAME: | 3582 | case NAME: | |
3582 | case STRING: | 3583 | case STRING: | |
3583 | return; | 3584 | return; | |
3584 | /* LINTED206: (enumeration values not handled in switch) */ | 3585 | /* LINTED206: (enumeration values not handled in switch) */ | |
3585 | case OR: | 3586 | case OR: | |
3586 | case XOR: | 3587 | case XOR: | |
3587 | case NE: | 3588 | case NE: | |
3588 | case GE: | 3589 | case GE: | |
3589 | case GT: | 3590 | case GT: | |
3590 | case LE: | 3591 | case LE: | |
3591 | case LT: | 3592 | case LT: | |
3592 | case SHR: | 3593 | case SHR: | |
3593 | case SHL: | 3594 | case SHL: | |
3594 | case MINUS: | 3595 | case MINUS: | |
3595 | case PLUS: | 3596 | case PLUS: | |
3596 | case MOD: | 3597 | case MOD: | |
3597 | case DIV: | 3598 | case DIV: | |
3598 | case MULT: | 3599 | case MULT: | |
3599 | case STAR: | 3600 | case STAR: | |
3600 | case UMINUS: | 3601 | case UMINUS: | |
3601 | case UPLUS: | 3602 | case UPLUS: | |
3602 | case DEC: | 3603 | case DEC: | |
3603 | case INC: | 3604 | case INC: | |
3604 | case COMPL: | 3605 | case COMPL: | |
3605 | case NOT: | 3606 | case NOT: | |
3606 | case POINT: | 3607 | case POINT: | |
3607 | case ARROW: | 3608 | case ARROW: | |
3608 | case NOOP: | 3609 | case NOOP: | |
3609 | case AND: | 3610 | case AND: | |
3610 | case FARG: | 3611 | case FARG: | |
3611 | case CASE: | 3612 | case CASE: | |
3612 | case INIT: | 3613 | case INIT: | |
3613 | case RETURN: | 3614 | case RETURN: | |
3614 | case ICALL: | 3615 | case ICALL: | |
3615 | case CVT: | 3616 | case CVT: | |
3616 | case COMMA: | 3617 | case COMMA: | |
3617 | case FSEL: | 3618 | case FSEL: | |
3618 | case COLON: | 3619 | case COLON: | |
3619 | case QUEST: | 3620 | case QUEST: | |
3620 | case LOGOR: | 3621 | case LOGOR: | |
3621 | case LOGAND: | 3622 | case LOGAND: | |
3622 | break; | 3623 | break; | |
3623 | } | 3624 | } | |
3624 | 3625 | |||
3625 | cvctx = mp->m_vctx; | 3626 | cvctx = mp->m_vctx; | |
3626 | ctctx = mp->m_tctx; | 3627 | ctctx = mp->m_tctx; | |
3627 | /* | 3628 | /* | |
3628 | * values of operands of ':' are not used if the type of at least | 3629 | * values of operands of ':' are not used if the type of at least | |
3629 | * one of the operands (for gcc compatibility) is void | 3630 | * one of the operands (for gcc compatibility) is void | |
3630 | * XXX test/value context of QUEST should probably be used as | 3631 | * XXX test/value context of QUEST should probably be used as | |
3631 | * context for both operands of COLON | 3632 | * context for both operands of COLON | |
3632 | */ | 3633 | */ | |
3633 | if (op == COLON && tn->tn_type->t_tspec == VOID) | 3634 | if (op == COLON && tn->tn_type->t_tspec == VOID) | |
3634 | cvctx = ctctx = 0; | 3635 | cvctx = ctctx = 0; | |
3635 | nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; | 3636 | nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; | |
3636 | chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); | 3637 | chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); | |
3637 | 3638 | |||
3638 | switch (op) { | 3639 | switch (op) { | |
3639 | case PUSH: | 3640 | case PUSH: | |
3640 | if (rn != NULL) | 3641 | if (rn != NULL) | |
3641 | chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); | 3642 | chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); | |
3642 | break; | 3643 | break; | |
3643 | case LOGAND: | 3644 | case LOGAND: | |
3644 | case LOGOR: | 3645 | case LOGOR: | |
3645 | chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); | 3646 | chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); | |
3646 | break; | 3647 | break; | |
3647 | case COLON: | 3648 | case COLON: | |
3648 | chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); | 3649 | chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); | |
3649 | break; | 3650 | break; | |
3650 | case COMMA: | 3651 | case COMMA: | |
3651 | chkmisc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); | 3652 | chkmisc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); | |
3652 | break; | 3653 | break; | |
3653 | default: | 3654 | default: | |
3654 | if (mp->m_binary) | 3655 | if (mp->m_binary) | |
3655 | chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); | 3656 | chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); | |
3656 | break; | 3657 | break; | |
3657 | } | 3658 | } | |
3658 | 3659 | |||
3659 | } | 3660 | } | |
3660 | 3661 | |||
3661 | /* | 3662 | /* | |
3662 | * Checks the range of array indices, if possible. | 3663 | * Checks the range of array indices, if possible. | |
3663 | * amper is set if only the address of the element is used. This | 3664 | * amper is set if only the address of the element is used. This | |
3664 | * means that the index is allowd to refere to the first element | 3665 | * means that the index is allowd to refere to the first element | |
3665 | * after the array. | 3666 | * after the array. | |
3666 | */ | 3667 | */ | |
3667 | static void | 3668 | static void | |
3668 | chkaidx(tnode_t *tn, int amper) | 3669 | chkaidx(tnode_t *tn, int amper) | |
3669 | { | 3670 | { | |
3670 | int dim; | 3671 | int dim; | |
3671 | tnode_t *ln, *rn; | 3672 | tnode_t *ln, *rn; | |
3672 | int elsz; | 3673 | int elsz; | |
3673 | int64_t con; | 3674 | int64_t con; | |
3674 | 3675 | |||
3675 | ln = tn->tn_left; | 3676 | ln = tn->tn_left; | |
3676 | rn = tn->tn_right; | 3677 | rn = tn->tn_right; | |
3677 | 3678 | |||
3678 | /* We can only check constant indices. */ | 3679 | /* We can only check constant indices. */ | |
3679 | if (rn->tn_op != CON) | 3680 | if (rn->tn_op != CON) | |
3680 | return; | 3681 | return; | |
3681 | 3682 | |||
3682 | /* Return if the left node does not stem from an array. */ | 3683 | /* Return if the left node does not stem from an array. */ | |
3683 | if (ln->tn_op != AMPER) | 3684 | if (ln->tn_op != AMPER) | |
3684 | return; | 3685 | return; | |
3685 | if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) | 3686 | if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) | |
3686 | return; | 3687 | return; | |
3687 | if (ln->tn_left->tn_type->t_tspec != ARRAY) | 3688 | if (ln->tn_left->tn_type->t_tspec != ARRAY) | |
3688 | return; | 3689 | return; | |
3689 | 3690 | |||
3690 | /* | 3691 | /* | |
3691 | * For incomplete array types, we can print a warning only if | 3692 | * For incomplete array types, we can print a warning only if | |
3692 | * the index is negative. | 3693 | * the index is negative. | |
3693 | */ | 3694 | */ | |
3694 | if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) | 3695 | if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) | |
3695 | return; | 3696 | return; | |
3696 | 3697 | |||
3697 | /* Get the size of one array element */ | 3698 | /* Get the size of one array element */ | |
3698 | if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) | 3699 | if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) | |
3699 | return; | 3700 | return; | |
3700 | elsz /= CHAR_BIT; | 3701 | elsz /= CHAR_BIT; | |
3701 | 3702 | |||
3702 | /* Change the unit of the index from bytes to element size. */ | 3703 | /* Change the unit of the index from bytes to element size. */ | |
3703 | if (isutyp(rn->tn_type->t_tspec)) { | 3704 | if (isutyp(rn->tn_type->t_tspec)) { | |
3704 | con = (uint64_t)rn->tn_val->v_quad / elsz; | 3705 | con = (uint64_t)rn->tn_val->v_quad / elsz; | |
3705 | } else { | 3706 | } else { | |
3706 | con = rn->tn_val->v_quad / elsz; | 3707 | con = rn->tn_val->v_quad / elsz; | |
3707 | } | 3708 | } | |
3708 | 3709 | |||
3709 | dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); | 3710 | dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); | |
3710 | 3711 | |||
3711 | if (!isutyp(rn->tn_type->t_tspec) && con < 0) { | 3712 | if (!isutyp(rn->tn_type->t_tspec) && con < 0) { | |
3712 | /* array subscript cannot be negative: %ld */ | 3713 | /* array subscript cannot be negative: %ld */ | |
3713 | warning(167, (long)con); | 3714 | warning(167, (long)con); | |
3714 | } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { | 3715 | } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { | |
3715 | /* array subscript cannot be > %d: %ld */ | 3716 | /* array subscript cannot be > %d: %ld */ | |
3716 | warning(168, dim - 1, (long)con); | 3717 | warning(168, dim - 1, (long)con); | |
3717 | } | 3718 | } | |
3718 | } | 3719 | } | |
3719 | 3720 | |||
3720 | /* | 3721 | /* | |
3721 | * Check for ordered comparisons of unsigned values with 0. | 3722 | * Check for ordered comparisons of unsigned values with 0. | |
3722 | */ | 3723 | */ | |
3723 | static void | 3724 | static void | |
3724 | chkcomp(op_t op, tnode_t *ln, tnode_t *rn) | 3725 | chkcomp(op_t op, tnode_t *ln, tnode_t *rn) | |
3725 | { | 3726 | { | |
3726 | char buf[64]; | 3727 | char buf[64]; | |
3727 | tspec_t lt, rt; | 3728 | tspec_t lt, rt; | |
3728 | mod_t *mp; | 3729 | mod_t *mp; | |
3729 | 3730 | |||
3730 | lt = ln->tn_type->t_tspec; | 3731 | lt = ln->tn_type->t_tspec; | |
3731 | rt = rn->tn_type->t_tspec; | 3732 | rt = rn->tn_type->t_tspec; | |
3732 | mp = &modtab[op]; | 3733 | mp = &modtab[op]; | |
3733 | 3734 | |||
3734 | if (ln->tn_op != CON && rn->tn_op != CON) | 3735 | if (ln->tn_op != CON && rn->tn_op != CON) | |
3735 | return; | 3736 | return; | |
3736 | 3737 | |||
3737 | if (!isityp(lt) || !isityp(rt)) | 3738 | if (!isityp(lt) || !isityp(rt)) | |
3738 | return; | 3739 | return; | |
3739 | 3740 | |||
3740 | if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && | 3741 | if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && | |
3741 | (rn->tn_val->v_quad < 0 || | 3742 | (rn->tn_val->v_quad < 0 || | |
3742 | rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { | 3743 | rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { | |
3743 | /* nonportable character comparison, op %s */ | 3744 | /* nonportable character comparison, op %s */ | |
3744 | warning(230, mp->m_name); | 3745 | warning(230, mp->m_name); | |
3745 | return; | 3746 | return; | |
3746 | } | 3747 | } | |
3747 | if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && | 3748 | if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && | |
3748 | (ln->tn_val->v_quad < 0 || | 3749 | (ln->tn_val->v_quad < 0 || | |
3749 | ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { | 3750 | ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { | |
3750 | /* nonportable character comparison, op %s */ | 3751 | /* nonportable character comparison, op %s */ | |
3751 | warning(230, mp->m_name); | 3752 | warning(230, mp->m_name); | |
3752 | return; | 3753 | return; | |
3753 | } | 3754 | } | |
3754 | if (isutyp(lt) && !isutyp(rt) && | 3755 | if (isutyp(lt) && !isutyp(rt) && | |
3755 | rn->tn_op == CON && rn->tn_val->v_quad <= 0) { | 3756 | rn->tn_op == CON && rn->tn_val->v_quad <= 0) { | |
3756 | if (rn->tn_val->v_quad < 0) { | 3757 | if (rn->tn_val->v_quad < 0) { | |
3757 | /* comparison of %s with %s, op %s */ | 3758 | /* comparison of %s with %s, op %s */ | |
3758 | warning(162, tyname(buf, sizeof(buf), ln->tn_type), | 3759 | warning(162, tyname(buf, sizeof(buf), ln->tn_type), | |
3759 | "negative constant", mp->m_name); | 3760 | "negative constant", mp->m_name); | |
3760 | } else if (op == LT || op == GE || (hflag && op == LE)) { | 3761 | } else if (op == LT || op == GE || (hflag && op == LE)) { | |
3761 | /* comparison of %s with %s, op %s */ | 3762 | /* comparison of %s with %s, op %s */ | |
3762 | warning(162, tyname(buf, sizeof(buf), ln->tn_type), | 3763 | warning(162, tyname(buf, sizeof(buf), ln->tn_type), | |
3763 | "0", mp->m_name); | 3764 | "0", mp->m_name); | |
3764 | } | 3765 | } | |
3765 | return; | 3766 | return; | |
3766 | } | 3767 | } | |
3767 | if (isutyp(rt) && !isutyp(lt) && | 3768 | if (isutyp(rt) && !isutyp(lt) && | |
3768 | ln->tn_op == CON && ln->tn_val->v_quad <= 0) { | 3769 | ln->tn_op == CON && ln->tn_val->v_quad <= 0) { | |
3769 | if (ln->tn_val->v_quad < 0) { | 3770 | if (ln->tn_val->v_quad < 0) { | |
3770 | /* comparison of %s with %s, op %s */ | 3771 | /* comparison of %s with %s, op %s */ | |
3771 | warning(162, "negative constant", | 3772 | warning(162, "negative constant", | |
3772 | tyname(buf, sizeof(buf), rn->tn_type), mp->m_name); | 3773 | tyname(buf, sizeof(buf), rn->tn_type), mp->m_name); | |
3773 | } else if (op == GT || op == LE || (hflag && op == GE)) { | 3774 | } else if (op == GT || op == LE || (hflag && op == GE)) { | |
3774 | /* comparison of %s with %s, op %s */ | 3775 | /* comparison of %s with %s, op %s */ | |
3775 | warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type), | 3776 | warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type), | |
3776 | mp->m_name); | 3777 | mp->m_name); | |
3777 | } | 3778 | } | |
3778 | return; | 3779 | return; | |
3779 | } | 3780 | } | |
3780 | } | 3781 | } | |
3781 | 3782 | |||
3782 | /* | 3783 | /* | |
3783 | * Takes an expression an returns 0 if this expression can be used | 3784 | * Takes an expression an returns 0 if this expression can be used | |
3784 | * for static initialisation, otherwise -1. | 3785 | * for static initialisation, otherwise -1. | |
3785 | * | 3786 | * | |
3786 | * Constant initialisation expressions must be constant or an address | 3787 | * Constant initialisation expressions must be constant or an address | |
3787 | * of a static object with an optional offset. In the first case, | 3788 | * of a static object with an optional offset. In the first case, | |
3788 | * the result is returned in *offsp. In the second case, the static | 3789 | * the result is returned in *offsp. In the second case, the static | |
3789 | * object is returned in *symp and the offset in *offsp. | 3790 | * object is returned in *symp and the offset in *offsp. | |
3790 | * | 3791 | * | |
3791 | * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and | 3792 | * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and | |
3792 | * CON. Type conversions are allowed if they do not change binary | 3793 | * CON. Type conversions are allowed if they do not change binary | |
3793 | * representation (including width). | 3794 | * representation (including width). | |
3794 | */ | 3795 | */ | |
3795 | int | 3796 | int | |
3796 | conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) | 3797 | conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) | |
3797 | { | 3798 | { | |
3798 | sym_t *sym; | 3799 | sym_t *sym; | |
3799 | ptrdiff_t offs1, offs2; | 3800 | ptrdiff_t offs1, offs2; | |
3800 | tspec_t t, ot; | 3801 | tspec_t t, ot; | |
3801 | 3802 | |||
3802 | switch (tn->tn_op) { | 3803 | switch (tn->tn_op) { | |
3803 | case MINUS: | 3804 | case MINUS: | |
3804 | if (tn->tn_right->tn_op == CVT) | 3805 | if (tn->tn_right->tn_op == CVT) | |
3805 | return conaddr(tn->tn_right, symp, offsp); | 3806 | return conaddr(tn->tn_right, symp, offsp); | |
3806 | else if (tn->tn_right->tn_op != CON) | 3807 | else if (tn->tn_right->tn_op != CON) | |
3807 | return (-1); | 3808 | return (-1); | |
3808 | /* FALLTHROUGH */ | 3809 | /* FALLTHROUGH */ | |
3809 | case PLUS: | 3810 | case PLUS: | |
3810 | offs1 = offs2 = 0; | 3811 | offs1 = offs2 = 0; | |
3811 | if (tn->tn_left->tn_op == CON) { | 3812 | if (tn->tn_left->tn_op == CON) { | |
3812 | offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; | 3813 | offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; | |
3813 | if (conaddr(tn->tn_right, &sym, &offs2) == -1) | 3814 | if (conaddr(tn->tn_right, &sym, &offs2) == -1) | |
3814 | return (-1); | 3815 | return (-1); | |
3815 | } else if (tn->tn_right->tn_op == CON) { | 3816 | } else if (tn->tn_right->tn_op == CON) { | |
3816 | offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; | 3817 | offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; | |
3817 | if (tn->tn_op == MINUS) | 3818 | if (tn->tn_op == MINUS) | |
3818 | offs2 = -offs2; | 3819 | offs2 = -offs2; | |
3819 | if (conaddr(tn->tn_left, &sym, &offs1) == -1) | 3820 | if (conaddr(tn->tn_left, &sym, &offs1) == -1) | |
3820 | return (-1); | 3821 | return (-1); | |
3821 | } else { | 3822 | } else { | |
3822 | return (-1); | 3823 | return (-1); | |
3823 | } | 3824 | } | |
3824 | *symp = sym; | 3825 | *symp = sym; | |
3825 | *offsp = offs1 + offs2; | 3826 | *offsp = offs1 + offs2; | |
3826 | break; | 3827 | break; | |
3827 | case AMPER: | 3828 | case AMPER: | |
3828 | if (tn->tn_left->tn_op == NAME) { | 3829 | if (tn->tn_left->tn_op == NAME) { | |
3829 | *symp = tn->tn_left->tn_sym; | 3830 | *symp = tn->tn_left->tn_sym; | |
3830 | *offsp = 0; | 3831 | *offsp = 0; | |
3831 | } else if (tn->tn_left->tn_op == STRING) { | 3832 | } else if (tn->tn_left->tn_op == STRING) { | |
3832 | /* | 3833 | /* | |
3833 | * If this would be the front end of a compiler we | 3834 | * If this would be the front end of a compiler we | |
3834 | * would return a label instead of 0. | 3835 | * would return a label instead of 0. | |
3835 | */ | 3836 | */ | |
3836 | *offsp = 0; | 3837 | *offsp = 0; | |
3837 | } | 3838 | } | |
3838 | break; | 3839 | break; | |
3839 | case CVT: | 3840 | case CVT: | |
3840 | t = tn->tn_type->t_tspec; | 3841 | t = tn->tn_type->t_tspec; | |
3841 | ot = tn->tn_left->tn_type->t_tspec; | 3842 | ot = tn->tn_left->tn_type->t_tspec; | |
3842 | if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) | 3843 | if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) | |
3843 | return (-1); | 3844 | return (-1); | |
3844 | #ifdef notdef | 3845 | #ifdef notdef | |
3845 | /* | 3846 | /* | |
3846 | * consider: | 3847 | * consider: | |
3847 | * struct foo { | 3848 | * struct foo { | |
3848 | * unsigned char a; | 3849 | * unsigned char a; | |
3849 | * } f = { | 3850 | * } f = { | |
3850 | * (u_char)(u_long)(&(((struct foo *)0)->a)) | 3851 | * (u_char)(u_long)(&(((struct foo *)0)->a)) | |
3851 | * }; | 3852 | * }; | |
3852 | * since psize(u_long) != psize(u_char) this fails. | 3853 | * since psize(u_long) != psize(u_char) this fails. | |
3853 | */ | 3854 | */ | |
3854 | else if (psize(t) != psize(ot)) | 3855 | else if (psize(t) != psize(ot)) | |
3855 | return (-1); | 3856 | return (-1); | |
3856 | #endif | 3857 | #endif | |
3857 | if (conaddr(tn->tn_left, symp, offsp) == -1) | 3858 | if (conaddr(tn->tn_left, symp, offsp) == -1) | |
3858 | return (-1); | 3859 | return (-1); | |
3859 | break; | 3860 | break; | |
3860 | default: | 3861 | default: | |
3861 | return (-1); | 3862 | return (-1); | |
3862 | } | 3863 | } | |
3863 | return (0); | 3864 | return (0); | |
3864 | } | 3865 | } | |
3865 | 3866 | |||
3866 | /* | 3867 | /* | |
3867 | * Concatenate two string constants. | 3868 | * Concatenate two string constants. | |
3868 | */ | 3869 | */ | |
3869 | strg_t * | 3870 | strg_t * | |
3870 | catstrg(strg_t *strg1, strg_t *strg2) | 3871 | catstrg(strg_t *strg1, strg_t *strg2) | |
3871 | { | 3872 | { | |
3872 | size_t len1, len2, len; | 3873 | size_t len1, len2, len; | |
3873 | 3874 | |||
3874 | if (strg1->st_tspec != strg2->st_tspec) { | 3875 | if (strg1->st_tspec != strg2->st_tspec) { | |
3875 | /* cannot concatenate wide and regular string literals */ | 3876 | /* cannot concatenate wide and regular string literals */ | |
3876 | error(292); | 3877 | error(292); | |
3877 | return (strg1); | 3878 | return (strg1); | |
3878 | } | 3879 | } | |
3879 | 3880 | |||
3880 | len1 = strg1->st_len; | 3881 | len1 = strg1->st_len; | |
3881 | len2 = strg2->st_len + 1; /* + NUL */ | 3882 | len2 = strg2->st_len + 1; /* + NUL */ | |
3882 | len = len1 + len2; | 3883 | len = len1 + len2; | |
3883 | 3884 | |||
3884 | #define COPY(F) \ | 3885 | #define COPY(F) \ | |
3885 | do { \ | 3886 | do { \ | |
3886 | strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \ | 3887 | strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \ | |
3887 | (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \ | 3888 | (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \ | |
3888 | free(strg2->F); \ | 3889 | free(strg2->F); \ | |
3889 | } while (/*CONSTCOND*/0) | 3890 | } while (/*CONSTCOND*/0) | |
3890 | 3891 | |||
3891 | if (strg1->st_tspec == CHAR) | 3892 | if (strg1->st_tspec == CHAR) | |
3892 | COPY(st_cp); | 3893 | COPY(st_cp); | |
3893 | else | 3894 | else | |
3894 | COPY(st_wcp); | 3895 | COPY(st_wcp); | |
3895 | 3896 | |||
3896 | strg1->st_len = len - 1; /* - NUL */; | 3897 | strg1->st_len = len - 1; /* - NUL */; | |
3897 | free(strg2); | 3898 | free(strg2); | |
3898 | 3899 | |||
3899 | return (strg1); | 3900 | return (strg1); | |
3900 | } | 3901 | } | |
3901 | 3902 | |||
3902 | /* | 3903 | /* | |
3903 | * Print a warning if the given node has operands which should be | 3904 | * Print a warning if the given node has operands which should be | |
3904 | * parenthesized. | 3905 | * parenthesized. | |
3905 | * | 3906 | * | |
3906 | * XXX Does not work if an operand is a constant expression. Constant | 3907 | * XXX Does not work if an operand is a constant expression. Constant | |
3907 | * expressions are already folded. | 3908 | * expressions are already folded. | |
3908 | */ | 3909 | */ | |
3909 | static void | 3910 | static void | |
3910 | precconf(tnode_t *tn) | 3911 | precconf(tnode_t *tn) | |
3911 | { | 3912 | { | |
3912 | tnode_t *ln, *rn; | 3913 | tnode_t *ln, *rn; | |
3913 | op_t lop, rop = NOOP; | 3914 | op_t lop, rop = NOOP; | |
3914 | int lparn, rparn = 0; | 3915 | int lparn, rparn = 0; | |
3915 | mod_t *mp; | 3916 | mod_t *mp; | |
3916 | int dowarn; | 3917 | int dowarn; | |
3917 | 3918 | |||
3918 | if (!hflag) | 3919 | if (!hflag) | |
3919 | return; | 3920 | return; | |
3920 | 3921 | |||
3921 | mp = &modtab[tn->tn_op]; | 3922 | mp = &modtab[tn->tn_op]; | |
3922 | 3923 | |||
3923 | lparn = 0; | 3924 | lparn = 0; | |
3924 | for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) | 3925 | for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) | |
3925 | lparn |= ln->tn_parn; | 3926 | lparn |= ln->tn_parn; | |
3926 | lparn |= ln->tn_parn; | 3927 | lparn |= ln->tn_parn; | |
3927 | lop = ln->tn_op; | 3928 | lop = ln->tn_op; | |
3928 | 3929 | |||
3929 | if (mp->m_binary) { | 3930 | if (mp->m_binary) { | |
3930 | rparn = 0; | 3931 | rparn = 0; | |
3931 | for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) | 3932 | for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) | |
3932 | rparn |= rn->tn_parn; | 3933 | rparn |= rn->tn_parn; | |
3933 | rparn |= rn->tn_parn; | 3934 | rparn |= rn->tn_parn; | |
3934 | rop = rn->tn_op; | 3935 | rop = rn->tn_op; | |
3935 | } | 3936 | } | |
3936 | 3937 | |||
3937 | dowarn = 0; | 3938 | dowarn = 0; | |
3938 | 3939 | |||
3939 | switch (tn->tn_op) { | 3940 | switch (tn->tn_op) { | |
3940 | case SHL: | 3941 | case SHL: | |
3941 | case SHR: | 3942 | case SHR: | |
3942 | if (!lparn && (lop == PLUS || lop == MINUS)) { | 3943 | if (!lparn && (lop == PLUS || lop == MINUS)) { | |
3943 | dowarn = 1; | 3944 | dowarn = 1; | |
3944 | } else if (!rparn && (rop == PLUS || rop == MINUS)) { | 3945 | } else if (!rparn && (rop == PLUS || rop == MINUS)) { | |
3945 | dowarn = 1; | 3946 | dowarn = 1; | |
3946 | } | 3947 | } | |
3947 | break; | 3948 | break; | |
3948 | case LOGOR: | 3949 | case LOGOR: | |
3949 | if (!lparn && lop == LOGAND) { | 3950 | if (!lparn && lop == LOGAND) { | |
3950 | dowarn = 1; | 3951 | dowarn = 1; | |
3951 | } else if (!rparn && rop == LOGAND) { | 3952 | } else if (!rparn && rop == LOGAND) { | |
3952 | dowarn = 1; | 3953 | dowarn = 1; | |
3953 | } | 3954 | } | |
3954 | break; | 3955 | break; | |
3955 | case AND: | 3956 | case AND: | |
3956 | case XOR: | 3957 | case XOR: | |
3957 | case OR: | 3958 | case OR: | |
3958 | if (!lparn && lop != tn->tn_op) { | 3959 | if (!lparn && lop != tn->tn_op) { | |
3959 | if (lop == PLUS || lop == MINUS) { | 3960 | if (lop == PLUS || lop == MINUS) { | |
3960 | dowarn = 1; | 3961 | dowarn = 1; | |
3961 | } else if (lop == AND || lop == XOR) { | 3962 | } else if (lop == AND || lop == XOR) { | |
3962 | dowarn = 1; | 3963 | dowarn = 1; | |
3963 | } | 3964 | } | |
3964 | } | 3965 | } | |
3965 | if (!dowarn && !rparn && rop != tn->tn_op) { | 3966 | if (!dowarn && !rparn && rop != tn->tn_op) { | |
3966 | if (rop == PLUS || rop == MINUS) { | 3967 | if (rop == PLUS || rop == MINUS) { | |
3967 | dowarn = 1; | 3968 | dowarn = 1; | |
3968 | } else if (rop == AND || rop == XOR) { | 3969 | } else if (rop == AND || rop == XOR) { | |
3969 | dowarn = 1; | 3970 | dowarn = 1; | |
3970 | } | 3971 | } | |
3971 | } | 3972 | } | |
3972 | break; | 3973 | break; | |
3973 | /* LINTED206: (enumeration values not handled in switch) */ | 3974 | /* LINTED206: (enumeration values not handled in switch) */ | |
3974 | case DECAFT: | 3975 | case DECAFT: | |
3975 | case XORASS: | 3976 | case XORASS: | |
3976 | case SHLASS: | 3977 | case SHLASS: | |
3977 | case NOOP: | 3978 | case NOOP: | |
3978 | case ARROW: | 3979 | case ARROW: | |
3979 | case ORASS: | 3980 | case ORASS: | |
3980 | case POINT: | 3981 | case POINT: | |
3981 | case NAME: | 3982 | case NAME: | |
3982 | case NOT: | 3983 | case NOT: | |
3983 | case COMPL: | 3984 | case COMPL: | |
3984 | case CON: | 3985 | case CON: | |
3985 | case INC: | 3986 | case INC: | |
3986 | case STRING: | 3987 | case STRING: | |
3987 | case DEC: | 3988 | case DEC: | |
3988 | case INCBEF: | 3989 | case INCBEF: | |
3989 | case DECBEF: | 3990 | case DECBEF: | |
3990 | case INCAFT: | 3991 | case INCAFT: | |
3991 | case FSEL: | 3992 | case FSEL: | |
3992 | case CALL: | 3993 | case CALL: | |
3993 | case COMMA: | 3994 | case COMMA: | |
3994 | case CVT: | 3995 | case CVT: | |
3995 | case ICALL: | 3996 | case ICALL: | |
3996 | case LOAD: | 3997 | case LOAD: | |
3997 | case PUSH: | 3998 | case PUSH: | |
3998 | case RETURN: | 3999 | case RETURN: | |
3999 | case INIT: | 4000 | case INIT: | |
4000 | case CASE: | 4001 | case CASE: | |
4001 | case FARG: | 4002 | case FARG: | |
4002 | case SUBASS: | 4003 | case SUBASS: | |
4003 | case ADDASS: | 4004 | case ADDASS: | |
4004 | case MODASS: | 4005 | case MODASS: | |
4005 | case DIVASS: | 4006 | case DIVASS: | |
4006 | case MULASS: | 4007 | case MULASS: | |
4007 | case ASSIGN: | 4008 | case ASSIGN: | |
4008 | case COLON: | 4009 | case COLON: | |
4009 | case QUEST: | 4010 | case QUEST: | |
4010 | case LOGAND: | 4011 | case LOGAND: | |
4011 | case NE: | 4012 | case NE: | |
4012 | case EQ: | 4013 | case EQ: | |
4013 | case GE: | 4014 | case GE: | |
4014 | case GT: | 4015 | case GT: | |
4015 | case LE: | 4016 | case LE: | |
4016 | case LT: | 4017 | case LT: | |
4017 | case MINUS: | 4018 | case MINUS: | |
4018 | case PLUS: | 4019 | case PLUS: | |
4019 | case MOD: | 4020 | case MOD: | |
4020 | case DIV: | 4021 | case DIV: | |
4021 | case MULT: | 4022 | case MULT: | |
4022 | case AMPER: | 4023 | case AMPER: | |
4023 | case STAR: | 4024 | case STAR: | |
4024 | case UMINUS: | 4025 | case UMINUS: | |
4025 | case SHRASS: | 4026 | case SHRASS: | |
4026 | case UPLUS: | 4027 | case UPLUS: | |
4027 | case ANDASS: | 4028 | case ANDASS: | |
4028 | case REAL: | 4029 | case REAL: | |
4029 | case IMAG: | 4030 | case IMAG: | |
4030 | break; | 4031 | break; | |
4031 | } | 4032 | } | |
4032 | 4033 | |||
4033 | if (dowarn) { | 4034 | if (dowarn) { | |
4034 | /* precedence confusion possible: parenthesize! */ | 4035 | /* precedence confusion possible: parenthesize! */ | |
4035 | warning(169); | 4036 | warning(169); | |
4036 | } | 4037 | } | |
4037 | 4038 | |||
4038 | } | 4039 | } |