1 /*
2  * Copyright (c) 2004 - 2010, Nils R. Weller
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  *
27  * Expression parser
28  */
29 #include "expr.h"
30 #include <stdlib.h>
31 #include <string.h>
32 #include <limits.h>
33 #include "token.h"
34 #include "error.h"
35 #include "misc.h"
36 #include "defs.h"
37 #include "type.h"
38 
39 #ifndef PREPROCESSOR
40 #    include "decl.h"
41 #    include "builtins.h"
42 #    include "scope.h"
43 #    include "icode.h"
44 #    include "debug.h"
45 #    include "cc1_main.h"
46 #    include "functions.h"
47 #    include "control.h"
48 #    include "analyze.h"
49 #    include "symlist.h"
50 #    include "backend.h"
51 #    include "reg.h"
52 #else
53 #    include "macros.h"
54 #endif
55 
56 #include "subexpr.h"
57 #include "typemap.h"
58 #include "libnwcc.h"
59 #include "zalloc.h"
60 #include "n_libc.h"
61 #include "evalexpr.h"
62 
63 
64 
65 int
const_value_is_nonzero(struct tyval * cv)66 const_value_is_nonzero(struct tyval *cv) {
67 	int		size;
68 	int		i;
69 	unsigned char	*uc;
70 
71 
72 	if (cv->str != NULL) {
73 		/* 08/05/09: This was missing (gave a crash) */
74 		return 1;
75 	}
76 
77 	size = cross_get_sizeof_type(cv->type);
78 	for (uc = (unsigned char *)cv->value, i = 0; i < size; ++i, ++uc) {
79 		if (*uc != 0) {
80 			return 1;
81 		}
82 	}
83 	return 0;
84 }
85 
86 #ifndef PREPROCESSOR
87 
88 /*
89  * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
90  * doesn't handle cross-compilation :(
91  * address->diff should probably become a ``struct tyval'' and then we
92  * need a nice set of utility functions to convert host values from/to
93  * target-independent values. tyval is probably our best bet for
94  * abstracting these things because exec_op() and such already use it
95  * in the interface
96  */
97 static void
addr_add_sub(struct tyval * tv,struct expr * ex,struct type * ty,int op)98 addr_add_sub(struct tyval *tv, struct expr *ex, struct type *ty, int op) {
99 	long		val;
100 	long		origval;
101 	int		esize = backend->get_sizeof_elem_type(ty);
102 	void		*newval;
103 
104 	/*
105 	 * 07/31/09: We have to create a copy of the constant value before
106 	 * we change it! Otherwise, if the expression is re-evaluated, the
107 	 * original token will have a ``long'' value with an ``int'' type
108 	 * (which breaks on 64bit big endian systems)
109 	 *
110 	 * So this was one of potentially various places where constant
111 	 * sub-expression evaluation can damage data structures if it turns
112 	 * out the expression has to be evaluated at runtime.
113 	 *
114 	 * (The bug occurred on PPC64 with:
115 	 *
116 	 *     char array[128];
117 	 *     unsigned long ul = (unsigned long)(array + 64);
118 	 *
119 	 * The int token 64 became 0 because the underlying value had been
120 	 * converted to unsigned long, and the value 64 was stored in the
121 	 * upper 4 bytes)
122 	 */
123 	newval = zalloc_buf(Z_CEXPR_BUF); /*n_xmalloc(16);*/ /* XXX */
124 	memcpy(newval, ex->const_value->value, 16);
125 	ex->const_value->value = newval;
126 
127 	cross_do_conv(ex->const_value, TY_LONG, 1);
128 	/* XXX what to do here? :( */
129 	ex->const_value->type->code = TY_LONG;
130 #if 0
131 	val = *(long *)ex->const_value->value * esize;
132 #endif
133 
134 	val = (long)cross_to_host_size_t(ex->const_value);
135 	origval = val;
136 	val *= esize;
137 
138 	if (tv->address != NULL) {
139 		if (op == TOK_OP_PLUS) {
140 			tv->address->diff += val;
141 		} else {
142 			tv->address->diff -= val;
143 		}
144 	} else {
145 		static struct tyval	src;
146 		static struct tyval	tmpval;
147 		static struct token	optok;
148 		struct type		*saved_type;
149 		int			opval = TOK_OP_PLUS;
150 
151 		optok.type = TOK_OPERATOR;
152 		optok.data = &opval;
153 		src.value = ex->const_value->value;
154 
155 		/*
156 		 * 08/19/07: Store (and later restore!) the value val
157 		 * as source. This was missing, so the array element
158 		 * calculation above was ignored
159 		 */
160 		cross_from_host_long(src.value, val, TY_LONG);
161 		src.type = make_basic_type(TY_LONG);
162 
163 		/*
164 		 * 08/19/07: This wasn't working because, as a comment
165 		 * here rightly said :-), we have to use a temporary
166 		 * tyval as target instead of using tv as target and
167 		 * destination
168 		 */
169 		saved_type = tv->type;
170 		tv->type = src.type;
171 		cross_exec_op(&optok, /*tv*/&tmpval, tv, &src);
172 		cross_from_host_long(src.value, origval, TY_LONG);
173 		tv->value = tmpval.value;
174 		tv->type = saved_type;
175 	}
176 }
177 
178 static int
calc_const_addr_diff(struct tyval * tmp1,struct tyval * tmp2,long * diff)179 calc_const_addr_diff(struct tyval *tmp1, struct tyval *tmp2, long *diff) {
180 	if (tmp1->address != NULL && tmp2->address != NULL) {
181 		if (tmp1->address->dec == tmp2->address->dec) {
182 			/* OK, same declaration, only addend makes the difference */
183 			*diff = tmp1->address->diff - tmp2->address->diff;
184 			return 0;
185 		}
186 
187 		/*
188 		 * This may be the same but re-declared identifier (XXX make sure
189 		 * this is really true), so compare by name
190 		 */
191 		if (strcmp(tmp1->address->dec->dtype->name,
192 			tmp2->address->dec->dtype->name) == 0) {
193 			/* OK, same declaration, only addend makes the difference */
194 			*diff = tmp1->address->diff - tmp2->address->diff;
195 			return 0;
196 		}
197 	} else {
198 		/*
199 		 * 07/17/08: Handle constants, like
200 		 *
201 		 *     (char *)123 - (char *)60
202 		 */
203 		struct tyval		tempdest = *tmp1;
204 		struct tyval		tempsrc = *tmp2;
205 		static struct tyval	tmpval;
206 		static struct token	optok;
207 		int			opval = TOK_OP_MINUS;
208 		int			scaling =
209 			tempdest.type->tlist != NULL?
210 			backend->get_sizeof_elem_type(tempdest.type):
211 			backend->get_sizeof_elem_type(tempsrc.type);
212 
213 		optok.type = TOK_OPERATOR;
214 		optok.data = &opval;
215 
216 		tempdest.type = dup_type(tempdest.type);
217 		tempsrc.type = dup_type(tempdest.type);
218 		cross_do_conv(&tempdest, backend->get_size_t()->code, 1);
219 		cross_do_conv(&tempsrc, backend->get_size_t()->code, 1);
220 
221 		/* Remove typenods, since cross_do_conv() doesn't do that */
222 		tempdest.type->tlist = NULL;
223 		tempsrc.type->tlist = NULL;
224 
225 		cross_exec_op(&optok, &tmpval, &tempdest, &tempsrc);
226 		*diff = cross_to_host_size_t(&tmpval);
227 		if (scaling > 1) {
228 			/* int* - int* yields val / sizeof(int) */
229 			*diff /= scaling;
230 		}
231 		return 0;
232 	}
233 
234 	return -1;
235 }
236 
237 static struct addr_const *
alloc_addr_const(void)238 alloc_addr_const(void) {
239 	struct addr_const		*ret = n_xmalloc(sizeof *ret);
240 	static struct addr_const	nullconst;
241 	*ret = nullconst;
242 	return ret;
243 }
244 
245 
246 static struct addr_const	*labels_used_in_cexpr_head;
247 static struct addr_const	*labels_used_in_cexpr_tail;
248 
249 void
process_labels_used_list(struct function * func)250 process_labels_used_list(struct function *func) {
251 	/*
252 	 * First patch all entries
253 	 */
254 	struct addr_const	*c;
255 
256 	for (c = labels_used_in_cexpr_head; c != NULL; c = c->next) {
257 		struct label	*l;
258 
259 		if ((l = lookup_label(func, c->labeltok->data)) == NULL) {
260 			errorfl(c->labeltok, "Label `%s' not defined",
261 				c->labeltok->data);
262 		} else {
263 			c->labelname = n_xstrdup(l->instr->dat);
264 			c->funcname = func->proto->dtype->name;
265 		}
266 	}
267 
268 	/*
269 	 * Reset lists for next function
270 	 */
271 	labels_used_in_cexpr_head = NULL;
272 	labels_used_in_cexpr_tail = NULL;
273 }
274 
275 void
append_labels_used_list(struct addr_const * c)276 append_labels_used_list(struct addr_const *c) {
277 	if (labels_used_in_cexpr_head == NULL) {
278 		labels_used_in_cexpr_head = labels_used_in_cexpr_tail = c;
279 	} else {
280 		labels_used_in_cexpr_tail->next = c;
281 		labels_used_in_cexpr_tail = c;
282 	}
283 }
284 
285 static struct tyval
do_static_var(struct expr * tree,struct tyval tv0,struct token * t,struct vreg ** builtinvr,int extype,int is_paren_subex)286 do_static_var(struct expr *tree,
287 		struct tyval tv0,
288 		struct token *t,
289 		struct vreg **builtinvr,
290 		int extype,
291 		int is_paren_subex) {
292 
293 	struct decl	*d;
294 	struct tyval	ret = tv0;
295 	int		i;
296 
297 	if (tree->data->operators[0] != NULL
298 		&& tree->data->operators[0]->type == TOK_PAREN_OPEN) {
299 		struct fcall_data	*fd;
300 
301 		fd = tree->data->operators[0]->data;
302 		if (fd->builtin != NULL
303 			&& fd->builtin->type == BUILTIN_OFFSETOF) {
304 			struct expr	*ex;
305 
306 			/*
307 			 * 07/17/08: Now that __bultin_offsetof() may be
308 			 * non-constant as well, check whether it is
309 			 */
310 			ex = fd->builtin->args[0];
311 			if (ex->const_value == NULL) {
312 				/* Not constant! */
313 				if (extype == EXPR_OPTCONSTINIT
314 					|| extype == EXPR_OPTCONSTARRAYSIZE) {
315 					if (extype == EXPR_OPTCONSTINIT) {
316 						warningfl(t, "Variable "
317 						"initializers are not "
318 						"allowed in ISO C90");
319 					} else {
320 						warningfl(t, "Variable-"
321 						"size arrays are not "
322 						"allowed in ISO C90");
323 					}
324 				} else if (extype == EXPR_OPTCONSTSUBEXPR) {
325 					;
326 				} else {
327 					errorfl(t, "Expression not constant");
328 				}
329 				ret.not_constant = 1;
330 				ret.type = NULL;
331 				return ret;
332 			}
333 			*builtinvr = fd->builtin->builtin->toicode(fd, NULL, 1);
334 			ret.type = (*builtinvr)->type;
335 			ret.value = (*builtinvr)->from_const->data;
336 			goto builtin_done;
337 		}
338 	} else if (tree->data->operators[0] != NULL
339 		&& tree->data->operators[0]->type == TOK_OP_ADDRLABEL) {
340 		/*
341 		 * 07/20/08: This must be a label address constant for
342 		 * computed gotos - &&label. Note that we cannot look up
343 		 * the name yet because it may occur later in the function
344 		 */
345 		ret.address = alloc_addr_const();
346 		ret.address->labeltok = t;
347 		append_labels_used_list(ret.address);
348 		ret.type = make_void_ptr_type();
349 		return ret;
350 	}
351 
352 	if ((d = access_symbol(curscope, t->data, 1)) == NULL) {
353 		/*
354 		 * This may be a call to an undeclared
355 		 * function if this is a VLA size
356 		 * expression or variable initializer
357 		 */
358 		if (extype == EXPR_OPTCONSTINIT
359 			|| extype == EXPR_OPTCONSTARRAYSIZE
360 			|| extype == EXPR_OPTCONSTSUBEXPR) {
361 			ret.not_constant = 1;
362 			ret.type = NULL;
363 		} else {
364 			errorfl(t,
365 			"Undeclared identifier `%s'",
366 			t->ascii);
367 			ret.type = ret.value = NULL;
368 		}
369 		return ret;
370 	}
371 	if (d->dtype->storage != TOK_KEY_STATIC
372 		&& d->dtype->storage != TOK_KEY_EXTERN
373 		&& d->dtype->tenum == NULL
374 		&& (d->dtype->tlist == NULL
375 		|| d->dtype->tlist->type
376 			!= TN_FUNCTION)) {
377 		/*
378 		 * XXX seems totally bogus.. only
379 		 * functions should be allowed at all for
380 		 * *values*???
381 		 */
382 		if (extype == EXPR_OPTCONSTINIT
383 			|| extype == EXPR_OPTCONSTARRAYSIZE) {
384 			if (extype == EXPR_OPTCONSTINIT) {
385 				warningfl(t, "Variable "
386 				"initializers are not "
387 				"allowed in ISO C90");
388 			} else {
389 				warningfl(t, "Variable-"
390 				"size arrays are not "
391 				"allowed in ISO C90");
392 			}
393 		} else if (extype == EXPR_OPTCONSTSUBEXPR) {
394 			;
395 		} else {
396 			errorfl(t, "Use of non-static "
397 			"identifier `%s' in constant"
398 			" expression", d->dtype->name);
399 		}
400 		ret.not_constant = 1;
401 		ret.type = ret.value = NULL;
402 		return ret;
403 	}
404 
405 	/*
406 	 * 06/01/08: Record that this is a static
407 	 * variable, i.e. it is only allowed for
408 	 * address constants
409 	 *
410 	 * 07/15/08: This also ruled out enum instances because
411 	 * there was no distinction between constant and instance
412 	 * by checking tenum_value.
413 	 *
414 	 * In
415 	 *
416 	 *    enum { VAL } foo;
417 	 *
418 	 * ... VAL and foo were both ruled now, now only VAL is.
419 	 */
420 	if ((d->dtype->tenum == NULL || d->tenum_value == NULL)
421 		&& (d->dtype->tlist == NULL
422 		|| d->dtype->tlist->type
423 			!= TN_FUNCTION)) {
424 		/* Not enum or function - variable */
425 		if (d->dtype->tlist != NULL
426 			&& d->dtype->tlist->type
427 			== TN_ARRAY_OF) {
428 			/*
429 			 * Array - decays into pointer
430 			 * to first element, i.e. an
431 			 * address constant!
432 			 */
433 			;
434 		} else {
435 			ret.is_static_var = t;
436 		}
437 	}
438 
439 	ret.type = d->dtype;
440 
441 	if (ret.type->code == TY_ENUM && ret.type->tlist == NULL) {
442 		/*
443 		 * 07/15/08: Didn't change the type from enum to
444 		 * int, so the emitters couldn't load these constants
445 		 * XXX don't use expensive memdup!
446 		 */
447 		ret.type = n_xmemdup(ret.type, sizeof *ret.type);
448 		ret.type->code = TY_INT;
449 		ret.type->sign = TOK_KEY_SIGNED;
450 		ret.type->tenum = NULL;
451 	}
452 
453 	if (d->dtype->tlist == NULL
454 		&& d->dtype->tenum != NULL
455 		&& d->tenum_value != NULL) {
456 
457 		/*
458 		 * The value is freed after use.  This is
459 		 * OK for tokens, but not for enum
460 		 * constants, whose values may be needed
461 		 * later - possibly in the same
462 		 * expression. So create a copy
463 		 */
464 		/* XXX Cross!!!!!!!! */
465 		ret.value = n_xmemdup(
466 			d->tenum_value->data,
467 			sizeof(int));
468 	} else {
469 		int		is_addr = 0 /*1*/ /*0*/;
470 		int		is_subscript = 0;
471 		struct type	curtype;
472 
473 		copy_type(&curtype, d->dtype, 0);
474 
475 		/*
476 		 * An identifier used in a constant
477 		 * expression may only be used for
478 		 * an address constant
479 		 *
480 		 * 07/14/08: Revived address detection, since otherwise
481 		 * OPTSUBEXPR evaluation of static variables always
482 		 * considered those to be addresses
483 		 */
484 		for (i = 0; tree->data->operators[i] != NULL; ++i) {
485 			if (tree->data->operators[i]->type ==
486 				TOK_OPERATOR) {
487 				if (*(int *)tree->data->operators[i]->data
488 					== TOK_OP_ADDR) {
489 					/* Address-of operator */
490 					is_addr = 1;
491 				}
492 			} else if (tree->data->operators[i]->type ==
493 				TOK_ARRAY_OPEN) {
494 				is_subscript = 1;
495 			} else if (tree->data->operators[i]->type ==
496 				TOK_OP_STRUMEMB) {
497 				struct decl	*dp;
498 				struct token	*ident = tree->data->operators[i]->data;
499 
500 				dp = access_symbol(curtype.tstruc->scope,
501 					ident->data, 0);
502 				if (dp != NULL) {
503 					if (dp->dtype->tlist != NULL
504 						&& dp->dtype->tlist->type == TN_ARRAY_OF) {
505 						is_addr = 1;
506 					}
507 				}
508 			}
509 		}
510 		if (!is_addr) {
511 			if (d->dtype->tlist != NULL
512 				&& (d->dtype->tlist->type == TN_ARRAY_OF
513 				|| d->dtype->tlist->type == TN_FUNCTION)) {
514 				if (!is_subscript) {
515 					/*
516 					 * OK - Static array or function
517 					 */
518 					is_addr = 1;
519 				} else if (d->dtype->tlist->type == TN_ARRAY_OF
520 					&& d->dtype->tlist->next != NULL
521 					&& d->dtype->tlist->next->type == TN_ARRAY_OF) {
522 					/*
523 					 * 02/28/09: For multi-dimensional arrays,
524 					 * a subscript yields one of the member
525 					 * arrays, which is allowed because it can
526 					 * be computed as an address constant of
527 					 * the base array plus offset
528 					 */
529 					is_addr = 1;
530 				} else {
531 					/*
532 					 * Not OK as constant - Subscripted
533 					 * array
534 					 */
535 					int	err = 0;
536 					if (extype == EXPR_OPTCONSTINIT
537 						|| extype == EXPR_OPTCONSTARRAYSIZE
538 						|| extype == EXPR_OPTCONSTSUBEXPR) {
539 						if (extype == EXPR_OPTCONSTINIT) {
540 							warningfl(t, "Variable "
541 							"initializers are not "
542 							"allowed in iso c90");
543 						} else if (extype == EXPR_OPTCONSTARRAYSIZE) {
544 							warningfl(t, "variable-"
545 							"size arrays are not "
546 							"allowed in iso c90");
547 						} else { /* expr_optconstsubexpr */
548 							;
549 						}
550 						err = 1;
551 					} else {
552 						/*
553 						 * 05/26/09: We can't error for
554 						 * parenthesized subexpressions
555 						 * yet, because that would rule
556 						 * out
557 						 *
558 						 *     &(foo[0])
559 						 */
560 						if (!is_paren_subex) {
561 							errorfl(t, "Invalid array subscript in "
562 								"constant expression");
563 							err = 1;
564 						} else {
565 							is_addr = 1;
566 						}
567 					}
568 
569 					if (err) {
570 						ret.not_constant = 1;
571 						ret.type = NULL;
572 						return ret;
573 					}
574 				}
575 			}
576 		}
577 		if (!is_addr) {
578 			if (is_paren_subex) {
579 				/*
580 				 * Make things like &(var)
581 				 * work
582 				 */
583 				;
584 			} else {
585 				/*
586 				 * Must be subscript like buf[x],
587 				 * AND there is no address-of
588 				 * operator - So it can't be a
589 				 * constant expression
590 				 */
591 				if (extype == EXPR_OPTCONSTINIT
592 					|| extype == EXPR_OPTCONSTARRAYSIZE
593 					|| extype == EXPR_OPTCONSTSUBEXPR) {
594 					if (extype == EXPR_OPTCONSTINIT) {
595 						warningfl(t, "Variable "
596 						"initializers are not "
597 						"allowed in ISO C90");
598 					} else if (extype == EXPR_OPTCONSTARRAYSIZE) {
599 						warningfl(t, "Variable-"
600 						"size arrays are not "
601 						"allowed in ISO C90");
602 					} else { /* EXPR_OPTCONSTSUBEXPR */
603 						;
604 					}
605 				} else {
606 					errorfl(t,
607 						"Static variable value used "
608 						"in constant expression");
609 				}
610 				ret.not_constant = 1;
611 				ret.type = NULL;
612 				return ret;
613 			}
614 		} else {
615 			/* Address constant */
616 			ret.address = alloc_addr_const();
617 			ret.address->dec = d;
618 		}
619 	}
620 builtin_done:
621 	return ret;
622 }
623 
624 #endif /* #ifndef PREPROCESSOR */
625 
626 
627 static struct tyval
do_eval_const_expr(struct expr * tree,int extype,int is_paren_subex)628 do_eval_const_expr(struct expr *tree, int extype, int is_paren_subex) {
629 	struct tyval		ret;
630 	struct tyval		tmp1;
631 	struct tyval		tmp2;
632 	struct tyval		*tv;
633 	struct tyval		*left;
634 	struct tyval		*right;
635 	size_t			i;
636 	int			rc = 0;
637 	int			nullok = 1;
638 	int			member_addr_const = 0;
639 	static struct tyval	nulltv;
640 	struct vreg		*builtinvr = NULL;
641 
642 	ret = nulltv;
643 	tmp1 = nulltv;
644 	tmp2 = nulltv;
645 
646 
647 	if (tree->op == 0) {
648 #ifndef PREPROCESSOR
649 		static struct vreg	structvr;
650 #endif
651 		struct decl		*dp;
652 		int			is_address_const = 0;
653 		int			has_struct_op = 0;
654 
655 		if (tree->stmt_as_expr) {
656 			/*
657 			 * 07/07/08: This was missing; We always assumed this
658 			 * has to be a normal sub-expression. With our more
659 			 * aggressive constant expression evaluation, this
660 			 * issue came up. For now, treat all stmt-as-expr as
661 			 * not constant! (Hope this doesn't break a great
662 			 * deal)
663 			 * XXX !!
664 			 */
665 			ret.type = NULL;
666 			ret.not_constant = 1;
667 			return ret;
668 		} else if (tree->data->is_expr) {
669 			/*
670 			 * 07/14/08: Only set the is_paren_subex flag if there
671 			 * is only a single sub-expression! I.e. set it for
672 			 *
673 			 *    (x)
674 			 *
675 			 * but not
676 			 *
677 			 *    (x + y)
678 			 *
679 			 * ... since for all intents and purposes, the flag is
680 			 * only intended for the former case, to allow address
681 			 * constants
682 			 */
683 			ret = do_eval_const_expr(tree->data->is_expr,
684 				extype, /*1*/
685 				tree->data->is_expr->op == 0);
686 			if (ret.type == NULL) {
687 				return ret;
688 			}
689 #ifndef PREPROCESSOR
690 			if (ret.is_static_var != NULL) {
691 				/*
692 				 * 07/14/08: Perform address checking. This
693 				 * can only be done now because this is a
694 				 * parenthesized expression like
695 				 *
696 				 *    &(foo)
697 				 */
698 				ret = do_static_var(tree, ret, ret.is_static_var, &builtinvr, extype, is_paren_subex);
699 				if (ret.type == NULL) {
700 					return ret;
701 				}
702 			}
703 #endif
704 		} else if (tree->data->meat != NULL) {
705 			struct token	*t = tree->data->meat;
706 
707 			if (t->type == TOK_STRING_LITERAL) {
708 				ret.str = t->data;
709 				ret.type = ret.str->ty;
710 			} else if (t->type == TOK_IDENTIFIER) {
711 #ifdef PREPROCESSOR
712 				int     zero = 0;
713 
714 				/*
715 				 * All macro expansion has already been
716 				 * done earlier, so this identifier is
717 				 * not a macro, so it becomes the value
718 				 * 0
719 				 */
720 				ret.type = make_basic_type(TY_INT);
721 				ret.value = n_xmemdup(&zero, sizeof zero);
722 #else
723 				ret = do_static_var(tree, ret, t, &builtinvr, extype, is_paren_subex);
724 				if (ret.type == NULL) {
725 					return ret;
726 				}
727 #endif
728 #ifdef PREPROCESSOR
729                         } else if (t->type == TOK_DEFINED) {
730 				struct token    *tmp = t->data;
731 				int             val;
732 
733 				ret.type = make_basic_type(TY_INT);
734 				if (lookup_macro(tmp->data, 0, -1) != NULL) {
735 					val = 1;
736 				} else {
737 					val = 0;
738 				}
739 				ret.value = n_xmemdup(&val, sizeof val);
740 #endif
741 			} else {
742 				/* Must be constant */
743 				if (t->type == TOK_COMP_LITERAL) {
744 					/*
745 					 * 06/28/08: This was missing, so we passed TOK_COMP_LITERAL to
746 					 * make_basic_type()!
747 					 */
748 					struct comp_literal	*lit;
749 					lit = t->data;
750 					ret.type = n_xmemdup(lit->struct_type, sizeof *lit->struct_type);
751 				} else {
752 					ret.type = make_basic_type(t->type);
753 					ret.type = n_xmemdup(ret.type,
754 						sizeof *ret.type);
755 				}
756 
757 				if (t->type == TOK_COMP_LITERAL) {
758 					struct comp_literal	*lit;
759 
760 					lit = t->data;
761 					if (tree->data->operators[0] != NULL) {
762 						/*
763 						 * Don't handle things like
764 						 *
765 						 *   static struct *foo =
766 						 *     &(struct foo) {...};
767 						 *
768 						 * just yet
769 						 *
770 						 * 07/10/08: Our more aggressive
771 						 * const expr evaluation now
772 						 * requires this not to yield
773 						 * an error
774 						 */
775 					/*	unimpl();*/
776 
777 						ret.not_constant = 1;
778 						ret.type = NULL;
779 						return ret;
780 					}
781 					ret.static_init = lit->init;
782 				} else if (IS_FLOATING(ret.type->code)) {
783 					struct ty_float	*fc;
784 
785 					fc = t->data;
786 					ret.value = fc->num->value;
787 
788 					/*
789 					 * This constant is not needed
790 					 * in the fp list for fp memory
791 					 * access
792 					 *
793 					 * 02/03/09: This seems to be a
794 					 * little too optimistc. It will
795 					 * also execute in
796 					 *
797 					 *    const_float * non_const_int
798 					 *
799 					 * ... so when we fall back to
800 					 * executing the operation at
801 					 * runtime, the float constant has
802 					 * wrongly been removed
803 					 *
804 					 * XXX Where is the right place
805 					 * to put this?
806 					 */
807 #if 0
808 					remove_float_const_from_list(fc);
809 #endif
810 				} else {
811 					ret.value = t->data;
812 				}
813 #ifndef PREPROCESSOR
814 				ret.is_nullptr_const =
815 					is_nullptr_const(t, ret.type);
816 #endif
817 
818 			}
819 			ret.alloc = 0;
820 		} else if (tree->data->is_sizeof) {
821 #ifndef PREPROCESSOR
822 			struct vreg	*vr;
823 
824 			vr = tree->data->is_sizeof->data;
825 			ret.type = vr->type;
826 
827 			if (vr->from_const == NULL) {
828 				/*
829 				 * 07/12/08: This happens for VLAs
830 				 */
831 				if (extype == EXPR_OPTCONSTINIT
832 					|| extype == EXPR_OPTCONSTARRAYSIZE
833 					|| extype == EXPR_OPTCONSTSUBEXPR) {
834 					if (extype == EXPR_OPTCONSTINIT) {
835 					warningfl(tree->data->is_sizeof, "Variable "
836 						"initializers are not "
837 						"allowed in ISO C90");
838 					} else if (extype == EXPR_OPTCONSTARRAYSIZE) {
839 						warningfl(tree->tok, "Variable-"
840 						"size arrays are not "
841 						"allowed in ISO C90");
842 					} else { /* EXPR_OPTCONSTSUBEXPR */
843 						;
844 					}
845 				} else {
846 					errorfl(tree->data->is_sizeof,
847 						"Invalid non-constant "
848 						"sizeof");
849 				}
850 
851 				ret.not_constant = 1;
852 				ret.type = NULL;
853 				return ret;
854 			}
855 			ret.value = vr->from_const->data;
856 #endif /* #ifndef PREPROCESSOR */
857 		} else {
858 			abort();
859 		}
860 
861 		/* Now apply all unary/postfix/prefix operators */
862 		tv = &ret;
863 		if (builtinvr != NULL) {
864 			/*
865 			 * Meat of subexpression is builtin function -
866 			 * ignore first (function call) operator
867 			 */
868 			i = 1;
869 		} else {
870 			i = 0;
871 		}
872 		for (/*i = 0*/; tree->data->operators[i] != NULL; ++i) {
873 			struct token	*op;
874 			struct decl	*d;
875 			struct token	*ident;
876 			int		opval;
877 			int		was_nullptr_const = 0;
878 
879 			op = tree->data->operators[i];
880 
881 			if (op->type == TOK_PAREN_OPEN) {
882 				/*
883 				 * 07/14/08: Function call - cannot be constant
884 				 */
885 				if (extype == EXPR_OPTCONSTINIT
886 					|| extype == EXPR_OPTCONSTARRAYSIZE
887 					|| extype == EXPR_OPTCONSTSUBEXPR) {
888 					if (extype == EXPR_OPTCONSTINIT) {
889 					warningfl(op, "Variable "
890 						"initializers are not "
891 						"allowed in ISO C90");
892 					} else if (extype == EXPR_OPTCONSTARRAYSIZE) {
893 						warningfl(op, "Variable-"
894 						"size arrays are not "
895 						"allowed in ISO C90");
896 					} else { /* EXPR_OPTCONSTSUBEXPR */
897 						;
898 					}
899 				} else {
900 					errorfl(op, "Function call in constant expression");
901 				}
902 				ret.type = NULL;
903 				ret.not_constant = 1;
904 				return ret;
905 			}
906 
907 
908 			if (ret.value == NULL
909 				&& ret.address == NULL
910 				&& op->type != TOK_OP_CAST
911 				&& (op->type != TOK_OPERATOR
912 				|| *(int *)op->data !=TOK_OP_ADDR)
913 				/* 07/11/08: Union below was missing! */
914 				&& ( (ret.type->code != TY_STRUCT && ret.type->code != TY_UNION)
915 				|| (op->type != TOK_OP_STRUMEMB
916 					&& op->type != TOK_OP_STRUPMEMB))) {
917 
918 				if (extype == EXPR_OPTCONSTINIT
919 					|| extype == EXPR_OPTCONSTARRAYSIZE
920 					|| extype == EXPR_OPTCONSTSUBEXPR) {
921 					if (extype == EXPR_OPTCONSTINIT) {
922 					warningfl(op, "Variable "
923 						"initializers are not "
924 						"allowed in ISO C90");
925 					} else if (extype == EXPR_OPTCONSTARRAYSIZE) {
926 						warningfl(op, "Variable-"
927 						"size arrays are not "
928 						"allowed in ISO C90");
929 					} else { /* EXPR_OPTCONSTSUBEXPR */
930 						;
931 					}
932 				} else {
933 					errorfl(op, "Invalid use of operator in constant "
934 						"expression");
935 				}
936 				ret.not_constant = 1;
937 				ret.type = NULL;
938 				return ret;
939 			}
940 
941 			switch (op->type) {
942 			case TOK_OP_CAST:
943 #ifndef PREPROCESSOR
944 				d = op->data;
945 				if (tv->is_nullptr_const) {
946 					if (d->dtype->tlist != NULL
947 						&& d->dtype->tlist->type ==
948 						TN_POINTER_TO
949 						&& d->dtype->tlist->next
950 						== NULL
951 						&& d->dtype->code == TY_VOID) {
952 						/* Remains nullptr */
953 						;
954 					} else {
955 						tv->is_nullptr_const = 0;
956 
957 						/*
958 						 * 11/05/20: For nonsensical constant
959 						 * expressions such as
960 						 *    (char)((void *)0)
961 						 * which are used in some real life
962 						 * programs - record that the original
963 						 * value was a null pointer constant,
964 						 * such that the operation is
965 						 * possible as a no-op
966 						 */
967 						was_nullptr_const = 1;
968 					}
969 				} else {
970 					/*
971 					 * 07/12/08: The cast operation is only
972 					 * allowed if we have an arithmetic
973 					 * constant, or it's an address constant
974 					 * which is (nonsensically) cast to an
975 					 * integer type
976 					 */
977 					if (tv->value == NULL) {
978 						int	bad = 1;
979 
980 
981 						if (extype == EXPR_OPTCONSTINIT
982 							|| extype == EXPR_OPTCONSTARRAYSIZE) {
983 							if (extype == EXPR_OPTCONSTINIT) {
984 								warningfl(op, "Variable "
985 								"initializers are not "
986 								"allowed in ISO C90");
987 							} else {
988 								warningfl(op, "Variable-"
989 								"size arrays are not "
990 								"allowed in ISO C90");
991 							}
992 						} else if (extype == EXPR_OPTCONSTSUBEXPR) {
993 							;
994 						} else {
995 							if (tv->type->tlist != NULL
996 								&& d->dtype->tlist == NULL) {
997 								/*
998 								 * This must be something like
999 								 * (long)&addr (handled below)
1000 								 */
1001 								bad = 0;
1002 							} else if (tv->type->tlist != NULL
1003 								&& d->dtype->tlist != NULL) {
1004 								/*
1005 								 * Pointer to pointer can't do
1006 								 * any damage as far as const-
1007 								 * ness goes
1008 								 */
1009 								bad = 0;
1010 							} else {
1011 								errorfl(op, "Cast makes expression "
1012 									"non-constant");
1013 							}
1014 						}
1015 
1016 						if (bad) {
1017 							ret.not_constant = 1;
1018 							ret.type = NULL;
1019 							return ret;
1020 						}
1021 					}
1022 				}
1023 
1024 				if (d->dtype->code == TY_VOID && d->dtype->tlist == NULL) {
1025 					/*
1026 					 * 07/12/08: Cast to void; This cannot possibly be
1027 					 * a constant expression
1028 					 */
1029 					if (extype == EXPR_OPTCONSTSUBEXPR) {
1030 						;
1031 					} else {
1032 						errorfl(op, "Invalid void expression");
1033 					}
1034 					ret.not_constant = 1;
1035 					ret.type = NULL;
1036 					return ret;
1037 				}
1038 
1039 				if (d->dtype->tlist != NULL) {
1040 					if (tree->data->meat &&
1041 						tree->data->meat->type
1042 						== TOK_STRING_LITERAL) {
1043 						;
1044 					} else {
1045 #if 0
1046 						do_conv(tv, TY_ULONG); /* XXX */
1047 #endif
1048 						if (ret.type->tlist == NULL) {
1049 							if (ret.value != NULL) {
1050 								cross_do_conv(tv, TY_ULONG, 0); /* XXX */
1051 							} else if (ret.address != NULL) {
1052 								;
1053 							} else {
1054 								ret.type = NULL;
1055 								ret.not_constant = 1;
1056 								return ret;
1057 							}
1058 						tv->type = make_basic_type(
1059 							TY_ULONG);
1060 						tv->type = n_xmemdup(tv->type,
1061 							sizeof *tv->type);
1062 						}
1063 					}
1064 					ret.type = d->dtype;
1065 				} else {
1066 					if (tv->type->tlist != NULL) {
1067 						/*
1068 						 * Very dangerous! A pointer
1069 						 * cast to an integer as a
1070 						 * *constant* expression! This
1071 						 * only makes sense if source
1072 						 * and target are the same
1073 						 * size. We have to support
1074 						 * this for programs like
1075 						 * xterm
1076 						 */
1077 						size_t	dest_size =
1078 					backend->get_sizeof_type(d->dtype,0);
1079 						size_t	src_size =
1080 					backend->get_ptr_size();
1081 
1082 						if (src_size == dest_size) {
1083 							/*
1084 							 * 07/07/09: Only enable this
1085 							 * warning for mandatory constant
1086 							 * expressions
1087 							 *
1088 							 * XXX Doesn't work :-(
1089 							 *
1090 							 * OPTCONSTSUBEXPR is always used.
1091 							 * Clean this up
1092 							 */
1093 							if (extype == EXPR_CONST
1094 								|| extype == EXPR_CONSTINIT
1095 								|| extype == EXPR_OPTCONSTSUBEXPR) {
1096 								warningfl(op,
1097 			"Nonportable bogus cast of pointer to integer in "
1098 			"constant expression");
1099 							}
1100 						} else {
1101 							if (extype == EXPR_OPTCONSTINIT
1102 							|| extype == EXPR_OPTCONSTARRAYSIZE) {
1103 							if (extype == EXPR_OPTCONSTINIT) {
1104 							warningfl(op, "Variable "
1105 							"initializers are not "
1106 							"allowed in ISO C90");
1107 							} else if (extype ==
1108 						EXPR_OPTCONSTSUBEXPR) {
1109 								;
1110 							} else {
1111 							warningfl(op, "Variable-"
1112 							"size arrays are not "
1113 							"allowed in ISO C90");
1114 							}
1115 							ret.not_constant = 1;
1116 							ret.type = NULL;
1117 							return ret;
1118 							} else {
1119 								/*
1120 								 * 11/05/20: Support this construct for
1121 								 * null pointer constants with a warning,
1122 								 * for apps like PostgreSQL
1123 								 */
1124 								(was_nullptr_const? warningfl: errorfl) (op,
1125 			"Invalid bogus cast of pointer to integer in "
1126 			"constant expression");
1127 							}
1128 						}
1129 
1130 						/*
1131 						 * BEWARE!!! We keep the type as
1132 						 * ``pointer'' because the backend
1133 						 * otherwise gets confused and
1134 						 * thinks this really is a long. Hm
1135 						 *
1136 						 * 08/18/07 If it is an array, we
1137 						 * change the type to pointer
1138 						 * because otherwise the backends
1139 						 * do not understand this kludged
1140 						 * initializer
1141 						 */
1142 						if (tv->type->tlist->type ==
1143 							TN_ARRAY_OF) {
1144 							tv->type =
1145 								dup_type(tv->type);
1146 							tv->type->tlist->type =
1147 								TN_POINTER_TO;
1148 						}
1149 						tv->type = d->dtype;
1150 					} else {
1151 						cross_do_conv(tv,
1152 							d->dtype->code, 0);
1153 						ret.type = d->dtype;
1154 					}
1155 				}
1156 				if (ret.type->code == TY_ENUM
1157 					&& ret.type->tlist == NULL) {
1158 					/* XXX is this really desirable? */
1159 					ret.type = n_xmemdup(make_basic_type(TY_INT),
1160 						sizeof(struct type));
1161 				}
1162 #endif
1163 				break;
1164 			case TOK_ARRAY_OPEN:
1165 #ifndef PREPROCESSOR
1166 #if 0
1167 				if (ret.address != NULL
1168 					&& (op=tree->data->operators[i+1])
1169 						!= NULL
1170 					&& op->type == TOK_OPERATOR
1171 					&& *(int *)op->data == TOK_OP_ADDR) {
1172 #endif
1173 				{
1174 					/* make &foo[x] work */
1175 					struct expr	*ex
1176 						= tree->data->operators[ i /*++ */]->
1177 						data;
1178 
1179 					if (eval_const_expr(ex, extype,
1180 						&ret.not_constant) != 0) {
1181 						ret.type = NULL;
1182 						return ret;
1183 					}
1184 
1185 					{
1186 						/*
1187 						 * 12/23/08: Create a copy of the value
1188 						 * because it may be associated with a
1189 						 * token, e.g. in
1190 						 *
1191 						 *    &a[0]
1192 						 *
1193 						 * addr_add_sub() will convert the index
1194 						 * to type size_t. If it turns out that
1195 						 * we really aren't dealing with a constant
1196 						 * expression, then it will have to be
1197 						 * reevaluated. And if a token has type
1198 						 * ``int'' set but the value was converted
1199 						 * to size_t, things would break.
1200 						 */
1201 						void *p = zalloc_buf(Z_CEXPR_BUF);  /*n_xmalloc(16);*/ /* XXX */
1202 						memcpy(p, ex->const_value->value, 16);
1203 						ex->const_value->value = p;
1204 					}
1205 
1206 					addr_add_sub(&ret, ex, tv->type,
1207 						TOK_OP_PLUS);
1208 					ret.type = dup_type(ret.type);
1209 					ret.type->tlist = ret.type->tlist->next;
1210 					if (member_addr_const) is_address_const = 0; /* XXX 2011 - ok? */
1211 				}
1212 #endif
1213 
1214 				break;
1215 			case TOK_PAREN_OPEN:
1216 				/* Must be function call operator */
1217 #ifndef PREPROCESSOR
1218 				if (extype == EXPR_OPTCONSTINIT
1219 					|| extype == EXPR_OPTCONSTARRAYSIZE) {
1220 					if (extype == EXPR_OPTCONSTINIT) {
1221 						warningfl(op, "Variable "
1222 						"initializers are not "
1223 						"allowed in ISO C90");
1224 					} else {
1225 						warningfl(op, "Variable-"
1226 						"size arrays are not "
1227 						"allowed in ISO C90");
1228 					}
1229 					ret.not_constant = 1;
1230 				} else if (extype == EXPR_OPTCONSTSUBEXPR) {
1231 					ret.not_constant = 1;
1232 				} else {
1233 					errorfl(op, "Invalid function call "
1234 					"in constant expression");
1235 				}
1236 				ret.type = NULL;
1237 				return ret;
1238 #endif
1239 				break;
1240 			case TOK_OP_STRUMEMB: /* XXX !??why not TOK_OPERATOR */
1241 			case TOK_OP_STRUPMEMB:
1242 #ifndef PREPROCESSOR
1243 				if (ret.type == NULL
1244 					|| ((ret.type->code != TY_STRUCT
1245 					&& ret.type->code != TY_UNION)
1246 					 /* || ret.type->tlist != NULL */  )) {
1247 					errorfl(tree->data->operators[i],
1248 						"Incorrect type for "
1249 						"operator `%s'",
1250 						tree->data->operators[i]->ascii);
1251 					ret.type = NULL;
1252 					return ret;
1253 				}
1254 
1255 				ident = op->data;
1256 				if ((dp = access_symbol(ret.type->tstruc->
1257 					scope, ident->data, 0)) == NULL) {
1258 					errorfl(tree->data->operators[i],
1259 						"Unknown structure member "
1260 						"`%s'", ident->data);
1261 					ret.type = NULL;
1262 					return ret;
1263 				}
1264 				/*
1265 				 * 04/25/11: Handle address constants better
1266 				 * (probably still not flawlessly). Previously
1267 				 * we've mostly been looking for the & operator
1268 				 * to determine whether something is an address
1269 				 * constant (all of this const-expr evaluation
1270 				 * stuff is really weak). This breaks down for
1271 				 * static array struct members;
1272 				 *
1273 				 *    static struct {
1274 				 *       char buf[128];
1275 				 *    } s;
1276 				 *    static char *p = s.buf;  // this err'ed
1277 				 *
1278 				 * So, upon encountering a struct member, we
1279 				 * check this. Hopefully this doesn't break
1280 				 * anything
1281 				 */
1282 				if (dp->dtype->tlist != NULL
1283 					&& dp->dtype->tlist->type == TN_ARRAY_OF) {
1284 					is_address_const = member_addr_const = 1;
1285 				}
1286 
1287 
1288 
1289 				/*
1290 				 * XXX this is quite ad-hocly kludged to make
1291 				 * nwcc work with the gtar source... it does
1292 				 * not understand named address constants
1293 				 * yet and is generally incomplete
1294 				 */
1295 				if (ret.value) {
1296 					static struct vreg	parentvr;
1297 
1298 					/*
1299 					 * 07/09/08: This was missing; If we
1300 					 * change the original value, then
1301 					 * we can't fall back to a non-const
1302 					 * evaluation in case the expression
1303 					 * isn't really constant
1304 					 */
1305 					void	*orig_value = ret.value;
1306 					ret.value = zalloc_buf(Z_CEXPR_BUF); /*n_xmalloc(16);*/ /* XXX */
1307 					memcpy(ret.value, orig_value, 16);
1308 
1309 					parentvr.type = ret.type;
1310 					structvr.parent = &parentvr;
1311 					structvr.memberdecl = dp;
1312 					*(long *)ret.value += calc_offsets(&structvr);
1313 				} else if (ret.address != NULL) {
1314 					static struct vreg	parentvr;
1315 
1316 					parentvr.type = ret.type;
1317 					structvr.parent = &parentvr;
1318 					structvr.memberdecl = dp;
1319 					ret.address->diff +=
1320 						calc_offsets(&structvr);
1321 				} else {
1322 					/*unimpl();*/
1323 					/*
1324 					 * 07/11/08: XXX Compound literals have
1325 					 * static_init set but nothing else.
1326 					 * That should probably be supported
1327 					 * too
1328 					 */
1329 					ret.not_constant = 1;
1330 					ret.type = NULL;
1331 					return ret;
1332 				}
1333 				ret.type = dp->dtype;
1334 				has_struct_op = 1;
1335 #endif
1336 				break;
1337 			case TOK_OPERATOR:
1338 				opval = *(int *)op->data;
1339 				if (opval == TOK_OP_ADDR) {
1340 #ifndef PREPROCESSOR
1341 					is_address_const = 1;
1342 					if (i == 0) {
1343 						; /* already taken care of */
1344 					} else {
1345 					}
1346 					/* XXX this sucks */
1347 					ret.type =
1348 						addrofify_type
1349 						(ret.type);
1350 #endif
1351 				} else if (opval == TOK_OP_LNEG
1352 					|| opval == TOK_OP_BNEG
1353 					|| opval == TOK_OP_UPLUS
1354 					|| opval == TOK_OP_UMINUS) {
1355 					int	oldtype = op->type; /* XXX needed? */
1356 					static struct tyval	tytmp;
1357 
1358 					if (tv->value == NULL) {
1359 						/*
1360 						 * 07/12/08: These operators
1361 						 * can only be applied to
1362 						 * arithmetic constants. If
1363 						 * this is an address/static
1364 						 * variable instead, it can't
1365 						 * be constant
1366 						 */
1367 						if (extype == EXPR_OPTCONSTINIT
1368 							|| extype == EXPR_OPTCONSTARRAYSIZE
1369 							|| extype == EXPR_OPTCONSTSUBEXPR) {
1370 							if (extype == EXPR_OPTCONSTINIT) {
1371 								warningfl(op, "Variable "
1372 								"initializers are not "
1373 								"allowed in ISO C90");
1374 							} else if (extype == EXPR_OPTCONSTARRAYSIZE) {
1375 								warningfl(op, "Variable-"
1376 								"size arrays are not "
1377 								"allowed in ISO C90");
1378 							}
1379 						} else {
1380 							errorfl(op, "Invalid use of `%s' operator "
1381 								"in constant expression",
1382 								op->ascii);
1383 						}
1384 						ret.not_constant = 1;
1385 						ret.type = NULL;
1386 						return ret;
1387 					}
1388 
1389 					op->type = opval;
1390 					if (opval == TOK_OP_LNEG
1391 						&& tv->is_nullptr_const) {
1392 						/*
1393 						 * 03/03/09: Very important null
1394 						 * pointer negation feature -
1395 						 * !((void *)0)
1396 						 * needed by emacs!!
1397 						 */
1398 						tytmp.value = zalloc_buf(Z_CEXPR_BUF); /*n_xmalloc(16);*/ /* XXX */
1399 						tytmp.type = tv->type;
1400 						if (tv->type->code < TY_INT) {
1401 							tv->type = n_xmemdup(
1402 								make_basic_type(TY_INT),
1403 								sizeof(struct type));
1404 						}
1405 						*(int *)tytmp.value = 1;
1406 					} else {
1407 						cross_exec_op(op, &tytmp, tv, NULL);
1408 					}
1409 					op->type = oldtype;
1410 					*tv = tytmp;
1411 				} else if (opval == TOK_OP_DEREF) {
1412 					if (member_addr_const) is_address_const = 0; /* XXX 2011 - ok? */
1413 					if (extype == EXPR_OPTCONSTINIT
1414 						|| extype == EXPR_OPTCONSTARRAYSIZE) {
1415 						if (extype == EXPR_OPTCONSTINIT) {
1416 							warningfl(op, "Variable "
1417 							"initializers are not "
1418 							"allowed in ISO C90");
1419 						} else {
1420 							warningfl(op, "Variable-"
1421 							"size arrays are not "
1422 							"allowed in ISO C90");
1423 						}
1424 						ret.not_constant = 1;
1425 					} else if (extype == EXPR_OPTCONSTSUBEXPR) {
1426 						;
1427 					}
1428 					ret.type = NULL;
1429 					return ret;
1430 				} else if (opval == TOK_OP_INCPRE
1431 					|| opval == TOK_OP_INCPOST
1432 					|| opval == TOK_OP_DECPRE
1433 					|| opval == TOK_OP_DECPOST) {
1434 					/*
1435 					 * 07/12/08: Allow these operators
1436 					 */
1437 					ret.not_constant = 1;
1438 					ret.type = NULL;
1439 					return ret;
1440 				} else {
1441 					printf("unknown operator %d\n",
1442 						opval);
1443 					abort();
1444 				}
1445 				break;
1446 			case TOK_KEY_SIZEOF:
1447 			case TOK_KEY_ALIGNOF:
1448 				; /* taken care of already */
1449 				break;
1450 			case TOK_OP_ADDRLABEL:
1451 #ifndef PREPROCESSOR
1452 				if (i == 0
1453 					&& ret.address != NULL
1454 					&& ret.address->labeltok != NULL) {
1455 					/* OK - &&label */
1456 					;
1457 				} else {
1458 					errorfl(op, "Invalid use of operator "
1459 						"`%s'", op->ascii);
1460 				}
1461 #endif
1462 				break;
1463 			default:
1464 				printf("unknown operator %d\n", op->type);
1465 				unimpl();
1466 			}
1467 		}
1468 
1469 		/*
1470 		 * 06/01/08: Now that all unary operators have been applied,
1471 		 * do sanity checking; If the ``meat'' of this sub-expression
1472 		 * is a static variable, it is only allowed to be used as an
1473 		 * address constant!
1474 		 *
1475 		 * Note that we cannot do this here yet if we're inside of a
1476 		 * parenthesized sub-expression such as;
1477 		 *
1478 		 *    &(foo)
1479 		 *
1480 		 * ... where the outer (not visible at this point) address-of
1481 		 * operator makes it valid. Thus the caller has to do it
1482 		 */
1483 		if ( (ret.is_static_var
1484 			&& !is_address_const
1485 			&& !is_paren_subex)
1486 			/*
1487 			 * 07/22/08: Disallow    foo.bar   and  foo->bar
1488 			 * without address-of operator
1489 			 */
1490 			|| (ret.address
1491 			&& has_struct_op
1492 			&& !is_address_const) ) {
1493 			/* Cannot be constant */
1494 			if (extype == EXPR_OPTCONSTINIT
1495 				|| extype == EXPR_OPTCONSTARRAYSIZE) {
1496 				if (extype == EXPR_OPTCONSTINIT) {
1497 					warningfl(ret.is_static_var, "Variable "
1498 					"initializers are not "
1499 					"allowed in ISO C90");
1500 				} else {
1501 					warningfl(ret.is_static_var, "Variable-"
1502 					"size arrays are not "
1503 					"allowed in ISO C90");
1504 				}
1505 				ret.not_constant = 1;
1506 			} else if (extype == EXPR_OPTCONSTSUBEXPR) {
1507 				ret.not_constant = 1;
1508 			} else {
1509 				errorfl(ret.is_static_var, "Invalid use of static "
1510 					"variable in constant "
1511 					"expression");
1512 			}
1513 			ret.type = NULL;
1514 			return ret;
1515 		} else if (ret.is_static_var && is_address_const) {
1516 			/*
1517 			 * This is a static variable which is correctly used
1518 			 * as an address constant; We can remove the static
1519 			 * marker (otherwise   (&foo)  breaks when the outer
1520 			 * call around the nested sub-expression reevaluates
1521 			 * the static setting)
1522 			 */
1523 			ret.is_static_var = NULL;
1524 		}
1525 
1526 		return ret;
1527 	}
1528 
1529 	/*
1530 	 * 07/22/08: Don't set is_paren_subex flag, since for all intents and
1531 	 * purposes
1532 	 *
1533 	 *     (foo op bar)
1534 	 *
1535 	 * ... is not constant if foo or bar is not constant. The flag is only
1536 	 * intended to make
1537 	 *
1538 	 *     &(foo)
1539 	 *
1540 	 * work
1541 	 */
1542 	tmp1 = do_eval_const_expr(tree->left, extype, 0 /*is_paren_subex*/);
1543 	if (tmp1.type == NULL) {
1544 		return tmp1;
1545 	}
1546 
1547 	if (tree->op == TOK_OP_LAND) {
1548 		int	res = 0;
1549 		int	not_zero = 0;
1550 
1551 		/*
1552 		 * 07/21/08: Handle address constants
1553 		 */
1554 		if (tmp1.address != NULL) {
1555 			if (tmp1.address->diff == 0) {
1556 				/*
1557 				 * OK - &static_var or &&label is definitely
1558 				 * nonzero
1559 				 */
1560 				not_zero = 1;
1561 			} else {
1562 				/*
1563 				 * &addr +/- offset may be zero (by invoking
1564 				 * undefined behavior, but it's a possibility
1565 				 * nonetheless) - wait until runtime to find
1566 				 * out
1567 				 */
1568 				ret.type = NULL;
1569 				ret.not_constant = 1;
1570 				return ret;
1571 			}
1572 		} else if (const_value_is_nonzero(&tmp1)) {
1573 			not_zero = 1;
1574 		}
1575 
1576 		if (not_zero) {
1577 			/*
1578 			 * 07/22/08: Don't set is_paren_subex flag, since for all intents and
1579 			 * purposes
1580 			 *
1581 			 *     (foo op bar)
1582 			 *
1583 			 * ... is not constant if foo or bar is not constant. The flag is only
1584 			 * intended to make
1585 			 *
1586 			 *     &(foo)
1587 			 *
1588 			 * work
1589 			 */
1590 			tmp2 = do_eval_const_expr(tree->right, extype,
1591 					0 /*is_paren_subex*/);
1592 			if (tmp2.type == NULL) {
1593 				/* 07/15/08: This was missing */
1594 				return tmp2;
1595 			}
1596 
1597 			/*
1598 			 * 07/21/08: Handle address constants
1599 			 */
1600 			if (tmp2.address != NULL) {
1601 				if (tmp2.address->diff == 0) {
1602 					/*
1603 					 * OK - &static_var or &&label is definitely
1604 					 * nonzero
1605 					 */
1606 					res = 1;
1607 				} else {
1608 						/*
1609 					 * &addr +/- offset may be zero (by invoking
1610 					 * undefined behavior, but it's a possibility
1611 					 * nonetheless) - wait until runtime to find
1612 					 * out
1613 					 */
1614 					ret.type = NULL;
1615 					ret.not_constant = 1;
1616 					return ret;
1617 				}
1618 			} else if (const_value_is_nonzero(&tmp2)) {
1619 				res = 1;
1620 			}
1621 
1622 
1623 #if 0
1624 			if (const_value_is_nonzero(&tmp2)) {
1625 				res = 1;
1626 			}
1627 #endif
1628 		}
1629 		ret.type = make_basic_type(TY_INT);
1630 		ret.type = n_xmemdup(ret.type, sizeof *ret.type);
1631 		ret.value = n_xmemdup(&res, sizeof res);
1632 		goto out;
1633 	} else if (tree->op == TOK_OP_LOR) {
1634 		int	res = 0;
1635 		int	not_zero = 0;
1636 
1637 
1638 		/*
1639 		 * 07/21/08: Handle address constants
1640 		 */
1641 		if (tmp1.address != NULL) {
1642 			if (tmp1.address->diff == 0) {
1643 				/*
1644 				 * OK - &static_var or &&label is definitely
1645 				 * nonzero
1646 				 */
1647 				not_zero = 1;
1648 			} else {
1649 					/*
1650 				 * &addr +/- offset may be zero (by invoking
1651 				 * undefined behavior, but it's a possibility
1652 				 * nonetheless) - wait until runtime to find
1653 				 * out
1654 				 */
1655 				ret.type = NULL;
1656 				ret.not_constant = 1;
1657 				return ret;
1658 			}
1659 		} else if (const_value_is_nonzero(&tmp1)) {
1660 			not_zero = 1;
1661 		}
1662 
1663 		if (/*!const_value_is_nonzero(&tmp1)*/  !not_zero) {
1664 			/*
1665 			 * 07/22/08: Don't set is_paren_subex flag, since for all intents and
1666 			 * purposes
1667 			 *
1668 			 *     (foo op bar)
1669 			 *
1670 			 * ... is not constant if foo or bar is not constant. The flag is only
1671 			 * intended to make
1672 			 *
1673 			 *     &(foo)
1674 			 *
1675 			 * work
1676 			 */
1677 			tmp2 = do_eval_const_expr(tree->right, extype,
1678 				0 /*is_paren_subex*/);
1679 			if (tmp2.type == NULL) {
1680 				/* 07/17/08: Missing! */
1681 				return tmp2;
1682 			}
1683 
1684 
1685 #if 0
1686 			if (const_value_is_nonzero(&tmp2)) {
1687 				res = 1;
1688 			}
1689 #endif
1690 			/*
1691 			 * 07/21/08: Handle address constants
1692 			 */
1693 			if (tmp2.address != NULL) {
1694 				if (tmp2.address->diff == 0) {
1695 					/*
1696 					 * OK - &static_var or &&label is definitely
1697 					 * nonzero
1698 					 */
1699 					res = 1;
1700 				} else {
1701 						/*
1702 					 * &addr +/- offset may be zero (by invoking
1703 					 * undefined behavior, but it's a possibility
1704 					 * nonetheless) - wait until runtime to find
1705 					 * out
1706 					 */
1707 					ret.type = NULL;
1708 					ret.not_constant = 1;
1709 					return ret;
1710 				}
1711 			} else if (const_value_is_nonzero(&tmp2)) {
1712 				res = 1;
1713 			}
1714 		} else {
1715 			res = 1;
1716 		}
1717 		ret.type = make_basic_type(TY_INT);
1718 		ret.type = n_xmemdup(ret.type, sizeof *ret.type);
1719 		ret.value = n_xmemdup(&res, sizeof res);
1720 		goto out;
1721 	} else if (tree->op != TOK_OP_COND) {
1722 		/* XXX broken */
1723 		/*
1724 		 * 07/22/08: Don't set is_paren_subex flag, since for all intents and
1725 		 * purposes
1726 		 *
1727 		 *     (foo op bar)
1728 		 *
1729 		 * ... is not constant if foo or bar is not constant. The flag is only
1730 		 * intended to make
1731 		 *
1732 		 *     &(foo)
1733 		 *
1734 		 * work
1735 		 */
1736 		tmp2 = do_eval_const_expr(tree->right, extype, 0 /*is_paren_subex*/);
1737 		nullok = 0;
1738 	} else {
1739 		/* Is TOK_OP_COND */
1740 		int	not_zero = 0;
1741 
1742 		if (tree->right->op != TOK_OP_COND2) {
1743 			errorfl(tree->right->tok,
1744 				"Parse error - expected second part "
1745 				"of conditional operator");
1746 			ret.type = NULL;
1747 			return ret;
1748 		}
1749 
1750 
1751 		/*
1752 		 * 07/21/08: Handle address constants
1753 		 */
1754 		if (tmp1.address != NULL) {
1755 			if (tmp1.address->diff == 0) {
1756 				/*
1757 				 * OK - &static_var or &&label is definitely
1758 				 * nonzero
1759 				 */
1760 				not_zero = 1;
1761 			} else {
1762 					/*
1763 				 * &addr +/- offset may be zero (by invoking
1764 				 * undefined behavior, but it's a possibility
1765 				 * nonetheless) - wait until runtime to find
1766 				 * out
1767 				 */
1768 				ret.type = NULL;
1769 				ret.not_constant = 1;
1770 				return ret;
1771 			}
1772 		} else if (const_value_is_nonzero(&tmp1)) {
1773 			not_zero = 1;
1774 		}
1775 
1776 		/*
1777 		 * 07/22/08: Don't set is_paren_subex flag, since for all intents and
1778 		 * purposes
1779 		 *
1780 		 *     (foo op bar)
1781 		 *
1782 		 * ... is not constant if foo or bar is not constant. The flag is only
1783 		 * intended to make
1784 		 *
1785 		 *     &(foo)
1786 		 *
1787 		 * work
1788 		 */
1789 		if (/*const_value_is_nonzero(&tmp1)*/ not_zero) {
1790 			tmp2 = do_eval_const_expr(tree->right->left, extype,
1791 					/*is_paren_subex*/0);
1792 		} else {
1793 			tmp2 = do_eval_const_expr(tree->right->right, extype,
1794 					/*is_paren_subex*/0);
1795 		}
1796 		if (tmp2.type == NULL) {
1797 			return ret;
1798 		}
1799 		if (tmp2.type->code < TY_INT) {
1800 			/*
1801 			 * XXX we also need some typechecking ... And
1802 			 * usual arithmetic conversions!!! E.g.
1803 			 * foo < bar? 0ll: 0;
1804 			 * ... should convert 0 to 0ll
1805 			 */
1806 			cross_do_conv(&tmp2, TY_INT, 1);
1807 		}
1808 		ret.type = tmp2.type;
1809 		ret.value = tmp2.value;
1810 		goto out;
1811 	}
1812 
1813 	tv = &ret;
1814 	left = &tmp1;
1815 	right = &tmp2;
1816 
1817 	/*
1818 	 * 07/17/08: Do things below for all pointer types, including
1819 	 * constant values like (char *)0x835353, i.e. don't demand
1820 	 * the address member being non-null
1821 	 */
1822 #ifndef PREPROCESSOR
1823 	if (tmp1.type != NULL && tmp2.type != NULL
1824 		&& (tmp1.type->tlist != NULL || tmp2.type->tlist != NULL)
1825 	/*	&& (tmp1.address != NULL || tmp2.address != NULL)*/
1826 		&& tree->op != TOK_OP_COMMA) { /* 06/01/08: Added this */
1827 
1828 		int	err = 0;
1829 
1830 		/*
1831 		 * XXX we need more typechecking
1832 		 */
1833 		if (tree->op == TOK_OP_PLUS
1834 			|| tree->op == TOK_OP_MINUS) {
1835 			static struct expr	dum;
1836 			int			op = tree->op;
1837 
1838 			/* Must be addr + integer */
1839 			if (tmp1.address == NULL && tmp2.address != NULL) {
1840 				dum.const_value = &tmp1;
1841 				addr_add_sub(&tmp2, &dum,
1842 					tmp2.type,
1843 					op);
1844 				return tmp2;
1845 			} else if (tmp2.address == NULL && tmp1.address != NULL) {
1846 				dum.const_value = &tmp2;
1847 				addr_add_sub(&tmp1, &dum,
1848 					tmp1.type,
1849 					op);
1850 				return tmp1;
1851 			} else {
1852 				/*
1853 				 * Both are pointers! Only valid for
1854 				 * minus
1855 				 */
1856 				if (tree->op != TOK_OP_MINUS) {
1857 					err = 1;
1858 				} else {
1859 					long	diff;
1860 
1861 					if (calc_const_addr_diff(&tmp1, &tmp2,
1862 						&diff) != 0) {
1863 						if (extype == EXPR_OPTCONSTINIT
1864 							|| extype == EXPR_OPTCONSTARRAYSIZE) {
1865 							if (extype == EXPR_OPTCONSTINIT) {
1866 								warningfl(tree->tok, "Variable "
1867 								"initializers are not "
1868 								"allowed in ISO C90");
1869 							} else {
1870 								warningfl(tree->tok, "Variable-"
1871 								"size arrays are not "
1872 								"allowed in ISO C90");
1873 							}
1874 							ret.not_constant = 1;
1875 							ret.type = NULL;
1876 							return ret;
1877 						} else if (extype == EXPR_OPTCONSTSUBEXPR) {
1878 							ret.not_constant = 1;
1879 							ret.type = NULL;
1880 							return ret;
1881 						}
1882 						errorfl(tree->tok, "Invalid "
1883 						"use of `-' operator "
1884 						"on distinct object addresses");
1885 						err = 1;
1886 					} else {
1887 						ret.value = zalloc_buf(Z_CEXPR_BUF); /*n_xmalloc(16);*/ /* XXX */
1888 						/* XXXXX cross, this sucks! */
1889 						*(int *)ret.value = (int)diff;
1890 						ret.address = NULL;
1891 						ret.str = NULL;
1892 						ret.struct_member = NULL;
1893 						/* XXXX use ptrdiff_t */
1894 						ret.type = n_xmemdup(
1895 							make_basic_type(TY_INT),
1896 							sizeof(struct type));
1897 						cross_do_conv(&ret,
1898 							TY_LONG, 1);
1899 						return ret;
1900 					}
1901 				}
1902 			}
1903 		} else if ( (tmp1.address && tmp2.address)
1904 			|| (tmp1.value && tmp2.value) ) {
1905 			long	diff;
1906 
1907 			if (calc_const_addr_diff(&tmp1, &tmp2,
1908 				&diff) != 0) {
1909 				errorfl(tree->tok, "Invalid "
1910 				"use of `%s' operator "
1911 				"on distinct object addresses",
1912 				tree->tok->ascii);
1913 			} else {
1914 				int	result;
1915 
1916 				ret.value = zalloc_buf(Z_CEXPR_BUF); /*n_xmalloc(16);*/ /* XXXXXX */
1917 
1918 				/*
1919 				 * Must be relational or equality operator
1920 				 */
1921 				switch (tree->op) {
1922 				case TOK_OP_LEQU:
1923 					result = diff == 0;
1924 					break;
1925 				case TOK_OP_LNEQU:
1926 					result = diff != 0;
1927 					break;
1928 				case TOK_OP_GREAT:
1929 					result = diff > 0;
1930 					break;
1931 				case TOK_OP_SMALL:
1932 					result = diff < 0;
1933 					break;
1934 				case TOK_OP_GREATEQ:
1935 					result = diff >= 0;
1936 					break;
1937 				case TOK_OP_SMALLEQ:
1938 					result = diff <= 0;
1939 					break;
1940 				default:
1941 					err = 1;
1942 				}
1943 				if (!err) {
1944 					/* XXXXXXXXXXX cross */
1945 					*(int *)ret.value = result;
1946 					ret.type = n_xmemdup(
1947 						make_basic_type(TY_INT),
1948 						sizeof(struct type));
1949 					return ret;
1950 				}
1951 			}
1952 		} else {
1953 			/*
1954 			 * 07/17/08: If we have two address constants, and one is
1955 			 * bound to an object and the other is a constant value,
1956 			 * then a comparison cannot meaningfully be made at compile
1957 			 * time, so the expression is not constant.
1958 			 * E.g. in
1959 			 *
1960 			 *    &foo == (void *)0x....)
1961 			 *
1962 			 * ... even if foo is static, we cannot tell whether both
1963 			 * values are the same
1964 			 */
1965 			if (tmp1.type->tlist != NULL && tmp2.type->tlist != NULL
1966 				&& compare_types(tmp1.type, tmp2.type, CMPTY_ARRAYPTR|CMPTY_ALL) == 0) {
1967 				if (extype == EXPR_OPTCONSTINIT
1968 					|| extype == EXPR_OPTCONSTARRAYSIZE) {
1969 					if (extype == EXPR_OPTCONSTINIT) {
1970 						warningfl(tree->tok, "Variable "
1971 						"initializers are not "
1972 						"allowed in ISO C90");
1973 					} else {
1974 						warningfl(tree->tok, "Variable-"
1975 						"size arrays are not "
1976 						"allowed in ISO C90");
1977 					}
1978 				} else if (extype == EXPR_OPTCONSTSUBEXPR) {
1979 					;
1980 				} else {
1981 					errorfl(tree->tok, "Expression not constant");
1982 				}
1983 				ret.type = NULL;
1984 				ret.not_constant = 1;
1985 				return ret;
1986 			} else {
1987 				/*
1988 				 * Pointer type with arithmetic type, and not
1989 				 * using plus or minus - not allowed
1990 				 *
1991 				 * 02/24/09: Handle null pointer constants
1992 			 	 */
1993 				if (tmp1.type->tlist != NULL && tmp2.is_nullptr_const) {
1994 					;
1995 				} else if (tmp2.type->tlist != NULL && tmp1.is_nullptr_const) {
1996 					;
1997 				} else {
1998 					err = 1;
1999 				}
2000 				if (!err) {
2001 					/* XXX We should evaluate here */
2002 					ret.type = NULL;
2003 					ret.not_constant = 1;
2004 					return ret;
2005 				}
2006 			}
2007 		}
2008 
2009 		if (err) {
2010 			/*
2011 			 * 05/31/09: This fails for e.g.
2012 			 *
2013 			 *     (int *)0 + 123
2014 			 *
2015 			 * Instead of evaluating it as a constant, we use the
2016 			 * workaround of treating it as nonconstant for now.
2017 			 * This fixes at least those cases where it is not
2018 			 * required to be treated as a constant expression
2019 			 * (e.g. in Perl source)
2020 			 * XXX Fix this the right way
2021 			 */
2022 			if (extype == EXPR_OPTCONSTINIT
2023 				|| extype == EXPR_OPTCONSTARRAYSIZE) {
2024 				if (extype == EXPR_OPTCONSTINIT) {
2025 					warningfl(tree->tok, "Variable "
2026 					"initializers are not "
2027 					"allowed in ISO C90");
2028 				} else {
2029 					warningfl(tree->tok, "Variable-"
2030 				"size arrays are not "
2031 					"allowed in ISO C90");
2032 				}
2033 			} else if (extype == EXPR_OPTCONSTSUBEXPR) {
2034 				;
2035 			} else {
2036 				errorfl(tree->tok, "Expression not constant");
2037 			}
2038 			ret.type = NULL;
2039 			ret.not_constant = 1;
2040 			return ret;
2041 #if 0
2042 			errorfl(tree->tok, "Incompatible types in expression");
2043 			ret.type = NULL;
2044 			return ret;
2045 #endif
2046 		}
2047 	}
2048 #endif /* #ifndef PREPROCESSOR */
2049 
2050 	if (tmp1.type == NULL
2051 		|| (!nullok && tmp2.type == NULL)
2052 		/*|| (!nullok && (rc = cross_convert_tyval(&tmp1, &tmp2, NULL)) != 0)*/) {
2053 		ret.type = NULL;
2054 		ret.value = NULL;
2055 		ret.not_constant = tmp1.not_constant || tmp2.not_constant;
2056 		if (rc != 0) {
2057 			errorfl(tree->tok, "Incompatible types in expression");
2058 			ret.type = NULL;
2059 			return ret;
2060 		}
2061 		return ret;
2062 	}
2063 
2064 	/*
2065 	 * 08/05/08: Only perform usual arithmetic conversions if the used
2066 	 * operator does in fact require this! (It used to be done
2067 	 * unconditionally, eg. in foo << bar, where the type of bar should
2068 	 * not affect foo)
2069 	 */
2070 	if (!nullok) {
2071 		if (tree->op == TOK_OP_COMMA
2072 			|| tree->op == TOK_OP_BSHL
2073 			|| tree->op == TOK_OP_BSHR
2074 			|| tree->op == TOK_OP_LAND
2075 			|| tree->op == TOK_OP_LOR) {
2076 			/*
2077 			 * Does not need usual arithmetic conversion
2078 			 */
2079 			if (tree->op == TOK_OP_BSHL
2080 				|| tree->op == TOK_OP_BSHR) {
2081 				/* Promote for shift */
2082 				if (tmp1.type->code < TY_INT) {
2083 					cross_do_conv(&tmp1, TY_INT, 1);
2084 				}
2085 			}
2086 		} else {
2087 			/* Needs usual arithmetic conversion */
2088 			if (cross_convert_tyval(&tmp1, &tmp2, NULL) != 0) {
2089 				errorfl(tree->tok, "Incompatible types in expression");
2090 				ret.type = NULL;
2091 				return ret;
2092 			}
2093 		}
2094 	}
2095 
2096 	if ((left->address == NULL && left->value == NULL)
2097 		|| (right->address == NULL && right->value == NULL)) {
2098 		if (tree->op != TOK_OP_COND) {
2099 			errorfl(tree->right->tok, "Incompatible types for "
2100 				"operator");
2101 			ret.type = NULL;
2102 			return ret;
2103 		}
2104 	}
2105 
2106 	/*
2107 	 * 05/25/09: Somehow, static addresses are still slipping through to
2108 	 * this point.
2109 	 *
2110 	 *     if (((tab)[0] & 1)) {
2111 	 *
2112 	 * ... here we are getting to TOK_OP_BAND even though a subscripted
2113 	 * static array isn't constant! The code works correctly if either
2114 	 * set of parens is removed, i.e.:
2115 	 *
2116 	 *     if ((tab[0] & 1)) {
2117 	 *
2118 	 * ... or
2119 	 *
2120 	 *     if ((tab)[0] & 1) {
2121 	 *
2122 	 * This is too obscure for me for now, so I'm putting in a check here.
2123 	 * XXX Do it right above
2124 	 */
2125 	if ( (left->address != NULL && left->value == NULL)
2126 		|| (right->address != NULL && right->value == NULL) ) {
2127 		if (extype == EXPR_OPTCONSTINIT
2128 			|| extype == EXPR_OPTCONSTARRAYSIZE) {
2129 			if (extype == EXPR_OPTCONSTINIT) {
2130 				warningfl(tree->tok, "Variable "
2131 				"initializers are not "
2132 				"allowed in ISO C90");
2133 			} else {
2134 				warningfl(tree->tok, "Variable-"
2135 				"size arrays are not "
2136 				"allowed in ISO C90");
2137 			}
2138 		} else if (extype == EXPR_OPTCONSTSUBEXPR) {
2139 			;
2140 		} else {
2141 			errorfl(tree->tok, "Expression not constant");
2142 		}
2143 		ret.type = NULL;
2144 		return ret;
2145 	}
2146 
2147 	switch (tree->op) {
2148 	case TOK_OP_PLUS:
2149 		if (left->address || right->address) {
2150 			unimpl();
2151 		} else {
2152 			cross_exec_op(tree->tok, tv, left, right);
2153 		}
2154 		break;
2155 	case TOK_OP_MINUS:
2156 		if (left->address || right->address) {
2157 			unimpl();
2158 		} else {
2159 			cross_exec_op(tree->tok, tv, left, right);
2160 		}
2161 		break;
2162 	case TOK_OP_MULTI:
2163 		cross_exec_op(tree->tok, tv, left, right);
2164 		break;
2165 	case TOK_OP_DIVIDE:
2166 		cross_exec_op(tree->tok, tv, left, right);
2167 		break;
2168 	case TOK_OP_SMALL:
2169 		cross_exec_op(tree->tok, tv, left, right);
2170 		break;
2171 	case TOK_OP_GREAT:
2172 		cross_exec_op(tree->tok, tv, left, right);
2173 		break;
2174 	case TOK_OP_GREATEQ:
2175 		cross_exec_op(tree->tok, tv, left, right);
2176 		break;
2177 	case TOK_OP_SMALLEQ:
2178 		cross_exec_op(tree->tok, tv, left, right);
2179 		break;
2180 	case TOK_OP_LEQU:
2181 		cross_exec_op(tree->tok, tv, left, right);
2182 		break;
2183 	case TOK_OP_LNEQU:
2184 		cross_exec_op(tree->tok, tv, left, right);
2185 		break;
2186 	case TOK_OP_MOD:
2187 		cross_exec_op(tree->tok, tv, left, right);
2188 		break;
2189 	case TOK_OP_BAND:
2190 		cross_exec_op(tree->tok, tv, left, right);
2191 		break;
2192 	case TOK_OP_BOR:
2193 		cross_exec_op(tree->tok, tv, left, right);
2194 		break;
2195 	case TOK_OP_BXOR:
2196 		cross_exec_op(tree->tok, tv, left, right);
2197 		break;
2198 	case TOK_OP_BSHL:
2199 		cross_exec_op(tree->tok, tv, left, right);
2200 		break;
2201 	case TOK_OP_BSHR:
2202 		cross_exec_op(tree->tok, tv, left, right);
2203 		break;
2204 	case TOK_OP_COMMA:
2205 		/*
2206 		 * 03/31/08: This was missing... In ordinary constant
2207 		 * expressions, the comma operator isn't allowed
2208 		 * anyway, but we now use this function for evaluating
2209 		 * constant sub-expressions in non-constant contexts
2210 		 * too, so we must handle it
2211 		 */
2212 		ret = *right;
2213 		break;
2214 	case TOK_OP_ASSIGN:
2215 	case TOK_OP_COBSHL:
2216 	case TOK_OP_COBSHR:
2217 	case TOK_OP_COPLUS:
2218 	case TOK_OP_COMINUS:
2219 	case TOK_OP_CODIVIDE:
2220 	case TOK_OP_COMULTI:
2221 	case TOK_OP_COBAND:
2222 	case TOK_OP_COBOR:
2223 	case TOK_OP_COBXOR:
2224 	case TOK_OP_COMOD:
2225 		errorfl(tree->tok, "Assignment operator applied to "
2226 			"something that is not an lvalue");
2227 		ret.type = NULL;
2228 		return ret;
2229 	default:
2230 		printf("Badness to the maximum %d\n", tree->op);
2231 		abort();
2232 	}
2233 
2234 	if (tree->op != TOK_OP_COND && tree->op != TOK_OP_COMMA) {
2235 		free(left->value);
2236 		free(right->value);
2237 	}
2238 
2239 out:
2240 
2241 	return ret;
2242 }
2243 
2244 int
2245 eval_const_expr(struct expr *ex, int extype, int *not_constant) {
2246 	struct tyval	tv;
2247 	struct tyval	*dtv;
2248 
2249 	if (ex->const_value != NULL) {
2250 		/* already been evaluated */
2251 		return 0;
2252 	}
2253 	tv = do_eval_const_expr(ex, extype, 0);
2254 	if (tv.type == NULL) {
2255 		if (not_constant != NULL) {
2256 			*not_constant = tv.not_constant;
2257 		}
2258 		return -1;
2259 	} else {
2260 		rv_setrc_print(tv.value, tv.type->code, 0);
2261 		dtv = n_xmalloc(sizeof tv);
2262 		memcpy(dtv, &tv, sizeof tv);
2263 		ex->const_value = dtv;
2264 	}
2265 
2266 	return 0;
2267 }
2268 
2269