xref: /illumos-gate/usr/src/tools/smatch/src/expression.c (revision c85f09cc92abd00c84e58ec9f0f5d942906cb713)
1 /*
2  * sparse/expression.c
3  *
4  * Copyright (C) 2003 Transmeta Corp.
5  *               2003-2004 Linus Torvalds
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  * This is the expression parsing part of parsing C.
26  */
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <limits.h>
36 
37 #include "lib.h"
38 #include "allocate.h"
39 #include "token.h"
40 #include "parse.h"
41 #include "symbol.h"
42 #include "scope.h"
43 #include "expression.h"
44 #include "target.h"
45 #include "char.h"
46 
match_oplist(int op,...)47 static int match_oplist(int op, ...)
48 {
49 	va_list args;
50 	int nextop;
51 
52 	va_start(args, op);
53 	do {
54 		nextop = va_arg(args, int);
55 	} while (nextop != 0 && nextop != op);
56 	va_end(args);
57 
58 	return nextop != 0;
59 }
60 
61 static struct token *comma_expression(struct token *, struct expression **);
62 
parens_expression(struct token * token,struct expression ** expr,const char * where)63 struct token *parens_expression(struct token *token, struct expression **expr, const char *where)
64 {
65 	struct token *p;
66 
67 	token = expect(token, '(', where);
68 	p = token;
69 	if (match_op(token, '{')) {
70 		struct expression *e = alloc_expression(token->pos, EXPR_STATEMENT);
71 		struct statement *stmt = alloc_statement(token->pos, STMT_COMPOUND);
72 		*expr = e;
73 		e->statement = stmt;
74 		start_symbol_scope(e->pos);
75 		token = compound_statement(token->next, stmt);
76 		end_symbol_scope();
77 		token = expect(token, '}', "at end of statement expression");
78 	} else
79 		token = parse_expression(token, expr);
80 
81 	if (token == p)
82 		sparse_error(token->pos, "an expression is expected before ')'");
83 	return expect(token, ')', where);
84 }
85 
86 /*
87  * Handle __func__, __FUNCTION__ and __PRETTY_FUNCTION__ token
88  * conversion
89  */
handle_func(struct token * token)90 static struct symbol *handle_func(struct token *token)
91 {
92 	struct ident *ident = token->ident;
93 	struct symbol *decl, *array;
94 	struct string *string;
95 	int len;
96 
97 	if (ident != &__func___ident &&
98 	    ident != &__FUNCTION___ident &&
99 	    ident != &__PRETTY_FUNCTION___ident)
100 		return NULL;
101 
102 	if (!current_fn || !current_fn->ident)
103 		return NULL;
104 
105 	/* OK, it's one of ours */
106 	array = alloc_symbol(token->pos, SYM_ARRAY);
107 	array->ctype.base_type = &char_ctype;
108 	array->ctype.alignment = 1;
109 	array->endpos = token->pos;
110 	decl = alloc_symbol(token->pos, SYM_NODE);
111 	decl->ctype.base_type = array;
112 	decl->ctype.alignment = 1;
113 	decl->ctype.modifiers = MOD_STATIC;
114 	decl->endpos = token->pos;
115 
116 	/* function-scope, but in NS_SYMBOL */
117 	bind_symbol(decl, ident, NS_LABEL);
118 	decl->namespace = NS_SYMBOL;
119 
120 	len = current_fn->ident->len;
121 	string = __alloc_string(len + 1);
122 	memcpy(string->data, current_fn->ident->name, len);
123 	string->data[len] = 0;
124 	string->length = len + 1;
125 
126 	decl->initializer = alloc_expression(token->pos, EXPR_STRING);
127 	decl->initializer->string = string;
128 	decl->initializer->ctype = decl;
129 	decl->array_size = alloc_const_expression(token->pos, len + 1);
130 	array->array_size = decl->array_size;
131 	decl->bit_size = array->bit_size = bytes_to_bits(len + 1);
132 
133 	return decl;
134 }
135 
parse_type(struct token * token,struct expression ** tree)136 static struct token *parse_type(struct token *token, struct expression **tree)
137 {
138 	struct symbol *sym;
139 	*tree = alloc_expression(token->pos, EXPR_TYPE);
140 	token = typename(token, &sym, NULL);
141 	if (sym->ident)
142 		sparse_error(token->pos,
143 			     "type expression should not include identifier "
144 			     "\"%s\"", sym->ident->name);
145 	(*tree)->symbol = sym;
146 	return token;
147 }
148 
builtin_types_compatible_p_expr(struct token * token,struct expression ** tree)149 static struct token *builtin_types_compatible_p_expr(struct token *token,
150 						     struct expression **tree)
151 {
152 	struct expression *expr = alloc_expression(
153 		token->pos, EXPR_COMPARE);
154 	expr->op = SPECIAL_EQUAL;
155 	token = token->next;
156 	if (!match_op(token, '('))
157 		return expect(token, '(',
158 			      "after __builtin_types_compatible_p");
159 	token = token->next;
160 	token = parse_type(token, &expr->left);
161 	if (!match_op(token, ','))
162 		return expect(token, ',',
163 			      "in __builtin_types_compatible_p");
164 	token = token->next;
165 	token = parse_type(token, &expr->right);
166 	if (!match_op(token, ')'))
167 		return expect(token, ')',
168 			      "at end of __builtin_types_compatible_p");
169 	token = token->next;
170 
171 	*tree = expr;
172 	return token;
173 }
174 
builtin_offsetof_expr(struct token * token,struct expression ** tree)175 static struct token *builtin_offsetof_expr(struct token *token,
176 					   struct expression **tree)
177 {
178 	struct expression *expr = NULL;
179 	struct expression **p = &expr;
180 	struct symbol *sym;
181 	int op = '.';
182 
183 	token = token->next;
184 	if (!match_op(token, '('))
185 		return expect(token, '(', "after __builtin_offset");
186 
187 	token = token->next;
188 	token = typename(token, &sym, NULL);
189 	if (sym->ident)
190 		sparse_error(token->pos,
191 			     "type expression should not include identifier "
192 			     "\"%s\"", sym->ident->name);
193 
194 	if (!match_op(token, ','))
195 		return expect(token, ',', "in __builtin_offset");
196 
197 	while (1) {
198 		struct expression *e;
199 		switch (op) {
200 		case ')':
201 			expr->in = sym;
202 			*tree = expr;
203 		default:
204 			return expect(token, ')', "at end of __builtin_offset");
205 		case SPECIAL_DEREFERENCE:
206 			e = alloc_expression(token->pos, EXPR_OFFSETOF);
207 			e->op = '[';
208 			*p = e;
209 			p = &e->down;
210 			/* fall through */
211 		case '.':
212 			token = token->next;
213 			e = alloc_expression(token->pos, EXPR_OFFSETOF);
214 			e->op = '.';
215 			if (token_type(token) != TOKEN_IDENT) {
216 				sparse_error(token->pos, "Expected member name");
217 				return token;
218 			}
219 			e->ident = token->ident;
220 			token = token->next;
221 			break;
222 		case '[':
223 			token = token->next;
224 			e = alloc_expression(token->pos, EXPR_OFFSETOF);
225 			e->op = '[';
226 			token = parse_expression(token, &e->index);
227 			token = expect(token, ']',
228 					"at end of array dereference");
229 			if (!e->index)
230 				return token;
231 		}
232 		*p = e;
233 		p = &e->down;
234 		op = token_type(token) == TOKEN_SPECIAL ? token->special : 0;
235 	}
236 }
237 
238 #ifndef ULLONG_MAX
239 #define ULLONG_MAX (~0ULL)
240 #endif
241 
parse_num(const char * nptr,char ** end)242 static unsigned long long parse_num(const char *nptr, char **end)
243 {
244 	if (nptr[0] == '0' && tolower((unsigned char)nptr[1]) == 'b')
245 		return strtoull(&nptr[2], end, 2);
246 	return strtoull(nptr, end, 0);
247 }
248 
get_number_value(struct expression * expr,struct token * token)249 static void get_number_value(struct expression *expr, struct token *token)
250 {
251 	const char *str = token->number;
252 	unsigned long long value;
253 	char *end;
254 	int size = 0, want_unsigned = 0;
255 	int overflow = 0, do_warn = 0;
256 	int try_unsigned = 1;
257 	int bits;
258 
259 	errno = 0;
260 	value = parse_num(str, &end);
261 	if (end == str)
262 		goto Float;
263 	if (value == ULLONG_MAX && errno == ERANGE)
264 		overflow = 1;
265 	while (1) {
266 		char c = *end++;
267 		if (!c) {
268 			break;
269 		} else if (c == 'u' || c == 'U') {
270 			if (want_unsigned)
271 				goto Enoint;
272 			want_unsigned = 1;
273 		} else if (c == 'l' || c == 'L') {
274 			if (size)
275 				goto Enoint;
276 			size = 1;
277 			if (*end == c) {
278 				size = 2;
279 				end++;
280 			}
281 		} else
282 			goto Float;
283 	}
284 	if (overflow)
285 		goto Eoverflow;
286 	/* OK, it's a valid integer */
287 	/* decimals can be unsigned only if directly specified as such */
288 	if (str[0] != '0' && !want_unsigned)
289 		try_unsigned = 0;
290 	if (!size) {
291 		bits = bits_in_int - 1;
292 		if (!(value & (~1ULL << bits))) {
293 			if (!(value & (1ULL << bits))) {
294 				goto got_it;
295 			} else if (try_unsigned) {
296 				want_unsigned = 1;
297 				goto got_it;
298 			}
299 		}
300 		size = 1;
301 		do_warn = 1;
302 	}
303 	if (size < 2) {
304 		bits = bits_in_long - 1;
305 		if (!(value & (~1ULL << bits))) {
306 			if (!(value & (1ULL << bits))) {
307 				goto got_it;
308 			} else if (try_unsigned) {
309 				want_unsigned = 1;
310 				goto got_it;
311 			}
312 			do_warn |= 2;
313 		}
314 		size = 2;
315 		do_warn |= 1;
316 	}
317 	bits = bits_in_longlong - 1;
318 	if (value & (~1ULL << bits))
319 		goto Eoverflow;
320 	if (!(value & (1ULL << bits)))
321 		goto got_it;
322 	if (!try_unsigned)
323 		warning(expr->pos, "decimal constant %s is too big for long long",
324 			show_token(token));
325 	want_unsigned = 1;
326 got_it:
327 	if (do_warn && Wconstant_suffix)
328 		warning(expr->pos, "constant %s is so big it is%s%s%s",
329 			show_token(token),
330 			want_unsigned ? " unsigned":"",
331 			size > 0 ? " long":"",
332 			size > 1 ? " long":"");
333 	if (do_warn & 2)
334 		warning(expr->pos,
335 			"decimal constant %s is between LONG_MAX and ULONG_MAX."
336 			" For C99 that means long long, C90 compilers are very "
337 			"likely to produce unsigned long (and a warning) here",
338 			show_token(token));
339         expr->type = EXPR_VALUE;
340 	expr->flags = CEF_SET_INT;
341         expr->ctype = ctype_integer(size, want_unsigned);
342         expr->value = value;
343 	return;
344 Eoverflow:
345 	error_die(expr->pos, "constant %s is too big even for unsigned long long",
346 			show_token(token));
347 	return;
348 Float:
349 	expr->fvalue = string_to_ld(str, &end);
350 	if (str == end)
351 		goto Enoint;
352 
353 	if (*end && end[1])
354 		goto Enoint;
355 
356 	if (*end == 'f' || *end == 'F')
357 		expr->ctype = &float_ctype;
358 	else if (*end == 'l' || *end == 'L')
359 		expr->ctype = &ldouble_ctype;
360 	else if (!*end)
361 		expr->ctype = &double_ctype;
362 	else
363 		goto Enoint;
364 
365 	expr->flags = CEF_SET_FLOAT;
366 	expr->type = EXPR_FVALUE;
367 	return;
368 
369 Enoint:
370 	error_die(expr->pos, "constant %s is not a valid number", show_token(token));
371 }
372 
primary_expression(struct token * token,struct expression ** tree)373 struct token *primary_expression(struct token *token, struct expression **tree)
374 {
375 	struct expression *expr = NULL;
376 
377 	switch (token_type(token)) {
378 	case TOKEN_CHAR ... TOKEN_WIDE_CHAR_EMBEDDED_3:
379 		expr = alloc_expression(token->pos, EXPR_VALUE);
380 		expr->flags = CEF_SET_CHAR;
381 		expr->ctype = token_type(token) < TOKEN_WIDE_CHAR ? &int_ctype : &long_ctype;
382 		get_char_constant(token, &expr->value);
383 		token = token->next;
384 		break;
385 
386 	case TOKEN_NUMBER:
387 		expr = alloc_expression(token->pos, EXPR_VALUE);
388 		get_number_value(expr, token); /* will see if it's an integer */
389 		token = token->next;
390 		break;
391 
392 	case TOKEN_ZERO_IDENT: {
393 		expr = alloc_expression(token->pos, EXPR_SYMBOL);
394 		expr->flags = CEF_SET_INT;
395 		expr->ctype = &int_ctype;
396 		expr->symbol = &zero_int;
397 		expr->symbol_name = token->ident;
398 		token = token->next;
399 		break;
400 	}
401 
402 	case TOKEN_IDENT: {
403 		struct symbol *sym = lookup_symbol(token->ident, NS_SYMBOL | NS_TYPEDEF);
404 		struct token *next = token->next;
405 
406 		if (!sym) {
407 			sym = handle_func(token);
408 			if (token->ident == &__builtin_types_compatible_p_ident) {
409 				token = builtin_types_compatible_p_expr(token, &expr);
410 				break;
411 			}
412 			if (token->ident == &__builtin_offsetof_ident) {
413 				token = builtin_offsetof_expr(token, &expr);
414 				break;
415 			}
416 		} else if (sym->enum_member) {
417 			expr = alloc_expression(token->pos, EXPR_VALUE);
418 			*expr = *sym->initializer;
419 			/* we want the right position reported, thus the copy */
420 			expr->pos = token->pos;
421 			expr->flags = CEF_SET_ENUM;
422 			token = next;
423 			break;
424 		}
425 
426 		expr = alloc_expression(token->pos, EXPR_SYMBOL);
427 
428 		/*
429 		 * We support types as real first-class citizens, with type
430 		 * comparisons etc:
431 		 *
432 		 *	if (typeof(a) == int) ..
433 		 */
434 		if (sym && sym->namespace == NS_TYPEDEF) {
435 			sparse_error(token->pos, "typename in expression");
436 			sym = NULL;
437 		}
438 		expr->symbol_name = token->ident;
439 		expr->symbol = sym;
440 
441 		/*
442 		 * A pointer to an lvalue designating a static storage
443 		 * duration object is an address constant [6.6(9)].
444 		 */
445 		if (sym && (sym->ctype.modifiers & (MOD_TOPLEVEL | MOD_STATIC)))
446 			expr->flags = CEF_ADDR;
447 
448 		token = next;
449 		break;
450 	}
451 
452 	case TOKEN_STRING:
453 	case TOKEN_WIDE_STRING:
454 		expr = alloc_expression(token->pos, EXPR_STRING);
455 		token = get_string_constant(token, expr);
456 		break;
457 
458 	case TOKEN_SPECIAL:
459 		if (token->special == '(') {
460 			expr = alloc_expression(token->pos, EXPR_PREOP);
461 			expr->op = '(';
462 			token = parens_expression(token, &expr->unop, "in expression");
463 			break;
464 		}
465 		if (token->special == '[' && lookup_type(token->next)) {
466 			expr = alloc_expression(token->pos, EXPR_TYPE);
467 			token = typename(token->next, &expr->symbol, NULL);
468 			token = expect(token, ']', "in type expression");
469 			break;
470 		}
471 
472 	default:
473 		;
474 	}
475 	*tree = expr;
476 	return token;
477 }
478 
expression_list(struct token * token,struct expression_list ** list)479 static struct token *expression_list(struct token *token, struct expression_list **list)
480 {
481 	while (!match_op(token, ')')) {
482 		struct expression *expr = NULL;
483 		token = assignment_expression(token, &expr);
484 		if (!expr)
485 			break;
486 		add_expression(list, expr);
487 		if (!match_op(token, ','))
488 			break;
489 		token = token->next;
490 	}
491 	return token;
492 }
493 
494 /*
495  * extend to deal with the ambiguous C grammar for parsing
496  * a cast expressions followed by an initializer.
497  */
postfix_expression(struct token * token,struct expression ** tree,struct expression * cast_init_expr)498 static struct token *postfix_expression(struct token *token, struct expression **tree, struct expression *cast_init_expr)
499 {
500 	struct expression *expr = cast_init_expr;
501 
502 	if (!expr)
503 		token = primary_expression(token, &expr);
504 
505 	while (expr && token_type(token) == TOKEN_SPECIAL) {
506 		switch (token->special) {
507 		case '[': {			/* Array dereference */
508 			struct expression *deref = alloc_expression(token->pos, EXPR_PREOP);
509 			struct expression *add = alloc_expression(token->pos, EXPR_BINOP);
510 
511 			deref->op = '*';
512 			deref->unop = add;
513 
514 			add->op = '+';
515 			add->left = expr;
516 			token = parse_expression(token->next, &add->right);
517 			token = expect(token, ']', "at end of array dereference");
518 			expr = deref;
519 			continue;
520 		}
521 		case SPECIAL_INCREMENT:		/* Post-increment */
522 		case SPECIAL_DECREMENT:	{	/* Post-decrement */
523 			struct expression *post = alloc_expression(token->pos, EXPR_POSTOP);
524 			post->op = token->special;
525 			post->unop = expr;
526 			expr = post;
527 			token = token->next;
528 			continue;
529 		}
530 		case SPECIAL_DEREFERENCE: {	/* Structure pointer member dereference */
531 			/* "x->y" is just shorthand for "(*x).y" */
532 			struct expression *inner = alloc_expression(token->pos, EXPR_PREOP);
533 			inner->op = '*';
534 			inner->unop = expr;
535 			expr = inner;
536 		}
537 		/* Fall through!! */
538 		case '.': {			/* Structure member dereference */
539 			struct expression *deref = alloc_expression(token->pos, EXPR_DEREF);
540 			deref->op = '.';
541 			deref->deref = expr;
542 			token = token->next;
543 			if (token_type(token) != TOKEN_IDENT) {
544 				sparse_error(token->pos, "Expected member name");
545 				break;
546 			}
547 			deref->member = token->ident;
548 			deref->member_offset = -1;
549 			token = token->next;
550 			expr = deref;
551 			continue;
552 		}
553 
554 		case '(': {			/* Function call */
555 			struct expression *call = alloc_expression(token->pos, EXPR_CALL);
556 			call->op = '(';
557 			call->fn = expr;
558 			token = expression_list(token->next, &call->args);
559 			token = expect(token, ')', "in function call");
560 			expr = call;
561 			continue;
562 		}
563 
564 		default:
565 			break;
566 		}
567 		break;
568 	}
569 	*tree = expr;
570 	return token;
571 }
572 
573 static struct token *cast_expression(struct token *token, struct expression **tree);
574 static struct token *unary_expression(struct token *token, struct expression **tree);
575 
type_info_expression(struct token * token,struct expression ** tree,int type)576 static struct token *type_info_expression(struct token *token,
577 	struct expression **tree, int type)
578 {
579 	struct expression *expr = alloc_expression(token->pos, type);
580 	struct token *p;
581 
582 	*tree = expr;
583 	expr->flags = CEF_SET_ICE; /* XXX: VLA support will need that changed */
584 	token = token->next;
585 	if (!match_op(token, '(') || !lookup_type(token->next))
586 		return unary_expression(token, &expr->cast_expression);
587 	p = token;
588 	token = typename(token->next, &expr->cast_type, NULL);
589 
590 	if (!match_op(token, ')')) {
591 		static const char * error[] = {
592 			[EXPR_SIZEOF] = "at end of sizeof",
593 			[EXPR_ALIGNOF] = "at end of __alignof__",
594 			[EXPR_PTRSIZEOF] = "at end of __sizeof_ptr__"
595 		};
596 		return expect(token, ')', error[type]);
597 	}
598 
599 	token = token->next;
600 	/*
601 	 * C99 ambiguity: the typename might have been the beginning
602 	 * of a typed initializer expression..
603 	 */
604 	if (match_op(token, '{')) {
605 		struct expression *cast = alloc_expression(p->pos, EXPR_CAST);
606 		cast->cast_type = expr->cast_type;
607 		expr->cast_type = NULL;
608 		expr->cast_expression = cast;
609 		token = initializer(&cast->cast_expression, token);
610 		token = postfix_expression(token, &expr->cast_expression, cast);
611 	}
612 	return token;
613 }
614 
unary_expression(struct token * token,struct expression ** tree)615 static struct token *unary_expression(struct token *token, struct expression **tree)
616 {
617 	if (token_type(token) == TOKEN_IDENT) {
618 		struct ident *ident = token->ident;
619 		if (ident->reserved) {
620 			static const struct {
621 				struct ident *id;
622 				int type;
623 			} type_information[] = {
624 				{ &sizeof_ident, EXPR_SIZEOF },
625 				{ &__alignof___ident, EXPR_ALIGNOF },
626 				{ &__alignof_ident, EXPR_ALIGNOF },
627 				{ &_Alignof_ident, EXPR_ALIGNOF },
628 				{ &__sizeof_ptr___ident, EXPR_PTRSIZEOF },
629 			};
630 			int i;
631 			for (i = 0; i < ARRAY_SIZE(type_information); i++) {
632 				if (ident == type_information[i].id)
633 					return type_info_expression(token, tree, type_information[i].type);
634 			}
635 		}
636 	}
637 
638 	if (token_type(token) == TOKEN_SPECIAL) {
639 		if (match_oplist(token->special,
640 		    SPECIAL_INCREMENT, SPECIAL_DECREMENT,
641 		    '&', '*', 0)) {
642 		    	struct expression *unop;
643 			struct expression *unary;
644 			struct token *next;
645 
646 			next = cast_expression(token->next, &unop);
647 			if (!unop) {
648 				sparse_error(token->pos, "Syntax error in unary expression");
649 				*tree = NULL;
650 				return next;
651 			}
652 			unary = alloc_expression(token->pos, EXPR_PREOP);
653 			unary->op = token->special;
654 			unary->unop = unop;
655 			*tree = unary;
656 			return next;
657 		}
658 		/* possibly constant ones */
659 		if (match_oplist(token->special, '+', '-', '~', '!', 0)) {
660 		    	struct expression *unop;
661 			struct expression *unary;
662 			struct token *next;
663 
664 			next = cast_expression(token->next, &unop);
665 			if (!unop) {
666 				sparse_error(token->pos, "Syntax error in unary expression");
667 				*tree = NULL;
668 				return next;
669 			}
670 			unary = alloc_expression(token->pos, EXPR_PREOP);
671 			unary->op = token->special;
672 			unary->unop = unop;
673 			*tree = unary;
674 			return next;
675 		}
676 		/* Gcc extension: &&label gives the address of a label */
677 		if (match_op(token, SPECIAL_LOGICAL_AND) &&
678 		    token_type(token->next) == TOKEN_IDENT) {
679 			struct expression *label = alloc_expression(token->pos, EXPR_LABEL);
680 			struct symbol *sym = label_symbol(token->next);
681 			if (!(sym->ctype.modifiers & MOD_ADDRESSABLE)) {
682 				sym->ctype.modifiers |= MOD_ADDRESSABLE;
683 				add_symbol(&function_computed_target_list, sym);
684 			}
685 			label->flags = CEF_ADDR;
686 			label->label_symbol = sym;
687 			*tree = label;
688 			return token->next->next;
689 		}
690 
691 	}
692 
693 	return postfix_expression(token, tree, NULL);
694 }
695 
696 /*
697  * Ambiguity: a '(' can be either a cast-expression or
698  * a primary-expression depending on whether it is followed
699  * by a type or not.
700  *
701  * additional ambiguity: a "cast expression" followed by
702  * an initializer is really a postfix-expression.
703  */
cast_expression(struct token * token,struct expression ** tree)704 static struct token *cast_expression(struct token *token, struct expression **tree)
705 {
706 	if (match_op(token, '(')) {
707 		struct token *next = token->next;
708 		if (lookup_type(next)) {
709 			struct expression *cast = alloc_expression(next->pos, EXPR_CAST);
710 			struct expression *v;
711 			struct symbol *sym;
712 			int is_force;
713 
714 			token = typename(next, &sym, &is_force);
715 			cast->cast_type = sym;
716 			token = expect(token, ')', "at end of cast operator");
717 			if (match_op(token, '{')) {
718 				if (toplevel(block_scope))
719 					sym->ctype.modifiers |= MOD_TOPLEVEL;
720 				if (is_force)
721 					warning(sym->pos,
722 						"[force] in compound literal");
723 				token = initializer(&cast->cast_expression, token);
724 				return postfix_expression(token, tree, cast);
725 			}
726 			*tree = cast;
727 			if (is_force)
728 				cast->type = EXPR_FORCE_CAST;
729 			token = cast_expression(token, &v);
730 			if (!v)
731 				return token;
732 			cast->cast_expression = v;
733 			return token;
734 		}
735 	}
736 	return unary_expression(token, tree);
737 }
738 
739 /*
740  * Generic left-to-right binop parsing
741  *
742  * This _really_ needs to be inlined, because that makes the inner
743  * function call statically deterministic rather than a totally
744  * unpredictable indirect call. But gcc-3 is so "clever" that it
745  * doesn't do so by default even when you tell it to inline it.
746  *
747  * Making it a macro avoids the inlining problem, and also means
748  * that we can pass in the op-comparison as an expression rather
749  * than create a data structure for it.
750  */
751 
752 #define LR_BINOP_EXPRESSION(__token, tree, type, inner, compare)	\
753 	struct expression *left = NULL;					\
754 	struct token * next = inner(__token, &left);			\
755 									\
756 	if (left) {							\
757 		while (token_type(next) == TOKEN_SPECIAL) {		\
758 			struct expression *top, *right = NULL;		\
759 			int op = next->special;				\
760 									\
761 			if (!(compare))					\
762 				goto out;				\
763 			top = alloc_expression(next->pos, type);	\
764 			next = inner(next->next, &right);		\
765 			if (!right) {					\
766 				sparse_error(next->pos, "No right hand side of '%s'-expression", show_special(op));	\
767 				break;					\
768 			}						\
769 			top->op = op;					\
770 			top->left = left;				\
771 			top->right = right;				\
772 			left = top;					\
773 		}							\
774 	}								\
775 out:									\
776 	*tree = left;							\
777 	return next;							\
778 
multiplicative_expression(struct token * token,struct expression ** tree)779 static struct token *multiplicative_expression(struct token *token, struct expression **tree)
780 {
781 	LR_BINOP_EXPRESSION(
782 		token, tree, EXPR_BINOP, cast_expression,
783 		(op == '*') || (op == '/') || (op == '%')
784 	);
785 }
786 
additive_expression(struct token * token,struct expression ** tree)787 static struct token *additive_expression(struct token *token, struct expression **tree)
788 {
789 	LR_BINOP_EXPRESSION(
790 		token, tree, EXPR_BINOP, multiplicative_expression,
791 		(op == '+') || (op == '-')
792 	);
793 }
794 
shift_expression(struct token * token,struct expression ** tree)795 static struct token *shift_expression(struct token *token, struct expression **tree)
796 {
797 	LR_BINOP_EXPRESSION(
798 		token, tree, EXPR_BINOP, additive_expression,
799 		(op == SPECIAL_LEFTSHIFT) || (op == SPECIAL_RIGHTSHIFT)
800 	);
801 }
802 
relational_expression(struct token * token,struct expression ** tree)803 static struct token *relational_expression(struct token *token, struct expression **tree)
804 {
805 	LR_BINOP_EXPRESSION(
806 		token, tree, EXPR_COMPARE, shift_expression,
807 		(op == '<') || (op == '>') ||
808 		(op == SPECIAL_LTE) || (op == SPECIAL_GTE)
809 	);
810 }
811 
equality_expression(struct token * token,struct expression ** tree)812 static struct token *equality_expression(struct token *token, struct expression **tree)
813 {
814 	LR_BINOP_EXPRESSION(
815 		token, tree, EXPR_COMPARE, relational_expression,
816 		(op == SPECIAL_EQUAL) || (op == SPECIAL_NOTEQUAL)
817 	);
818 }
819 
bitwise_and_expression(struct token * token,struct expression ** tree)820 static struct token *bitwise_and_expression(struct token *token, struct expression **tree)
821 {
822 	LR_BINOP_EXPRESSION(
823 		token, tree, EXPR_BINOP, equality_expression,
824 		(op == '&')
825 	);
826 }
827 
bitwise_xor_expression(struct token * token,struct expression ** tree)828 static struct token *bitwise_xor_expression(struct token *token, struct expression **tree)
829 {
830 	LR_BINOP_EXPRESSION(
831 		token, tree, EXPR_BINOP, bitwise_and_expression,
832 		(op == '^')
833 	);
834 }
835 
bitwise_or_expression(struct token * token,struct expression ** tree)836 static struct token *bitwise_or_expression(struct token *token, struct expression **tree)
837 {
838 	LR_BINOP_EXPRESSION(
839 		token, tree, EXPR_BINOP, bitwise_xor_expression,
840 		(op == '|')
841 	);
842 }
843 
logical_and_expression(struct token * token,struct expression ** tree)844 static struct token *logical_and_expression(struct token *token, struct expression **tree)
845 {
846 	LR_BINOP_EXPRESSION(
847 		token, tree, EXPR_LOGICAL, bitwise_or_expression,
848 		(op == SPECIAL_LOGICAL_AND)
849 	);
850 }
851 
logical_or_expression(struct token * token,struct expression ** tree)852 static struct token *logical_or_expression(struct token *token, struct expression **tree)
853 {
854 	LR_BINOP_EXPRESSION(
855 		token, tree, EXPR_LOGICAL, logical_and_expression,
856 		(op == SPECIAL_LOGICAL_OR)
857 	);
858 }
859 
conditional_expression(struct token * token,struct expression ** tree)860 struct token *conditional_expression(struct token *token, struct expression **tree)
861 {
862 	token = logical_or_expression(token, tree);
863 	if (*tree && match_op(token, '?')) {
864 		struct expression *expr = alloc_expression(token->pos, EXPR_CONDITIONAL);
865 		expr->op = token->special;
866 		expr->left = *tree;
867 		*tree = expr;
868 		token = parse_expression(token->next, &expr->cond_true);
869 		token = expect(token, ':', "in conditional expression");
870 		token = conditional_expression(token, &expr->cond_false);
871 	}
872 	return token;
873 }
874 
assignment_expression(struct token * token,struct expression ** tree)875 struct token *assignment_expression(struct token *token, struct expression **tree)
876 {
877 	token = conditional_expression(token, tree);
878 	if (*tree && token_type(token) == TOKEN_SPECIAL) {
879 		static const int assignments[] = {
880 			'=',
881 			SPECIAL_ADD_ASSIGN, SPECIAL_SUB_ASSIGN,
882 			SPECIAL_MUL_ASSIGN, SPECIAL_DIV_ASSIGN,
883 			SPECIAL_MOD_ASSIGN, SPECIAL_SHL_ASSIGN,
884 			SPECIAL_SHR_ASSIGN, SPECIAL_AND_ASSIGN,
885 			SPECIAL_OR_ASSIGN,  SPECIAL_XOR_ASSIGN };
886 		int i, op = token->special;
887 		for (i = 0; i < ARRAY_SIZE(assignments); i++)
888 			if (assignments[i] == op) {
889 				struct expression * expr = alloc_expression(token->pos, EXPR_ASSIGNMENT);
890 				expr->left = *tree;
891 				expr->op = op;
892 				*tree = expr;
893 				return assignment_expression(token->next, &expr->right);
894 			}
895 	}
896 	return token;
897 }
898 
comma_expression(struct token * token,struct expression ** tree)899 static struct token *comma_expression(struct token *token, struct expression **tree)
900 {
901 	LR_BINOP_EXPRESSION(
902 		token, tree, EXPR_COMMA, assignment_expression,
903 		(op == ',')
904 	);
905 }
906 
parse_expression(struct token * token,struct expression ** tree)907 struct token *parse_expression(struct token *token, struct expression **tree)
908 {
909 	return comma_expression(token,tree);
910 }
911 
912 
913