/*
 * sparse/evaluate.c
 *
 * Copyright (C) 2003 Transmeta Corp.
 *               2003-2004 Linus Torvalds
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * Evaluate constant expressions.
 */
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>

#include "evaluate.h"
#include "lib.h"
#include "allocate.h"
#include "parse.h"
#include "token.h"
#include "symbol.h"
#include "target.h"
#include "expression.h"

struct symbol *current_fn;

struct ident bad_address_space = { .len = 6, .name = "bad AS", };

static struct symbol *degenerate(struct expression *expr);
static struct symbol *evaluate_symbol(struct symbol *sym);

static inline int valid_expr_type(struct expression *expr)
{
	return expr && valid_type(expr->ctype);
}

static inline int valid_subexpr_type(struct expression *expr)
{
	return valid_expr_type(expr->left)
	    && valid_expr_type(expr->right);
}

static struct symbol *evaluate_symbol_expression(struct expression *expr)
{
	struct expression *addr;
	struct symbol *sym = expr->symbol;
	struct symbol *base_type;

	if (!sym) {
		expression_error(expr, "undefined identifier '%s'", show_ident(expr->symbol_name));
		return NULL;
	}

	examine_symbol_type(sym);

	base_type = get_base_type(sym);
	if (!base_type) {
		expression_error(expr, "identifier '%s' has no type", show_ident(expr->symbol_name));
		return NULL;
	}

	addr = alloc_expression(expr->pos, EXPR_SYMBOL);
	addr->symbol = sym;
	addr->symbol_name = expr->symbol_name;
	addr->ctype = &lazy_ptr_ctype;	/* Lazy evaluation: we need to do a proper job if somebody does &sym */
	addr->flags = expr->flags;
	expr->type = EXPR_PREOP;
	expr->op = '*';
	expr->unop = addr;
	expr->flags = CEF_NONE;

	/* The type of a symbol is the symbol itself! */
	expr->ctype = sym;
	return sym;
}

static struct symbol *evaluate_string(struct expression *expr)
{
	struct symbol *sym = alloc_symbol(expr->pos, SYM_NODE);
	struct symbol *array = alloc_symbol(expr->pos, SYM_ARRAY);
	struct expression *addr = alloc_expression(expr->pos, EXPR_SYMBOL);
	struct expression *initstr = alloc_expression(expr->pos, EXPR_STRING);
	unsigned int length = expr->string->length;

	sym->array_size = alloc_const_expression(expr->pos, length);
	sym->bit_size = bytes_to_bits(length);
	sym->ctype.alignment = 1;
	sym->string = 1;
	sym->ctype.modifiers = MOD_STATIC;
	sym->ctype.base_type = array;
	sym->initializer = initstr;

	initstr->ctype = sym;
	initstr->string = expr->string;

	array->array_size = sym->array_size;
	array->bit_size = bytes_to_bits(length);
	array->ctype.alignment = 1;
	array->ctype.modifiers = MOD_STATIC;
	array->ctype.base_type = &char_ctype;
	
	addr->symbol = sym;
	addr->ctype = &lazy_ptr_ctype;
	addr->flags = CEF_ADDR;

	expr->type = EXPR_PREOP;
	expr->op = '*';
	expr->unop = addr;  
	expr->ctype = sym;
	return sym;
}

/* type has come from classify_type and is an integer type */
static inline struct symbol *integer_promotion(struct symbol *type)
{
	unsigned long mod =  type->ctype.modifiers;
	int width = type->bit_size;

	/*
	 * Bitfields always promote to the base type,
	 * even if the bitfield might be bigger than
	 * an "int".
	 */
	if (type->type == SYM_BITFIELD) {
		type = type->ctype.base_type;
	}
	mod = type->ctype.modifiers;
	if (width < bits_in_int)
		return &int_ctype;

	/* If char/short has as many bits as int, it still gets "promoted" */
	if (mod & (MOD_CHAR | MOD_SHORT)) {
		if (mod & MOD_UNSIGNED)
			return &uint_ctype;
		return &int_ctype;
	}
	return type;
}

/*
 * integer part of usual arithmetic conversions:
 *	integer promotions are applied
 *	if left and right are identical, we are done
 *	if signedness is the same, convert one with lower rank
 *	unless unsigned argument has rank lower than signed one, convert the
 *	signed one.
 *	if signed argument is bigger than unsigned one, convert the unsigned.
 *	otherwise, convert signed.
 *
 * Leaving aside the integer promotions, that is equivalent to
 *	if identical, don't convert
 *	if left is bigger than right, convert right
 *	if right is bigger than left, convert right
 *	otherwise, if signedness is the same, convert one with lower rank
 *	otherwise convert the signed one.
 */
static struct symbol *bigger_int_type(struct symbol *left, struct symbol *right)
{
	unsigned long lmod, rmod;

	left = integer_promotion(left);
	right = integer_promotion(right);

	if (left == right)
		goto left;

	if (left->bit_size > right->bit_size)
		goto left;

	if (right->bit_size > left->bit_size)
		goto right;

	lmod = left->ctype.modifiers;
	rmod = right->ctype.modifiers;
	if ((lmod ^ rmod) & MOD_UNSIGNED) {
		if (lmod & MOD_UNSIGNED)
			goto left;
	} else if ((lmod & ~rmod) & (MOD_LONG_ALL))
		goto left;
right:
	left = right;
left:
	return left;
}

static int same_cast_type(struct symbol *orig, struct symbol *new)
{
	return orig->bit_size == new->bit_size &&
	       orig->bit_offset == new->bit_offset;
}

static struct symbol *base_type(struct symbol *node, unsigned long *modp, struct ident **asp)
{
	unsigned long mod = 0;
	struct ident *as = NULL;

	while (node) {
		mod |= node->ctype.modifiers;
		combine_address_space(node->pos, &as, node->ctype.as);
		if (node->type == SYM_NODE) {
			node = node->ctype.base_type;
			continue;
		}
		break;
	}
	*modp = mod & ~MOD_IGNORE;
	*asp = as;
	return node;
}

static int is_same_type(struct expression *expr, struct symbol *new)
{
	struct symbol *old = expr->ctype;
	unsigned long oldmod, newmod;
	struct ident *oldas, *newas;

	old = base_type(old, &oldmod, &oldas);
	new = base_type(new, &newmod, &newas);

	/* Same base type, same address space? */
	if (old == new && oldas == newas) {
		unsigned long difmod;

		/* Check the modifier bits. */
		difmod = (oldmod ^ newmod) & ~MOD_NOCAST;

		/* Exact same type? */
		if (!difmod)
			return 1;

		/*
		 * Not the same type, but differs only in "const".
		 * Don't warn about MOD_NOCAST.
		 */
		if (difmod == MOD_CONST)
			return 0;
	}
	if ((oldmod | newmod) & MOD_NOCAST) {
		const char *tofrom = "to/from";
		if (!(newmod & MOD_NOCAST))
			tofrom = "from";
		if (!(oldmod & MOD_NOCAST))
			tofrom = "to";
		warning(expr->pos, "implicit cast %s nocast type", tofrom);
	}
	return 0;
}

static void
warn_for_different_enum_types (struct position pos,
			       struct symbol *typea,
			       struct symbol *typeb)
{
	if (!Wenum_mismatch)
		return;
	if (typea->type == SYM_NODE)
		typea = typea->ctype.base_type;
	if (typeb->type == SYM_NODE)
		typeb = typeb->ctype.base_type;

	if (typea == typeb)
		return;

	if (typea->type == SYM_ENUM && typeb->type == SYM_ENUM) {
		warning(pos, "mixing different enum types");
		info(pos, "    %s versus", show_typename(typea));
		info(pos, "    %s", show_typename(typeb));
	}
}

static int cast_flags(struct expression *expr, struct expression *target);
static struct symbol *cast_to_bool(struct expression *expr);

/*
 * This gets called for implicit casts in assignments and
 * integer promotion. We often want to try to move the
 * cast down, because the ops involved may have been
 * implicitly cast up, and we can get rid of the casts
 * early.
 */
static struct expression * cast_to(struct expression *old, struct symbol *type)
{
	struct expression *expr;

	warn_for_different_enum_types (old->pos, old->ctype, type);

	if (old->ctype != &null_ctype && is_same_type(old, type))
		return old;

	/*
	 * See if we can simplify the op. Move the cast down.
	 */
	switch (old->type) {
	case EXPR_PREOP:
		if (old->ctype->bit_size < type->bit_size)
			break;
		if (old->op == '~') {
			old->ctype = type;
			old->unop = cast_to(old->unop, type);
			return old;
		}
		break;

	case EXPR_IMPLIED_CAST:
		warn_for_different_enum_types(old->pos, old->ctype, type);

		if (old->ctype->bit_size >= type->bit_size) {
			struct expression *orig = old->cast_expression;
			if (same_cast_type(orig->ctype, type))
				return orig;
			if (old->ctype->bit_offset == type->bit_offset) {
				old->ctype = type;
				old->cast_type = type;
				return old;
			}
		}
		break;

	default:
		/* nothing */;
	}

	expr = alloc_expression(old->pos, EXPR_IMPLIED_CAST);
	expr->ctype = type;
	expr->cast_type = type;
	expr->cast_expression = old;
	expr->flags = cast_flags(expr, old);

	if (is_bool_type(type))
		cast_to_bool(expr);

	return expr;
}

enum {
	TYPE_NUM = 1,
	TYPE_BITFIELD = 2,
	TYPE_RESTRICT = 4,
	TYPE_FLOAT = 8,
	TYPE_PTR = 16,
	TYPE_COMPOUND = 32,
	TYPE_FOULED = 64,
	TYPE_FN = 128,
};

static inline int classify_type(struct symbol *type, struct symbol **base)
{
	static int type_class[SYM_BAD + 1] = {
		[SYM_PTR] = TYPE_PTR,
		[SYM_FN] = TYPE_PTR | TYPE_FN,
		[SYM_ARRAY] = TYPE_PTR | TYPE_COMPOUND,
		[SYM_STRUCT] = TYPE_COMPOUND,
		[SYM_UNION] = TYPE_COMPOUND,
		[SYM_BITFIELD] = TYPE_NUM | TYPE_BITFIELD,
		[SYM_RESTRICT] = TYPE_NUM | TYPE_RESTRICT,
		[SYM_FOULED] = TYPE_NUM | TYPE_RESTRICT | TYPE_FOULED,
	};
	if (type->type == SYM_NODE)
		type = type->ctype.base_type;
	if (type->type == SYM_TYPEOF) {
		type = evaluate_expression(type->initializer);
		if (!type)
			type = &bad_ctype;
		else if (type->type == SYM_NODE)
			type = type->ctype.base_type;
	}
	if (type->type == SYM_ENUM)
		type = type->ctype.base_type;
	*base = type;
	if (type->type == SYM_BASETYPE) {
		if (type->ctype.base_type == &int_type)
			return TYPE_NUM;
		if (type->ctype.base_type == &fp_type)
			return TYPE_NUM | TYPE_FLOAT;
	}
	return type_class[type->type];
}

#define is_int(class) ((class & (TYPE_NUM | TYPE_FLOAT)) == TYPE_NUM)

static inline int is_string_type(struct symbol *type)
{
	if (type->type == SYM_NODE)
		type = type->ctype.base_type;
	return type->type == SYM_ARRAY && is_byte_type(type->ctype.base_type);
}

static struct symbol *bad_expr_type(struct expression *expr)
{
	switch (expr->type) {
	case EXPR_BINOP:
	case EXPR_COMPARE:
		if (!valid_subexpr_type(expr))
			break;
		sparse_error(expr->pos, "incompatible types for operation (%s)", show_special(expr->op));
		info(expr->pos, "   left side has type %s", show_typename(expr->left->ctype));
		info(expr->pos, "   right side has type %s", show_typename(expr->right->ctype));
		break;
	case EXPR_PREOP:
	case EXPR_POSTOP:
		if (!valid_expr_type(expr->unop))
			break;
		sparse_error(expr->pos, "incompatible types for operation (%s)", show_special(expr->op));
		info(expr->pos, "   argument has type %s", show_typename(expr->unop->ctype));
		break;
	default:
		break;
	}

	expr->flags = CEF_NONE;
	return expr->ctype = &bad_ctype;
}

static int restricted_value(struct expression *v, struct symbol *type)
{
	if (v->type != EXPR_VALUE)
		return 1;
	if (v->value != 0)
		return 1;
	return 0;
}

static int restricted_binop(int op, struct symbol *type)
{
	switch (op) {
		case '&':
		case '=':
		case SPECIAL_AND_ASSIGN:
		case SPECIAL_OR_ASSIGN:
		case SPECIAL_XOR_ASSIGN:
			return 1;	/* unfoul */
		case '|':
		case '^':
		case '?':
			return 2;	/* keep fouled */
		case SPECIAL_EQUAL:
		case SPECIAL_NOTEQUAL:
			return 3;	/* warn if fouled */
		default:
			return 0;	/* warn */
	}
}

static int restricted_unop(int op, struct symbol **type)
{
	if (op == '~') {
		if ((*type)->bit_size < bits_in_int)
			*type = befoul(*type);
		return 0;
	} if (op == '+')
		return 0;
	return 1;
}

/* type should be SYM_FOULED */
static inline struct symbol *unfoul(struct symbol *type)
{
	return type->ctype.base_type;
}

static struct symbol *restricted_binop_type(int op,
					struct expression *left,
					struct expression *right,
					int lclass, int rclass,
					struct symbol *ltype,
					struct symbol *rtype)
{
	struct symbol *ctype = NULL;
	if (lclass & TYPE_RESTRICT) {
		if (rclass & TYPE_RESTRICT) {
			if (ltype == rtype) {
				ctype = ltype;
			} else if (lclass & TYPE_FOULED) {
				if (unfoul(ltype) == rtype)
					ctype = ltype;
			} else if (rclass & TYPE_FOULED) {
				if (unfoul(rtype) == ltype)
					ctype = rtype;
			}
		} else {
			if (!restricted_value(right, ltype))
				ctype = ltype;
		}
	} else if (!restricted_value(left, rtype))
		ctype = rtype;

	if (ctype) {
		switch (restricted_binop(op, ctype)) {
		case 1:
			if ((lclass ^ rclass) & TYPE_FOULED)
				ctype = unfoul(ctype);
			break;
		case 3:
			if (!(lclass & rclass & TYPE_FOULED))
				break;
		case 0:
			ctype = NULL;
		default:
			break;
		}
	}

	return ctype;
}

static inline void unrestrict(struct expression *expr,
			      int class, struct symbol **ctype)
{
	if (class & TYPE_RESTRICT) {
		if (class & TYPE_FOULED)
			*ctype = unfoul(*ctype);
		warning(expr->pos, "%s degrades to integer",
			show_typename(*ctype));
		*ctype = (*ctype)->ctype.base_type; /* get to arithmetic type */
	}
}

static struct symbol *usual_conversions(int op,
					struct expression *left,
					struct expression *right,
					int lclass, int rclass,
					struct symbol *ltype,
					struct symbol *rtype)
{
	struct symbol *ctype;

	warn_for_different_enum_types(right->pos, left->ctype, right->ctype);

	if ((lclass | rclass) & TYPE_RESTRICT)
		goto Restr;

Normal:
	if (!(lclass & TYPE_FLOAT)) {
		if (!(rclass & TYPE_FLOAT))
			return bigger_int_type(ltype, rtype);
		else
			return rtype;
	} else if (rclass & TYPE_FLOAT) {
		unsigned long lmod = ltype->ctype.modifiers;
		unsigned long rmod = rtype->ctype.modifiers;
		if (rmod & ~lmod & (MOD_LONG_ALL))
			return rtype;
		else
			return ltype;
	} else
		return ltype;

Restr:
	ctype = restricted_binop_type(op, left, right,
				      lclass, rclass, ltype, rtype);
	if (ctype)
		return ctype;

	unrestrict(left, lclass, &ltype);
	unrestrict(right, rclass, &rtype);

	goto Normal;
}

static inline int lvalue_expression(struct expression *expr)
{
	return expr->type == EXPR_PREOP && expr->op == '*';
}

static struct symbol *evaluate_ptr_add(struct expression *expr, struct symbol *itype)
{
	struct expression *index = expr->right;
	struct symbol *ctype, *base;
	int multiply;

	classify_type(degenerate(expr->left), &ctype);
	base = examine_pointer_target(ctype);

	/*
	 * An address constant +/- an integer constant expression
	 * yields an address constant again [6.6(7)].
	 */
	if ((expr->left->flags & CEF_ADDR) && (expr->right->flags & CEF_ICE))
		expr->flags = CEF_ADDR;

	if (!base) {
		expression_error(expr, "missing type information");
		return NULL;
	}
	if (is_function(base)) {
		expression_error(expr, "arithmetics on pointers to functions");
		return NULL;
	}

	/* Get the size of whatever the pointer points to */
	multiply = is_void_type(base) ? 1 : bits_to_bytes(base->bit_size);

	if (ctype == &null_ctype)
		ctype = &ptr_ctype;
	expr->ctype = ctype;

	if (multiply == 1 && itype->bit_size >= bits_in_pointer)
		return ctype;

	if (index->type == EXPR_VALUE) {
		struct expression *val = alloc_expression(expr->pos, EXPR_VALUE);
		unsigned long long v = index->value, mask;
		mask = 1ULL << (itype->bit_size - 1);
		if (v & mask)
			v |= -mask;
		else
			v &= mask - 1;
		v *= multiply;
		mask = 1ULL << (bits_in_pointer - 1);
		v &= mask | (mask - 1);
		val->value = v;
		val->ctype = ssize_t_ctype;
		expr->right = val;
		return ctype;
	}

	if (itype->bit_size < bits_in_pointer)
		index = cast_to(index, ssize_t_ctype);

	if (multiply > 1) {
		struct expression *val = alloc_expression(expr->pos, EXPR_VALUE);
		struct expression *mul = alloc_expression(expr->pos, EXPR_BINOP);

		val->ctype = ssize_t_ctype;
		val->value = multiply;

		mul->op = '*';
		mul->ctype = ssize_t_ctype;
		mul->left = index;
		mul->right = val;
		index = mul;
	}

	expr->right = index;
	return ctype;
}

static void examine_fn_arguments(struct symbol *fn);

#define MOD_IGN (MOD_QUALIFIER | MOD_PURE)

const char *type_difference(struct ctype *c1, struct ctype *c2,
	unsigned long mod1, unsigned long mod2)
{
	struct ident *as1 = c1->as, *as2 = c2->as;
	struct symbol *t1 = c1->base_type;
	struct symbol *t2 = c2->base_type;
	int move1 = 1, move2 = 1;
	mod1 |= c1->modifiers;
	mod2 |= c2->modifiers;
	for (;;) {
		unsigned long diff;
		int type;
		struct symbol *base1 = t1->ctype.base_type;
		struct symbol *base2 = t2->ctype.base_type;

		/*
		 * FIXME! Collect alignment and context too here!
		 */
		if (move1) {
			if (t1 && t1->type != SYM_PTR) {
				mod1 |= t1->ctype.modifiers;
				combine_address_space(t1->pos, &as1, t1->ctype.as);
			}
			move1 = 0;
		}

		if (move2) {
			if (t2 && t2->type != SYM_PTR) {
				mod2 |= t2->ctype.modifiers;
				combine_address_space(t2->pos, &as2, t2->ctype.as);
			}
			move2 = 0;
		}

		if (t1 == t2)
			break;
		if (!t1 || !t2)
			return "different types";

		if (t1->type == SYM_NODE || t1->type == SYM_ENUM) {
			t1 = base1;
			move1 = 1;
			if (!t1)
				return "bad types";
			continue;
		}

		if (t2->type == SYM_NODE || t2->type == SYM_ENUM) {
			t2 = base2;
			move2 = 1;
			if (!t2)
				return "bad types";
			continue;
		}

		move1 = move2 = 1;
		type = t1->type;
		if (type != t2->type)
			return "different base types";

		switch (type) {
		default:
			sparse_error(t1->pos,
				     "internal error: bad type in derived(%d)",
				     type);
			return "bad types";
		case SYM_RESTRICT:
			return "different base types";
		case SYM_UNION:
		case SYM_STRUCT:
			/* allow definition of incomplete structs and unions */
			if (t1->ident == t2->ident)
			  return NULL;
			return "different base types";
		case SYM_ARRAY:
			/* XXX: we ought to compare sizes */
			break;
		case SYM_PTR:
			if (as1 != as2)
				return "different address spaces";
			/* MOD_SPECIFIER is due to idiocy in parse.c */
			if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SPECIFIER)
				return "different modifiers";
			/* we could be lazier here */
			base1 = examine_pointer_target(t1);
			base2 = examine_pointer_target(t2);
			mod1 = t1->ctype.modifiers;
			as1 = t1->ctype.as;
			mod2 = t2->ctype.modifiers;
			as2 = t2->ctype.as;
			break;
		case SYM_FN: {
			struct symbol *arg1, *arg2;
			int i;

			if (as1 != as2)
				return "different address spaces";
			if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS)
				return "different modifiers";
			mod1 = t1->ctype.modifiers;
			as1 = t1->ctype.as;
			mod2 = t2->ctype.modifiers;
			as2 = t2->ctype.as;

			if (t1->variadic != t2->variadic)
				return "incompatible variadic arguments";
			examine_fn_arguments(t1);
			examine_fn_arguments(t2);
			PREPARE_PTR_LIST(t1->arguments, arg1);
			PREPARE_PTR_LIST(t2->arguments, arg2);
			i = 1;
			for (;;) {
				const char *diffstr;
				if (!arg1 && !arg2)
					break;
				if (!arg1 || !arg2)
					return "different argument counts";
				diffstr = type_difference(&arg1->ctype,
							  &arg2->ctype,
							  MOD_IGN, MOD_IGN);
				if (diffstr) {
					static char argdiff[80];
					sprintf(argdiff, "incompatible argument %d (%s)", i, diffstr);
					return argdiff;
				}
				NEXT_PTR_LIST(arg1);
				NEXT_PTR_LIST(arg2);
				i++;
			}
			FINISH_PTR_LIST(arg2);
			FINISH_PTR_LIST(arg1);
			break;
		}
		case SYM_BASETYPE:
			if (as1 != as2)
				return "different address spaces";
			if (base1 != base2)
				return "different base types";
			diff = (mod1 ^ mod2) & ~MOD_IGNORE;
			if (!diff)
				return NULL;
			if (diff & MOD_SIZE)
				return "different type sizes";
			else if (diff & ~MOD_SIGNEDNESS)
				return "different modifiers";
			else
				return "different signedness";
		}
		t1 = base1;
		t2 = base2;
	}
	if (as1 != as2)
		return "different address spaces";
	if ((mod1 ^ mod2) & ~MOD_IGNORE & ~MOD_SIGNEDNESS)
		return "different modifiers";
	return NULL;
}

static void bad_null(struct expression *expr)
{
	if (Wnon_pointer_null)
		warning(expr->pos, "Using plain integer as NULL pointer");
}

static unsigned long target_qualifiers(struct symbol *type)
{
	unsigned long mod = type->ctype.modifiers & MOD_IGN;
	if (type->ctype.base_type && type->ctype.base_type->type == SYM_ARRAY)
		mod = 0;
	return mod;
}

static struct symbol *evaluate_ptr_sub(struct expression *expr)
{
	const char *typediff;
	struct symbol *ltype, *rtype;
	struct expression *l = expr->left;
	struct expression *r = expr->right;
	struct symbol *lbase;

	classify_type(degenerate(l), &ltype);
	classify_type(degenerate(r), &rtype);

	lbase = examine_pointer_target(ltype);
	examine_pointer_target(rtype);
	typediff = type_difference(&ltype->ctype, &rtype->ctype,
				   target_qualifiers(rtype),
				   target_qualifiers(ltype));
	if (typediff)
		expression_error(expr, "subtraction of different types can't work (%s)", typediff);

	if (is_function(lbase)) {
		expression_error(expr, "subtraction of functions? Share your drugs");
		return NULL;
	}

	expr->ctype = ssize_t_ctype;
	if (lbase->bit_size > bits_in_char) {
		struct expression *sub = alloc_expression(expr->pos, EXPR_BINOP);
		struct expression *div = expr;
		struct expression *val = alloc_expression(expr->pos, EXPR_VALUE);
		unsigned long value = bits_to_bytes(lbase->bit_size);

		val->ctype = size_t_ctype;
		val->value = value;

		if (value & (value-1)) {
			if (Wptr_subtraction_blows) {
				warning(expr->pos, "potentially expensive pointer subtraction");
				info(expr->pos, "    '%s' has a non-power-of-2 size: %lu", show_typename(lbase), value);
			}
		}

		sub->op = '-';
		sub->ctype = ssize_t_ctype;
		sub->left = l;
		sub->right = r;

		div->op = '/';
		div->left = sub;
		div->right = val;
	}
		
	return ssize_t_ctype;
}

#define is_safe_type(type) ((type)->ctype.modifiers & MOD_SAFE)

static struct symbol *evaluate_conditional(struct expression *expr, int iterator)
{
	struct symbol *ctype;

	if (!expr)
		return NULL;

	if (!iterator && expr->type == EXPR_ASSIGNMENT && expr->op == '=')
		warning(expr->pos, "assignment expression in conditional");

	ctype = evaluate_expression(expr);
	if (!valid_type(ctype))
		return NULL;
	if (is_safe_type(ctype))
		warning(expr->pos, "testing a 'safe expression'");
	if (is_func_type(ctype)) {
		if (Waddress)
			warning(expr->pos, "the address of %s will always evaluate as true", "a function");
	} else if (is_array_type(ctype)) {
		if (Waddress)
			warning(expr->pos, "the address of %s will always evaluate as true", "an array");
	} else if (!is_scalar_type(ctype)) {
		sparse_error(expr->pos, "incorrect type in conditional (non-scalar type)");
		info(expr->pos, "   got %s", show_typename(ctype));
		return NULL;
	}

	ctype = degenerate(expr);
	return ctype;
}

static struct symbol *evaluate_logical(struct expression *expr)
{
	if (!evaluate_conditional(expr->left, 0))
		return NULL;
	if (!evaluate_conditional(expr->right, 0))
		return NULL;

	/* the result is int [6.5.13(3), 6.5.14(3)] */
	expr->ctype = &int_ctype;
	expr->flags = expr->left->flags & expr->right->flags;
	expr->flags &= ~(CEF_CONST_MASK | CEF_ADDR);
	return &int_ctype;
}

static struct symbol *evaluate_binop(struct expression *expr)
{
	struct symbol *ltype, *rtype, *ctype;
	int lclass = classify_type(expr->left->ctype, &ltype);
	int rclass = classify_type(expr->right->ctype, &rtype);
	int op = expr->op;

	/* number op number */
	if (lclass & rclass & TYPE_NUM) {
		expr->flags = expr->left->flags & expr->right->flags;
		expr->flags &= ~CEF_CONST_MASK;

		if ((lclass | rclass) & TYPE_FLOAT) {
			switch (op) {
			case '+': case '-': case '*': case '/':
				break;
			default:
				return bad_expr_type(expr);
			}
		}

		if (op == SPECIAL_LEFTSHIFT || op == SPECIAL_RIGHTSHIFT) {
			// shifts do integer promotions, but that's it.
			unrestrict(expr->left, lclass, &ltype);
			unrestrict(expr->right, rclass, &rtype);
			ctype = ltype = integer_promotion(ltype);
			rtype = integer_promotion(rtype);
		} else {
			// The rest do usual conversions
			const unsigned left_not  = expr->left->type == EXPR_PREOP
			                           && expr->left->op == '!';
			const unsigned right_not = expr->right->type == EXPR_PREOP
			                           && expr->right->op == '!';
			if ((op == '&' || op == '|') && (left_not || right_not))
				warning(expr->pos, "dubious: %sx %c %sy",
				        left_not ? "!" : "",
					op,
					right_not ? "!" : "");

			ltype = usual_conversions(op, expr->left, expr->right,
						  lclass, rclass, ltype, rtype);
			ctype = rtype = ltype;
		}

		expr->left = cast_to(expr->left, ltype);
		expr->right = cast_to(expr->right, rtype);
		expr->ctype = ctype;
		return ctype;
	}

	/* pointer (+|-) integer */
	if (lclass & TYPE_PTR && is_int(rclass) && (op == '+' || op == '-')) {
		unrestrict(expr->right, rclass, &rtype);
		return evaluate_ptr_add(expr, rtype);
	}

	/* integer + pointer */
	if (rclass & TYPE_PTR && is_int(lclass) && op == '+') {
		struct expression *index = expr->left;
		unrestrict(index, lclass, &ltype);
		expr->left = expr->right;
		expr->right = index;
		return evaluate_ptr_add(expr, ltype);
	}

	/* pointer - pointer */
	if (lclass & rclass & TYPE_PTR && expr->op == '-')
		return evaluate_ptr_sub(expr);

	return bad_expr_type(expr);
}

static struct symbol *evaluate_comma(struct expression *expr)
{
	expr->ctype = degenerate(expr->right);
	if (expr->ctype == &null_ctype)
		expr->ctype = &ptr_ctype;
	expr->flags &= expr->left->flags & expr->right->flags;
	return expr->ctype;
}

static int modify_for_unsigned(int op)
{
	if (op == '<')
		op = SPECIAL_UNSIGNED_LT;
	else if (op == '>')
		op = SPECIAL_UNSIGNED_GT;
	else if (op == SPECIAL_LTE)
		op = SPECIAL_UNSIGNED_LTE;
	else if (op == SPECIAL_GTE)
		op = SPECIAL_UNSIGNED_GTE;
	return op;
}

enum null_constant_type {
	NON_NULL,
	NULL_PTR,
	NULL_ZERO,
};

static inline int is_null_pointer_constant(struct expression *e)
{
	if (e->ctype == &null_ctype)
		return NULL_PTR;
	if (!(e->flags & CEF_ICE))
		return NON_NULL;
	return is_zero_constant(e) ? NULL_ZERO : NON_NULL;
}

static struct symbol *evaluate_compare(struct expression *expr)
{
	struct expression *left = expr->left, *right = expr->right;
	struct symbol *ltype, *rtype, *lbase, *rbase;
	int lclass = classify_type(degenerate(left), &ltype);
	int rclass = classify_type(degenerate(right), &rtype);
	struct symbol *ctype;
	const char *typediff;

	/* Type types? */
	if (is_type_type(ltype) && is_type_type(rtype)) {
		/*
		 * __builtin_types_compatible_p() yields an integer
		 * constant expression
		 */
		expr->flags = CEF_SET_ICE;
		goto OK;
	}

	if (is_safe_type(left->ctype) || is_safe_type(right->ctype))
		warning(expr->pos, "testing a 'safe expression'");

	expr->flags = left->flags & right->flags & ~CEF_CONST_MASK & ~CEF_ADDR;

	/* number on number */
	if (lclass & rclass & TYPE_NUM) {
		ctype = usual_conversions(expr->op, expr->left, expr->right,
					  lclass, rclass, ltype, rtype);
		expr->left = cast_to(expr->left, ctype);
		expr->right = cast_to(expr->right, ctype);
		if (ctype->ctype.modifiers & MOD_UNSIGNED)
			expr->op = modify_for_unsigned(expr->op);
		goto OK;
	}

	/* at least one must be a pointer */
	if (!((lclass | rclass) & TYPE_PTR))
		return bad_expr_type(expr);

	/* equality comparisons can be with null pointer constants */
	if (expr->op == SPECIAL_EQUAL || expr->op == SPECIAL_NOTEQUAL) {
		int is_null1 = is_null_pointer_constant(left);
		int is_null2 = is_null_pointer_constant(right);
		if (is_null1 == NULL_ZERO)
			bad_null(left);
		if (is_null2 == NULL_ZERO)
			bad_null(right);
		if (is_null1 && is_null2) {
			int positive = expr->op == SPECIAL_EQUAL;
			expr->type = EXPR_VALUE;
			expr->value = positive;
			goto OK;
		}
		if (is_null1 && (rclass & TYPE_PTR)) {
			left = cast_to(left, rtype);
			goto OK;
		}
		if (is_null2 && (lclass & TYPE_PTR)) {
			right = cast_to(right, ltype);
			goto OK;
		}
	}
	/* both should be pointers */
	if (!(lclass & rclass & TYPE_PTR))
		return bad_expr_type(expr);
	expr->op = modify_for_unsigned(expr->op);

	lbase = examine_pointer_target(ltype);
	rbase = examine_pointer_target(rtype);

	/* they also have special treatment for pointers to void */
	if (expr->op == SPECIAL_EQUAL || expr->op == SPECIAL_NOTEQUAL) {
		if (ltype->ctype.as == rtype->ctype.as) {
			if (lbase == &void_ctype) {
				right = cast_to(right, ltype);
				goto OK;
			}
			if (rbase == &void_ctype) {
				left = cast_to(left, rtype);
				goto OK;
			}
		}
	}

	typediff = type_difference(&ltype->ctype, &rtype->ctype,
				   target_qualifiers(rtype),
				   target_qualifiers(ltype));
	if (!typediff)
		goto OK;

	expression_error(expr, "incompatible types in comparison expression (%s):", typediff);
	info(expr->pos, "   %s", show_typename(ltype));
	info(expr->pos, "   %s", show_typename(rtype));
	return NULL;

OK:
	/* the result is int [6.5.8(6), 6.5.9(3)]*/
	expr->ctype = &int_ctype;
	return &int_ctype;
}

/*
 * NOTE! The degenerate case of "x ? : y", where we don't
 * have a true case, this will possibly promote "x" to the
 * same type as "y", and thus _change_ the conditional
 * test in the expression. But since promotion is "safe"
 * for testing, that's OK.
 */
static struct symbol *evaluate_conditional_expression(struct expression *expr)
{
	struct expression **cond;
	struct symbol *ctype, *ltype, *rtype, *lbase, *rbase;
	int lclass, rclass;
	const char * typediff;
	int qual;

	if (!evaluate_conditional(expr->conditional, 0))
		return NULL;
	if (!evaluate_expression(expr->cond_false))
		return NULL;

	ctype = degenerate(expr->conditional);
	rtype = degenerate(expr->cond_false);

	cond = &expr->conditional;
	ltype = ctype;
	if (expr->cond_true) {
		if (!evaluate_expression(expr->cond_true))
			return NULL;
		ltype = degenerate(expr->cond_true);
		cond = &expr->cond_true;
	}

	expr->flags = (expr->conditional->flags & (*cond)->flags &
			expr->cond_false->flags & ~CEF_CONST_MASK);
	/*
	 * A conditional operator yields a particular constant
	 * expression type only if all of its three subexpressions are
	 * of that type [6.6(6), 6.6(8)].
	 * As an extension, relax this restriction by allowing any
	 * constant expression type for the condition expression.
	 *
	 * A conditional operator never yields an address constant
	 * [6.6(9)].
	 * However, as an extension, if the condition is any constant
	 * expression, and the true and false expressions are both
	 * address constants, mark the result as an address constant.
	 */
	if (expr->conditional->flags & (CEF_ACE | CEF_ADDR))
		expr->flags = (*cond)->flags & expr->cond_false->flags & ~CEF_CONST_MASK;

	lclass = classify_type(ltype, &ltype);
	rclass = classify_type(rtype, &rtype);
	if (lclass & rclass & TYPE_NUM) {
		ctype = usual_conversions('?', *cond, expr->cond_false,
					  lclass, rclass, ltype, rtype);
		*cond = cast_to(*cond, ctype);
		expr->cond_false = cast_to(expr->cond_false, ctype);
		goto out;
	}

	if ((lclass | rclass) & TYPE_PTR) {
		int is_null1 = is_null_pointer_constant(*cond);
		int is_null2 = is_null_pointer_constant(expr->cond_false);

		if (is_null1 && is_null2) {
			*cond = cast_to(*cond, &ptr_ctype);
			expr->cond_false = cast_to(expr->cond_false, &ptr_ctype);
			ctype = &ptr_ctype;
			goto out;
		}
		if (is_null1 && (rclass & TYPE_PTR)) {
			if (is_null1 == NULL_ZERO)
				bad_null(*cond);
			*cond = cast_to(*cond, rtype);
			ctype = rtype;
			goto out;
		}
		if (is_null2 && (lclass & TYPE_PTR)) {
			if (is_null2 == NULL_ZERO)
				bad_null(expr->cond_false);
			expr->cond_false = cast_to(expr->cond_false, ltype);
			ctype = ltype;
			goto out;
		}
		if (!(lclass & rclass & TYPE_PTR)) {
			typediff = "different types";
			goto Err;
		}
		/* OK, it's pointer on pointer */
		if (ltype->ctype.as != rtype->ctype.as) {
			typediff = "different address spaces";
			goto Err;
		}

		/* need to be lazier here */
		lbase = examine_pointer_target(ltype);
		rbase = examine_pointer_target(rtype);
		qual = target_qualifiers(ltype) | target_qualifiers(rtype);

		if (lbase == &void_ctype) {
			/* XXX: pointers to function should warn here */
			ctype = ltype;
			goto Qual;

		}
		if (rbase == &void_ctype) {
			/* XXX: pointers to function should warn here */
			ctype = rtype;
			goto Qual;
		}
		/* XXX: that should be pointer to composite */
		ctype = ltype;
		typediff = type_difference(&ltype->ctype, &rtype->ctype,
					   qual, qual);
		if (!typediff)
			goto Qual;
		goto Err;
	}

	/* void on void, struct on same struct, union on same union */
	if (ltype == rtype) {
		ctype = ltype;
		goto out;
	}
	typediff = "different base types";

Err:
	expression_error(expr, "incompatible types in conditional expression (%s):", typediff);
	info(expr->pos, "   %s", show_typename(ltype));
	info(expr->pos, "   %s", show_typename(rtype));
	/*
	 * if the condition is constant, the type is in fact known
	 * so use it, as gcc & clang do.
	 */
	switch (expr_truth_value(expr->conditional)) {
	case 1:	expr->ctype = ltype;
		break;
	case 0: expr->ctype = rtype;
		break;
	default:
		break;
	}
	return NULL;

out:
	expr->ctype = ctype;
	return ctype;

Qual:
	if (qual & ~ctype->ctype.modifiers) {
		struct symbol *sym = alloc_symbol(ctype->pos, SYM_PTR);
		*sym = *ctype;
		sym->ctype.modifiers |= qual;
		ctype = sym;
	}
	*cond = cast_to(*cond, ctype);
	expr->cond_false = cast_to(expr->cond_false, ctype);
	goto out;
}

/* FP assignments can not do modulo or bit operations */
static int compatible_float_op(int op)
{
	return	op == SPECIAL_ADD_ASSIGN ||
		op == SPECIAL_SUB_ASSIGN ||
		op == SPECIAL_MUL_ASSIGN ||
		op == SPECIAL_DIV_ASSIGN;
}

static int evaluate_assign_op(struct expression *expr)
{
	struct symbol *target = expr->left->ctype;
	struct symbol *source = expr->right->ctype;
	struct symbol *t, *s;
	int tclass = classify_type(target, &t);
	int sclass = classify_type(source, &s);
	int op = expr->op;

	if (tclass & sclass & TYPE_NUM) {
		if (tclass & TYPE_FLOAT && !compatible_float_op(op)) {
			expression_error(expr, "invalid assignment");
			return 0;
		}
		if (tclass & TYPE_RESTRICT) {
			if (!restricted_binop(op, t)) {
				warning(expr->pos, "bad assignment (%s) to %s",
					show_special(op), show_typename(t));
				expr->right = cast_to(expr->right, target);
				return 0;
			}
			/* allowed assignments unfoul */
			if (sclass & TYPE_FOULED && unfoul(s) == t)
				goto Cast;
			if (!restricted_value(expr->right, t))
				return 1;
		} else if (op == SPECIAL_SHR_ASSIGN || op == SPECIAL_SHL_ASSIGN) {
			// shifts do integer promotions, but that's it.
			unrestrict(expr->right, sclass, &s);
			target = integer_promotion(s);
			goto Cast;
		} else if (!(sclass & TYPE_RESTRICT))
			goto usual;
		/* source and target would better be identical restricted */
		if (t == s)
			return 1;
		warning(expr->pos, "invalid assignment: %s", show_special(op));
		info(expr->pos, "   left side has type %s", show_typename(t));
		info(expr->pos, "   right side has type %s", show_typename(s));
		expr->right = cast_to(expr->right, target);
		return 0;
	}
	if (tclass == TYPE_PTR && is_int(sclass)) {
		if (op == SPECIAL_ADD_ASSIGN || op == SPECIAL_SUB_ASSIGN) {
			unrestrict(expr->right, sclass, &s);
			evaluate_ptr_add(expr, s);
			return 1;
		}
		expression_error(expr, "invalid pointer assignment");
		return 0;
	}

	expression_error(expr, "invalid assignment");
	return 0;

usual:
	target = usual_conversions(op, expr->left, expr->right,
				tclass, sclass, target, source);
Cast:
	expr->right = cast_to(expr->right, target);
	return 1;
}

static int whitelist_pointers(struct symbol *t1, struct symbol *t2)
{
	if (t1 == t2)
		return 0;	/* yes, 0 - we don't want a cast_to here */
	if (t1 == &void_ctype)
		return 1;
	if (t2 == &void_ctype)
		return 1;
	if (classify_type(t1, &t1) != TYPE_NUM)
		return 0;
	if (classify_type(t2, &t2) != TYPE_NUM)
		return 0;
	if (t1 == t2)
		return 1;
	if (t1->ctype.modifiers & t2->ctype.modifiers & MOD_CHAR)
		return 1;
	if ((t1->ctype.modifiers ^ t2->ctype.modifiers) & MOD_SIZE)
		return 0;
	return !Wtypesign;
}

static int check_assignment_types(struct symbol *target, struct expression **rp,
	const char **typediff)
{
	struct symbol *source = degenerate(*rp);
	struct symbol *t, *s;
	int tclass = classify_type(target, &t);
	int sclass = classify_type(source, &s);

	if (tclass & sclass & TYPE_NUM) {
		if (tclass & TYPE_RESTRICT) {
			/* allowed assignments unfoul */
			if (sclass & TYPE_FOULED && unfoul(s) == t)
				goto Cast;
			if (!restricted_value(*rp, target))
				return 1;
			if (s == t)
				return 1;
		} else if (!(sclass & TYPE_RESTRICT))
			goto Cast;
                if (t == &bool_ctype) {
                        if (is_fouled_type(s))
                                warning((*rp)->pos, "%s degrades to integer",
                                        show_typename(s->ctype.base_type));
                        goto Cast;
                }
		*typediff = "different base types";
		return 0;
	}

	if (tclass == TYPE_PTR) {
		unsigned long mod1, mod2;
		struct symbol *b1, *b2;
		// NULL pointer is always OK
		int is_null = is_null_pointer_constant(*rp);
		if (is_null) {
			if (is_null == NULL_ZERO)
				bad_null(*rp);
			goto Cast;
		}
		if (!(sclass & TYPE_PTR)) {
			*typediff = "different base types";
			return 0;
		}
		b1 = examine_pointer_target(t);
		b2 = examine_pointer_target(s);
		mod1 = target_qualifiers(t);
		mod2 = target_qualifiers(s);
		if (whitelist_pointers(b1, b2)) {
			/*
			 * assignments to/from void * are OK, provided that
			 * we do not remove qualifiers from pointed to [C]
			 * or mix address spaces [sparse].
			 */
			if (t->ctype.as != s->ctype.as) {
				*typediff = "different address spaces";
				return 0;
			}
			/*
			 * If this is a function pointer assignment, it is
			 * actually fine to assign a pointer to const data to
			 * it, as a function pointer points to const data
			 * implicitly, i.e., dereferencing it does not produce
			 * an lvalue.
			 */
			if (b1->type == SYM_FN)
				mod1 |= MOD_CONST;
			if (mod2 & ~mod1) {
				*typediff = "different modifiers";
				return 0;
			}
			goto Cast;
		}
		/* It's OK if the target is more volatile or const than the source */
		*typediff = type_difference(&t->ctype, &s->ctype, 0, mod1);
		if (*typediff)
			return 0;
		return 1;
	}

	if ((tclass & TYPE_COMPOUND) && s == t)
		return 1;

	if (tclass & TYPE_NUM) {
		/* XXX: need to turn into comparison with NULL */
		if (t == &bool_ctype && (sclass & TYPE_PTR))
			goto Cast;
		*typediff = "different base types";
		return 0;
	}
	*typediff = "invalid types";
	return 0;

Cast:
	*rp = cast_to(*rp, target);
	return 1;
}

static int compatible_assignment_types(struct expression *expr, struct symbol *target,
	struct expression **rp, const char *where)
{
	const char *typediff;
	struct symbol *source = degenerate(*rp);

	if (!check_assignment_types(target, rp, &typediff)) {
		warning(expr->pos, "incorrect type in %s (%s)", where, typediff);
		info(expr->pos, "   expected %s", show_typename(target));
		info(expr->pos, "   got %s", show_typename(source));
		*rp = cast_to(*rp, target);
		return 0;
	}

	return 1;
}

static int compatible_transparent_union(struct symbol *target,
	struct expression **rp)
{
	struct symbol *t, *member;
	classify_type(target, &t);
	if (t->type != SYM_UNION || !t->transparent_union)
		return 0;

	FOR_EACH_PTR(t->symbol_list, member) {
		const char *typediff;
		if (check_assignment_types(member, rp, &typediff))
			return 1;
	} END_FOR_EACH_PTR(member);

	return 0;
}

static int compatible_argument_type(struct expression *expr, struct symbol *target,
	struct expression **rp, const char *where)
{
	if (compatible_transparent_union(target, rp))
		return 1;

	return compatible_assignment_types(expr, target, rp, where);
}

static void mark_assigned(struct expression *expr)
{
	struct symbol *sym;

	if (!expr)
		return;
	switch (expr->type) {
	case EXPR_SYMBOL:
		sym = expr->symbol;
		if (!sym)
			return;
		if (sym->type != SYM_NODE)
			return;
		sym->ctype.modifiers |= MOD_ASSIGNED;
		return;

	case EXPR_BINOP:
		mark_assigned(expr->left);
		mark_assigned(expr->right);
		return;
	case EXPR_CAST:
	case EXPR_FORCE_CAST:
		mark_assigned(expr->cast_expression);
		return;
	case EXPR_SLICE:
		mark_assigned(expr->base);
		return;
	default:
		/* Hmm? */
		return;
	}
}

static void evaluate_assign_to(struct expression *left, struct symbol *type)
{
	if (type->ctype.modifiers & MOD_CONST)
		expression_error(left, "assignment to const expression");

	/* We know left is an lvalue, so it's a "preop-*" */
	mark_assigned(left->unop);
}

static struct symbol *evaluate_assignment(struct expression *expr)
{
	struct expression *left = expr->left;
	struct expression *where = expr;
	struct symbol *ltype;

	if (!lvalue_expression(left)) {
		expression_error(expr, "not an lvalue");
		return NULL;
	}

	ltype = left->ctype;

	if (expr->op != '=') {
		if (!evaluate_assign_op(expr))
			return NULL;
	} else {
		if (!compatible_assignment_types(where, ltype, &expr->right, "assignment"))
			return NULL;
	}

	evaluate_assign_to(left, ltype);

	expr->ctype = ltype;
	return ltype;
}

static void examine_fn_arguments(struct symbol *fn)
{
	struct symbol *s;

	FOR_EACH_PTR(fn->arguments, s) {
		struct symbol *arg = evaluate_symbol(s);
		/* Array/function arguments silently degenerate into pointers */
		if (arg) {
			struct symbol *ptr;
			switch(arg->type) {
			case SYM_ARRAY:
			case SYM_FN:
				ptr = alloc_symbol(s->pos, SYM_PTR);
				if (arg->type == SYM_ARRAY)
					ptr->ctype = arg->ctype;
				else
					ptr->ctype.base_type = arg;
				combine_address_space(s->pos, &ptr->ctype.as, s->ctype.as);
				ptr->ctype.modifiers |= s->ctype.modifiers & MOD_PTRINHERIT;

				s->ctype.base_type = ptr;
				s->ctype.as = NULL;
				s->ctype.modifiers &= ~MOD_PTRINHERIT;
				s->bit_size = 0;
				s->examined = 0;
				examine_symbol_type(s);
				break;
			default:
				/* nothing */
				break;
			}
		}
	} END_FOR_EACH_PTR(s);
}

static struct symbol *convert_to_as_mod(struct symbol *sym, struct ident *as, int mod)
{
	/* Take the modifiers of the pointer, and apply them to the member */
	mod |= sym->ctype.modifiers;
	if (sym->ctype.as != as || sym->ctype.modifiers != mod) {
		struct symbol *newsym = alloc_symbol(sym->pos, SYM_NODE);
		*newsym = *sym;
		newsym->ctype.as = as;
		newsym->ctype.modifiers = mod;
		sym = newsym;
	}
	return sym;
}

static struct symbol *create_pointer(struct expression *expr, struct symbol *sym, int degenerate)
{
	struct symbol *node = alloc_symbol(expr->pos, SYM_NODE);
	struct symbol *ptr = alloc_symbol(expr->pos, SYM_PTR);

	node->ctype.base_type = ptr;
	ptr->bit_size = bits_in_pointer;
	ptr->ctype.alignment = pointer_alignment;

	node->bit_size = bits_in_pointer;
	node->ctype.alignment = pointer_alignment;

	access_symbol(sym);
	if (sym->ctype.modifiers & MOD_REGISTER) {
		warning(expr->pos, "taking address of 'register' variable '%s'", show_ident(sym->ident));
		sym->ctype.modifiers &= ~MOD_REGISTER;
	}
	if (sym->type == SYM_NODE) {
		combine_address_space(sym->pos, &ptr->ctype.as, sym->ctype.as);
		ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT;
		sym = sym->ctype.base_type;
	}
	if (degenerate && sym->type == SYM_ARRAY) {
		combine_address_space(sym->pos, &ptr->ctype.as, sym->ctype.as);
		ptr->ctype.modifiers |= sym->ctype.modifiers & MOD_PTRINHERIT;
		sym = sym->ctype.base_type;
	}
	ptr->ctype.base_type = sym;

	return node;
}

/* Arrays degenerate into pointers on pointer arithmetic */
static struct symbol *degenerate(struct expression *expr)
{
	struct symbol *ctype, *base;

	if (!expr)
		return NULL;
	ctype = expr->ctype;
	if (!ctype)
		return NULL;
	base = examine_symbol_type(ctype);
	if (ctype->type == SYM_NODE)
		base = ctype->ctype.base_type;
	/*
	 * Arrays degenerate into pointers to the entries, while
	 * functions degenerate into pointers to themselves.
	 * If array was part of non-lvalue compound, we create a copy
	 * of that compound first and then act as if we were dealing with
	 * the corresponding field in there.
	 */
	switch (base->type) {
	case SYM_ARRAY:
		if (expr->type == EXPR_SLICE) {
			struct symbol *a = alloc_symbol(expr->pos, SYM_NODE);
			struct expression *e0, *e1, *e2, *e3, *e4;

			a->ctype.base_type = expr->base->ctype;
			a->bit_size = expr->base->ctype->bit_size;
			a->array_size = expr->base->ctype->array_size;

			e0 = alloc_expression(expr->pos, EXPR_SYMBOL);
			e0->symbol = a;
			e0->ctype = &lazy_ptr_ctype;

			e1 = alloc_expression(expr->pos, EXPR_PREOP);
			e1->unop = e0;
			e1->op = '*';
			e1->ctype = expr->base->ctype;	/* XXX */

			e2 = alloc_expression(expr->pos, EXPR_ASSIGNMENT);
			e2->left = e1;
			e2->right = expr->base;
			e2->op = '=';
			e2->ctype = expr->base->ctype;

			if (expr->r_bitpos) {
				e3 = alloc_expression(expr->pos, EXPR_BINOP);
				e3->op = '+';
				e3->left = e0;
				e3->right = alloc_const_expression(expr->pos,
							bits_to_bytes(expr->r_bitpos));
				e3->ctype = &lazy_ptr_ctype;
			} else {
				e3 = e0;
			}

			e4 = alloc_expression(expr->pos, EXPR_COMMA);
			e4->left = e2;
			e4->right = e3;
			e4->ctype = &lazy_ptr_ctype;

			expr->unop = e4;
			expr->type = EXPR_PREOP;
			expr->op = '*';
		}
	case SYM_FN:
		if (expr->op != '*' || expr->type != EXPR_PREOP) {
			expression_error(expr, "strange non-value function or array");
			return &bad_ctype;
		}
		*expr = *expr->unop;
		ctype = create_pointer(expr, ctype, 1);
		expr->ctype = ctype;
	default:
		/* nothing */;
	}
	return ctype;
}

static struct symbol *evaluate_addressof(struct expression *expr)
{
	struct expression *op = expr->unop;
	struct symbol *ctype;

	if (op->op != '*' || op->type != EXPR_PREOP) {
		expression_error(expr, "not addressable");
		return NULL;
	}
	ctype = op->ctype;
	*expr = *op->unop;

	if (expr->type == EXPR_SYMBOL) {
		struct symbol *sym = expr->symbol;
		sym->ctype.modifiers |= MOD_ADDRESSABLE;
	}

	/*
	 * symbol expression evaluation is lazy about the type
	 * of the sub-expression, so we may have to generate
	 * the type here if so..
	 */
	if (expr->ctype == &lazy_ptr_ctype) {
		ctype = create_pointer(expr, ctype, 0);
		expr->ctype = ctype;
	}
	return expr->ctype;
}


static struct symbol *evaluate_dereference(struct expression *expr)
{
	struct expression *op = expr->unop;
	struct symbol *ctype = op->ctype, *node, *target;

	/* Simplify: *&(expr) => (expr) */
	if (op->type == EXPR_PREOP && op->op == '&') {
		*expr = *op->unop;
		expr->flags = CEF_NONE;
		return expr->ctype;
	}

	examine_symbol_type(ctype);

	/* Dereferencing a node drops all the node information. */
	if (ctype->type == SYM_NODE)
		ctype = ctype->ctype.base_type;

	target = ctype->ctype.base_type;
	examine_symbol_type(target);

	switch (ctype->type) {
	default:
		expression_error(expr, "cannot dereference this type");
		return NULL;
	case SYM_FN:
		*expr = *op;
		return expr->ctype;
	case SYM_PTR:
		node = alloc_symbol(expr->pos, SYM_NODE);
		node->ctype.modifiers = target->ctype.modifiers & MOD_SPECIFIER;
		merge_type(node, ctype);
		break;

	case SYM_ARRAY:
		if (!lvalue_expression(op)) {
			expression_error(op, "non-lvalue array??");
			return NULL;
		}

		/* Do the implied "addressof" on the array */
		*op = *op->unop;

		/*
		 * When an array is dereferenced, we need to pick
		 * up the attributes of the original node too..
		 */
		node = alloc_symbol(expr->pos, SYM_NODE);
		merge_type(node, op->ctype);
		merge_type(node, ctype);
		break;
	}

	node->bit_size = target->bit_size;
	node->array_size = target->array_size;

	expr->ctype = node;
	return node;
}

/*
 * Unary post-ops: x++ and x--
 */
static struct symbol *evaluate_postop(struct expression *expr)
{
	struct expression *op = expr->unop;
	struct symbol *ctype = op->ctype;
	int class = classify_type(ctype, &ctype);
	int multiply = 0;

	if (!class || class & TYPE_COMPOUND) {
		expression_error(expr, "need scalar for ++/--");
		return NULL;
	}
	if (!lvalue_expression(expr->unop)) {
		expression_error(expr, "need lvalue expression for ++/--");
		return NULL;
	}

	if ((class & TYPE_RESTRICT) && restricted_unop(expr->op, &ctype))
		unrestrict(expr, class, &ctype);

	if (class & TYPE_NUM) {
		multiply = 1;
	} else if (class == TYPE_PTR) {
		struct symbol *target = examine_pointer_target(ctype);
		if (!is_function(target))
			multiply = bits_to_bytes(target->bit_size);
	}

	if (multiply) {
		evaluate_assign_to(op, op->ctype);
		expr->op_value = multiply;
		expr->ctype = ctype;
		return ctype;
	}

	expression_error(expr, "bad argument type for ++/--");
	return NULL;
}

static struct symbol *evaluate_sign(struct expression *expr)
{
	struct symbol *ctype = expr->unop->ctype;
	int class = classify_type(ctype, &ctype);
	unsigned char flags = expr->unop->flags & ~CEF_CONST_MASK;

	/* should be an arithmetic type */
	if (!(class & TYPE_NUM))
		return bad_expr_type(expr);
	if (class & TYPE_RESTRICT)
		goto Restr;
Normal:
	if (!(class & TYPE_FLOAT)) {
		ctype = integer_promotion(ctype);
		expr->unop = cast_to(expr->unop, ctype);
	} else if (expr->op != '~') {
		/* no conversions needed */
	} else {
		return bad_expr_type(expr);
	}
	if (expr->op == '+')
		*expr = *expr->unop;
	expr->flags = flags;
	expr->ctype = ctype;
	return ctype;
Restr:
	if (restricted_unop(expr->op, &ctype))
		unrestrict(expr, class, &ctype);
	goto Normal;
}

static struct symbol *evaluate_preop(struct expression *expr)
{
	struct symbol *ctype = expr->unop->ctype;

	switch (expr->op) {
	case '(':
		*expr = *expr->unop;
		return ctype;

	case '+':
	case '-':
	case '~':
		return evaluate_sign(expr);

	case '*':
		return evaluate_dereference(expr);

	case '&':
		return evaluate_addressof(expr);

	case SPECIAL_INCREMENT:
	case SPECIAL_DECREMENT:
		/*
		 * From a type evaluation standpoint the preops are
		 * the same as the postops
		 */
		return evaluate_postop(expr);

	case '!':
		ctype = degenerate(expr->unop);
		expr->flags = expr->unop->flags & ~CEF_CONST_MASK;
		/*
		 * A logical negation never yields an address constant
		 * [6.6(9)].
		 */
		expr->flags &= ~CEF_ADDR;

		if (is_safe_type(ctype))
			warning(expr->pos, "testing a 'safe expression'");
		if (is_float_type(ctype)) {
			struct expression *arg = expr->unop;
			expr->type = EXPR_COMPARE;
			expr->op = SPECIAL_EQUAL;
			expr->left = arg;
			expr->right = alloc_expression(expr->pos, EXPR_FVALUE);
			expr->right->ctype = ctype;
			expr->right->fvalue = 0;
		} else if (is_fouled_type(ctype)) {
			warning(expr->pos, "%s degrades to integer",
				show_typename(ctype->ctype.base_type));
		}
		/* the result is int [6.5.3.3(5)]*/
		ctype = &int_ctype;
		break;

	default:
		break;
	}
	expr->ctype = ctype;
	return ctype;
}

static struct symbol *find_identifier(struct ident *ident, struct symbol_list *_list, int *offset)
{
	struct ptr_list *head = (struct ptr_list *)_list;
	struct ptr_list *list = head;

	if (!head)
		return NULL;
	do {
		int i;
		for (i = 0; i < list->nr; i++) {
			struct symbol *sym = (struct symbol *) list->list[i];
			if (sym->ident) {
				if (sym->ident != ident)
					continue;
				*offset = sym->offset;
				return sym;
			} else {
				struct symbol *ctype = sym->ctype.base_type;
				struct symbol *sub;
				if (!ctype)
					continue;
				if (ctype->type != SYM_UNION && ctype->type != SYM_STRUCT)
					continue;
				sub = find_identifier(ident, ctype->symbol_list, offset);
				if (!sub)
					continue;
				*offset += sym->offset;
				return sub;
			}	
		}
	} while ((list = list->next) != head);
	return NULL;
}

static struct expression *evaluate_offset(struct expression *expr, unsigned long offset)
{
	struct expression *add;

	/*
	 * Create a new add-expression
	 *
	 * NOTE! Even if we just add zero, we need a new node
	 * for the member pointer, since it has a different
	 * type than the original pointer. We could make that
	 * be just a cast, but the fact is, a node is a node,
	 * so we might as well just do the "add zero" here.
	 */
	add = alloc_expression(expr->pos, EXPR_BINOP);
	add->op = '+';
	add->left = expr;
	add->right = alloc_expression(expr->pos, EXPR_VALUE);
	add->right->ctype = &int_ctype;
	add->right->value = offset;

	/*
	 * The ctype of the pointer will be lazily evaluated if
	 * we ever take the address of this member dereference..
	 */
	add->ctype = &lazy_ptr_ctype;
	/*
	 * The resulting address of a member access through an address
	 * constant is an address constant again [6.6(9)].
	 */
	add->flags = expr->flags;

	return add;
}

/* structure/union dereference */
static struct symbol *evaluate_member_dereference(struct expression *expr)
{
	int offset;
	struct symbol *ctype, *member;
	struct expression *deref = expr->deref, *add;
	struct ident *ident = expr->member;
	struct ident *address_space;
	unsigned int mod;

	if (!evaluate_expression(deref))
		return NULL;
	if (!ident) {
		expression_error(expr, "bad member name");
		return NULL;
	}

	ctype = deref->ctype;
	examine_symbol_type(ctype);
	address_space = ctype->ctype.as;
	mod = ctype->ctype.modifiers;
	if (ctype->type == SYM_NODE) {
		ctype = ctype->ctype.base_type;
		combine_address_space(deref->pos, &address_space, ctype->ctype.as);
		mod |= ctype->ctype.modifiers;
	}
	if (!ctype || (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION)) {
		expression_error(expr, "expected structure or union");
		return NULL;
	}
	offset = 0;
	member = find_identifier(ident, ctype->symbol_list, &offset);
	if (!member) {
		const char *type = ctype->type == SYM_STRUCT ? "struct" : "union";
		const char *name = "<unnamed>";
		int namelen = 9;
		if (ctype->ident) {
			name = ctype->ident->name;
			namelen = ctype->ident->len;
		}
		if (ctype->symbol_list)
			expression_error(expr, "no member '%s' in %s %.*s",
				show_ident(ident), type, namelen, name);
		else
			expression_error(expr, "using member '%s' in "
				"incomplete %s %.*s", show_ident(ident),
				type, namelen, name);
		return NULL;
	}

	/*
	 * The member needs to take on the address space and modifiers of
	 * the "parent" type.
	 */
	member = convert_to_as_mod(member, address_space, mod);
	ctype = get_base_type(member);

	if (!lvalue_expression(deref)) {
		if (deref->type != EXPR_SLICE) {
			expr->base = deref;
			expr->r_bitpos = 0;
		} else {
			expr->base = deref->base;
			expr->r_bitpos = deref->r_bitpos;
		}
		expr->r_bitpos += bytes_to_bits(offset);
		expr->type = EXPR_SLICE;
		expr->r_nrbits = member->bit_size;
		expr->r_bitpos += member->bit_offset;
		expr->ctype = member;
		return member;
	}

	deref = deref->unop;
	expr->deref = deref;

	add = evaluate_offset(deref, offset);
	expr->type = EXPR_PREOP;
	expr->op = '*';
	expr->unop = add;

	expr->ctype = member;
	return member;
}

static int is_promoted(struct expression *expr)
{
	while (1) {
		switch (expr->type) {
		case EXPR_BINOP:
		case EXPR_SELECT:
		case EXPR_CONDITIONAL:
			return 1;
		case EXPR_COMMA:
			expr = expr->right;
			continue;
		case EXPR_PREOP:
			switch (expr->op) {
			case '(':
				expr = expr->unop;
				continue;
			case '+':
			case '-':
			case '~':
				return 1;
			default:
				return 0;
			}
		default:
			return 0;
		}
	}
}


static struct symbol *evaluate_cast(struct expression *);

static struct symbol *evaluate_type_information(struct expression *expr)
{
	struct symbol *sym = expr->cast_type;
	if (!sym) {
		sym = evaluate_expression(expr->cast_expression);
		if (!sym)
			return NULL;
		/*
		 * Expressions of restricted types will possibly get
		 * promoted - check that here
		 */
		if (is_restricted_type(sym)) {
			if (sym->bit_size < bits_in_int && is_promoted(expr))
				sym = &int_ctype;
		} else if (is_fouled_type(sym)) {
			sym = &int_ctype;
		}
	}
	examine_symbol_type(sym);
	if (is_bitfield_type(sym)) {
		expression_error(expr, "trying to examine bitfield type");
		return NULL;
	}
	return sym;
}

static struct symbol *evaluate_sizeof(struct expression *expr)
{
	struct symbol *type;
	int size;

	type = evaluate_type_information(expr);
	if (!type)
		return NULL;

	size = type->bit_size;

	if (size < 0 && is_void_type(type)) {
		if (Wpointer_arith)
			warning(expr->pos, "expression using sizeof(void)");
		size = bits_in_char;
	}

	if (is_bool_type(type)) {
		if (Wsizeof_bool)
			warning(expr->pos, "expression using sizeof _Bool");
		size = bits_to_bytes(bits_in_bool) * bits_in_char;
	}

	if (is_function(type->ctype.base_type)) {
		if (Wpointer_arith)
			warning(expr->pos, "expression using sizeof on a function");
		size = bits_in_char;
	}

	if (is_array_type(type) && size < 0) {	// VLA, 1-dimension only
		struct expression *base, *size;
		struct symbol *base_type;

		if (type->type == SYM_NODE)
			type = type->ctype.base_type;	// strip the SYM_NODE
		base_type = get_base_type(type);
		if (!base_type)
			goto error;
		if (base_type->bit_size <= 0) {
			base = alloc_expression(expr->pos, EXPR_SIZEOF);
			base->cast_type = base_type;
			if (!evaluate_sizeof(base))
				goto error;
		} else {
			base = alloc_expression(expr->pos, EXPR_VALUE);
			base->value = bits_to_bytes(base_type->bit_size);
			base->ctype = size_t_ctype;
		}
		size = alloc_expression(expr->pos, EXPR_CAST);
		size->cast_type = size_t_ctype;
		size->cast_expression = type->array_size;
		if (!evaluate_expression(size))
			goto error;
		expr->left = size;
		expr->right = base;
		expr->type = EXPR_BINOP;
		expr->op = '*';
		return expr->ctype = size_t_ctype;
	}

error:
	if ((size < 0) || (size & (bits_in_char - 1)))
		expression_error(expr, "cannot size expression");

	expr->type = EXPR_VALUE;
	expr->value = bits_to_bytes(size);
	expr->taint = 0;
	expr->ctype = size_t_ctype;
	return size_t_ctype;
}

static struct symbol *evaluate_ptrsizeof(struct expression *expr)
{
	struct symbol *type;
	int size;

	type = evaluate_type_information(expr);
	if (!type)
		return NULL;

	if (type->type == SYM_NODE)
		type = type->ctype.base_type;
	if (!type)
		return NULL;
	switch (type->type) {
	case SYM_ARRAY:
		break;
	case SYM_PTR:
		type = get_base_type(type);
		if (type)
			break;
	default:
		expression_error(expr, "expected pointer expression");
		return NULL;
	}
	size = type->bit_size;
	if (size & (bits_in_char-1))
		size = 0;
	expr->type = EXPR_VALUE;
	expr->value = bits_to_bytes(size);
	expr->taint = 0;
	expr->ctype = size_t_ctype;
	return size_t_ctype;
}

static struct symbol *evaluate_alignof(struct expression *expr)
{
	struct symbol *type;

	type = evaluate_type_information(expr);
	if (!type)
		return NULL;

	expr->type = EXPR_VALUE;
	expr->value = type->ctype.alignment;
	expr->taint = 0;
	expr->ctype = size_t_ctype;
	return size_t_ctype;
}

static int evaluate_arguments(struct symbol *fn, struct expression_list *head)
{
	struct expression *expr;
	struct symbol_list *argument_types = fn->arguments;
	struct symbol *argtype;
	int i = 1;

	PREPARE_PTR_LIST(argument_types, argtype);
	FOR_EACH_PTR (head, expr) {
		struct expression **p = THIS_ADDRESS(expr);
		struct symbol *ctype, *target;
		ctype = evaluate_expression(expr);

		if (!ctype)
			return 0;

		target = argtype;
		if (!target) {
			struct symbol *type;
			int class = classify_type(ctype, &type);
			if (is_int(class)) {
				*p = cast_to(expr, integer_promotion(type));
			} else if (class & TYPE_FLOAT) {
				unsigned long mod = type->ctype.modifiers;
				if (!(mod & (MOD_LONG_ALL)))
					*p = cast_to(expr, &double_ctype);
			} else if (class & TYPE_PTR) {
				if (expr->ctype == &null_ctype)
					*p = cast_to(expr, &ptr_ctype);
				else
					degenerate(expr);
			}
		} else if (!target->forced_arg){
			static char where[30];
			examine_symbol_type(target);
			sprintf(where, "argument %d", i);
			compatible_argument_type(expr, target, p, where);
		}

		i++;
		NEXT_PTR_LIST(argtype);
	} END_FOR_EACH_PTR(expr);
	FINISH_PTR_LIST(argtype);
	return 1;
}

static void convert_index(struct expression *e)
{
	struct expression *child = e->idx_expression;
	unsigned from = e->idx_from;
	unsigned to = e->idx_to + 1;
	e->type = EXPR_POS;
	e->init_offset = from * bits_to_bytes(e->ctype->bit_size);
	e->init_nr = to - from;
	e->init_expr = child;
}

static void convert_ident(struct expression *e)
{
	struct expression *child = e->ident_expression;
	int offset = e->offset;

	e->type = EXPR_POS;
	e->init_offset = offset;
	e->init_nr = 1;
	e->init_expr = child;
}

static void convert_designators(struct expression *e)
{
	while (e) {
		if (e->type == EXPR_INDEX)
			convert_index(e);
		else if (e->type == EXPR_IDENTIFIER)
			convert_ident(e);
		else
			break;
		e = e->init_expr;
	}
}

static void excess(struct expression *e, const char *s)
{
	warning(e->pos, "excessive elements in %s initializer", s);
}

/*
 * implicit designator for the first element
 */
static struct expression *first_subobject(struct symbol *ctype, int class,
					  struct expression **v)
{
	struct expression *e = *v, *new;

	if (ctype->type == SYM_NODE)
		ctype = ctype->ctype.base_type;

	if (class & TYPE_PTR) { /* array */
		if (!ctype->bit_size)
			return NULL;
		new = alloc_expression(e->pos, EXPR_INDEX);
		new->idx_expression = e;
		new->ctype = ctype->ctype.base_type;
	} else  {
		struct symbol *field, *p;
		PREPARE_PTR_LIST(ctype->symbol_list, p);
		while (p && !p->ident && is_bitfield_type(p))
			NEXT_PTR_LIST(p);
		field = p;
		FINISH_PTR_LIST(p);
		if (!field)
			return NULL;
		new = alloc_expression(e->pos, EXPR_IDENTIFIER);
		new->ident_expression = e;
		new->field = new->ctype = field;
		new->offset = field->offset;
	}
	*v = new;
	return new;
}

/*
 * sanity-check explicit designators; return the innermost one or NULL
 * in case of error.  Assign types.
 */
static struct expression *check_designators(struct expression *e,
					    struct symbol *ctype)
{
	struct expression *last = NULL;
	const char *err;
	while (1) {
		if (ctype->type == SYM_NODE)
			ctype = ctype->ctype.base_type;
		if (e->type == EXPR_INDEX) {
			struct symbol *type;
			if (ctype->type != SYM_ARRAY) {
				err = "array index in non-array";
				break;
			}
			type = ctype->ctype.base_type;
			if (ctype->bit_size >= 0 && type->bit_size >= 0) {
				unsigned offset = array_element_offset(type->bit_size, e->idx_to);
				if (offset >= ctype->bit_size) {
					err = "index out of bounds in";
					break;
				}
			}
			e->ctype = ctype = type;
			ctype = type;
			last = e;
			if (!e->idx_expression) {
				err = "invalid";
				break;
			}
			e = e->idx_expression;
		} else if (e->type == EXPR_IDENTIFIER) {
			int offset = 0;
			if (ctype->type != SYM_STRUCT && ctype->type != SYM_UNION) {
				err = "field name not in struct or union";
				break;
			}
			ctype = find_identifier(e->expr_ident, ctype->symbol_list, &offset);
			if (!ctype) {
				err = "unknown field name in";
				break;
			}
			e->offset = offset;
			e->field = e->ctype = ctype;
			last = e;
			if (!e->ident_expression) {
				err = "invalid";
				break;
			}
			e = e->ident_expression;
		} else if (e->type == EXPR_POS) {
			err = "internal front-end error: EXPR_POS in";
			break;
		} else
			return last;
	}
	expression_error(e, "%s initializer", err);
	return NULL;
}

/*
 * choose the next subobject to initialize.
 *
 * Get designators for next element, switch old ones to EXPR_POS.
 * Return the resulting expression or NULL if we'd run out of subobjects.
 * The innermost designator is returned in *v.  Designators in old
 * are assumed to be already sanity-checked.
 */
static struct expression *next_designators(struct expression *old,
			     struct symbol *ctype,
			     struct expression *e, struct expression **v)
{
	struct expression *new = NULL;

	if (!old)
		return NULL;
	if (old->type == EXPR_INDEX) {
		struct expression *copy;
		unsigned n;

		copy = next_designators(old->idx_expression,
					old->ctype, e, v);
		if (!copy) {
			n = old->idx_to + 1;
			if (array_element_offset(old->ctype->bit_size, n) == ctype->bit_size) {
				convert_index(old);
				return NULL;
			}
			copy = e;
			*v = new = alloc_expression(e->pos, EXPR_INDEX);
		} else {
			n = old->idx_to;
			new = alloc_expression(e->pos, EXPR_INDEX);
		}

		new->idx_from = new->idx_to = n;
		new->idx_expression = copy;
		new->ctype = old->ctype;
		convert_index(old);
	} else if (old->type == EXPR_IDENTIFIER) {
		struct expression *copy;
		struct symbol *field;
		int offset = 0;

		copy = next_designators(old->ident_expression,
					old->ctype, e, v);
		if (!copy) {
			field = old->field->next_subobject;
			if (!field) {
				convert_ident(old);
				return NULL;
			}
			copy = e;
			*v = new = alloc_expression(e->pos, EXPR_IDENTIFIER);
			/*
			 * We can't necessarily trust "field->offset",
			 * because the field might be in an anonymous
			 * union, and the field offset is then the offset
			 * within that union.
			 *
			 * The "old->offset - old->field->offset"
			 * would be the offset of such an anonymous
			 * union.
			 */
			offset = old->offset - old->field->offset;
		} else {
			field = old->field;
			new = alloc_expression(e->pos, EXPR_IDENTIFIER);
		}

		new->field = field;
		new->expr_ident = field->ident;
		new->ident_expression = copy;
		new->ctype = field;
		new->offset = field->offset + offset;
		convert_ident(old);
	}
	return new;
}

static int handle_initializer(struct expression **ep, int nested,
		int class, struct symbol *ctype, unsigned long mods);

/*
 * deal with traversing subobjects [6.7.8(17,18,20)]
 */
static void handle_list_initializer(struct expression *expr,
		int class, struct symbol *ctype, unsigned long mods)
{
	struct expression *e, *last = NULL, *top = NULL, *next;
	int jumped = 0;

	FOR_EACH_PTR(expr->expr_list, e) {
		struct expression **v;
		struct symbol *type;
		int lclass;

		if (e->type != EXPR_INDEX && e->type != EXPR_IDENTIFIER) {
			struct symbol *struct_sym;
			if (!top) {
				top = e;
				last = first_subobject(ctype, class, &top);
			} else {
				last = next_designators(last, ctype, e, &top);
			}
			if (!last) {
				excess(e, class & TYPE_PTR ? "array" :
							"struct or union");
				DELETE_CURRENT_PTR(e);
				continue;
			}
			struct_sym = ctype->type == SYM_NODE ? ctype->ctype.base_type : ctype;
			if (Wdesignated_init && struct_sym->designated_init)
				warning(e->pos, "%s%.*s%spositional init of field in %s %s, declared with attribute designated_init",
					ctype->ident ? "in initializer for " : "",
					ctype->ident ? ctype->ident->len : 0,
					ctype->ident ? ctype->ident->name : "",
					ctype->ident ? ": " : "",
					get_type_name(struct_sym->type),
					show_ident(struct_sym->ident));
			if (jumped) {
				warning(e->pos, "advancing past deep designator");
				jumped = 0;
			}
			REPLACE_CURRENT_PTR(e, last);
		} else {
			next = check_designators(e, ctype);
			if (!next) {
				DELETE_CURRENT_PTR(e);
				continue;
			}
			top = next;
			/* deeper than one designator? */
			jumped = top != e;
			convert_designators(last);
			last = e;
		}

found:
		lclass = classify_type(top->ctype, &type);
		if (top->type == EXPR_INDEX)
			v = &top->idx_expression;
		else
			v = &top->ident_expression;

		mods |= ctype->ctype.modifiers & MOD_STORAGE;
		if (handle_initializer(v, 1, lclass, top->ctype, mods))
			continue;

		if (!(lclass & TYPE_COMPOUND)) {
			warning(e->pos, "bogus scalar initializer");
			DELETE_CURRENT_PTR(e);
			continue;
		}

		next = first_subobject(type, lclass, v);
		if (next) {
			warning(e->pos, "missing braces around initializer");
			top = next;
			goto found;
		}

		DELETE_CURRENT_PTR(e);
		excess(e, lclass & TYPE_PTR ? "array" : "struct or union");

	} END_FOR_EACH_PTR(e);

	convert_designators(last);
	expr->ctype = ctype;
}

static int is_string_literal(struct expression **v)
{
	struct expression *e = *v;
	while (e && e->type == EXPR_PREOP && e->op == '(')
		e = e->unop;
	if (!e || e->type != EXPR_STRING)
		return 0;
	if (e != *v && Wparen_string)
		warning(e->pos,
			"array initialized from parenthesized string constant");
	*v = e;
	return 1;
}

/*
 * We want a normal expression, possibly in one layer of braces.  Warn
 * if the latter happens inside a list (it's legal, but likely to be
 * an effect of screwup).  In case of anything not legal, we are definitely
 * having an effect of screwup, so just fail and let the caller warn.
 */
static struct expression *handle_scalar(struct expression *e, int nested)
{
	struct expression *v = NULL, *p;
	int count = 0;

	/* normal case */
	if (e->type != EXPR_INITIALIZER)
		return e;

	FOR_EACH_PTR(e->expr_list, p) {
		if (!v)
			v = p;
		count++;
	} END_FOR_EACH_PTR(p);
	if (count != 1)
		return NULL;
	switch(v->type) {
	case EXPR_INITIALIZER:
	case EXPR_INDEX:
	case EXPR_IDENTIFIER:
		return NULL;
	default:
		break;
	}
	if (nested)
		warning(e->pos, "braces around scalar initializer");
	return v;
}

/*
 * deal with the cases that don't care about subobjects:
 * scalar <- assignment expression, possibly in braces [6.7.8(11)]
 * character array <- string literal, possibly in braces [6.7.8(14)]
 * struct or union <- assignment expression of compatible type [6.7.8(13)]
 * compound type <- initializer list in braces [6.7.8(16)]
 * The last one punts to handle_list_initializer() which, in turn will call
 * us for individual elements of the list.
 *
 * We do not handle 6.7.8(15) (wide char array <- wide string literal) for
 * the lack of support of wide char stuff in general.
 *
 * One note: we need to take care not to evaluate a string literal until
 * we know that we *will* handle it right here.  Otherwise we would screw
 * the cases like struct { struct {char s[10]; ...} ...} initialized with
 * { "string", ...} - we need to preserve that string literal recognizable
 * until we dig into the inner struct.
 */
static int handle_initializer(struct expression **ep, int nested,
		int class, struct symbol *ctype, unsigned long mods)
{
	int is_string = is_string_type(ctype);
	struct expression *e = *ep, *p;
	struct symbol *type;

	if (!e)
		return 0;

	/* scalar */
	if (!(class & TYPE_COMPOUND)) {
		e = handle_scalar(e, nested);
		if (!e)
			return 0;
		*ep = e;
		if (!evaluate_expression(e))
			return 1;
		compatible_assignment_types(e, ctype, ep, "initializer");
		/*
		 * Initializers for static storage duration objects
		 * shall be constant expressions or a string literal [6.7.8(4)].
		 */
		mods |= ctype->ctype.modifiers;
		mods &= (MOD_TOPLEVEL | MOD_STATIC);
		if (mods && !(e->flags & (CEF_ACE | CEF_ADDR)))
			if (Wconstexpr_not_const)
				warning(e->pos, "non-constant initializer for static object");

		return 1;
	}

	/*
	 * sublist; either a string, or we dig in; the latter will deal with
	 * pathologies, so we don't need anything fancy here.
	 */
	if (e->type == EXPR_INITIALIZER) {
		if (is_string) {
			struct expression *v = NULL;
			int count = 0;

			FOR_EACH_PTR(e->expr_list, p) {
				if (!v)
					v = p;
				count++;
			} END_FOR_EACH_PTR(p);
			if (count == 1 && is_string_literal(&v)) {
				*ep = e = v;
				goto String;
			}
		}
		handle_list_initializer(e, class, ctype, mods);
		return 1;
	}

	/* string */
	if (is_string_literal(&e)) {
		/* either we are doing array of char, or we'll have to dig in */
		if (is_string) {
			*ep = e;
			goto String;
		}
		return 0;
	}
	/* struct or union can be initialized by compatible */
	if (class != TYPE_COMPOUND)
		return 0;
	type = evaluate_expression(e);
	if (!type)
		return 0;
	if (ctype->type == SYM_NODE)
		ctype = ctype->ctype.base_type;
	if (type->type == SYM_NODE)
		type = type->ctype.base_type;
	if (ctype == type)
		return 1;
	return 0;

String:
	p = alloc_expression(e->pos, EXPR_STRING);
	*p = *e;
	type = evaluate_expression(p);
	if (ctype->bit_size != -1) {
		if (ctype->bit_size + bits_in_char < type->bit_size)
			warning(e->pos,
				"too long initializer-string for array of char");
		else if (Winit_cstring && ctype->bit_size + bits_in_char == type->bit_size) {
			warning(e->pos,
				"too long initializer-string for array of char(no space for nul char)");
		}
	}
	*ep = p;
	return 1;
}

static void evaluate_initializer(struct symbol *ctype, struct expression **ep)
{
	struct symbol *type;
	int class = classify_type(ctype, &type);
	if (!handle_initializer(ep, 0, class, ctype, 0))
		expression_error(*ep, "invalid initializer");
}

static struct symbol *cast_to_bool(struct expression *expr)
{
	struct expression *old = expr->cast_expression;
	struct expression *zero;
	struct symbol *otype;
	int oclass = classify_type(degenerate(old), &otype);
	struct symbol *ctype;

	if (oclass & TYPE_COMPOUND)
		return NULL;

	zero = alloc_const_expression(expr->pos, 0);
	expr->op = SPECIAL_NOTEQUAL;
	ctype = usual_conversions(expr->op, old, zero,
			oclass, TYPE_NUM, otype, zero->ctype);
	expr->type = EXPR_COMPARE;
	expr->left = cast_to(old, ctype);
	expr->right = cast_to(zero, ctype);

	return expr->ctype;
}

static int cast_flags(struct expression *expr, struct expression *old)
{
	struct symbol *t;
	int class;
	int flags = CEF_NONE;

	class = classify_type(expr->ctype, &t);
	if (class & TYPE_NUM) {
		flags = old->flags & ~CEF_CONST_MASK;
		/*
		 * Casts to numeric types never result in address
		 * constants [6.6(9)].
		 */
		flags &= ~CEF_ADDR;

		/*
		 * As an extension, treat address constants cast to
		 * integer type as an arithmetic constant.
		 */
		if (old->flags & CEF_ADDR)
			flags = CEF_ACE;

		/*
		 * Cast to float type -> not an integer constant
		 * expression [6.6(6)].
		 */
		if (class & TYPE_FLOAT)
			flags &= ~CEF_CLR_ICE;
		/*
		 * Casts of float literals to integer type results in
		 * a constant integer expression [6.6(6)].
		 */
		else if (old->flags & CEF_FLOAT)
			flags = CEF_SET_ICE;
	} else if (class & TYPE_PTR) {
		/*
		 * Casts of integer literals to pointer type yield
		 * address constants [6.6(9)].
		 *
		 * As an extension, treat address constants cast to a
		 * different pointer type as address constants again.
		 *
		 * As another extension, treat integer constant
		 * expressions (in contrast to literals) cast to
		 * pointer type as address constants.
		 */
		if (old->flags & (CEF_ICE | CEF_ADDR))
			flags = CEF_ADDR;
	}

	return flags;
}

static struct symbol *evaluate_cast(struct expression *expr)
{
	struct expression *source = expr->cast_expression;
	struct symbol *ctype;
	struct symbol *ttype, *stype;
	int tclass, sclass;
	struct ident *tas = NULL, *sas = NULL;

	if (!source)
		return NULL;

	/*
	 * Special case: a cast can be followed by an
	 * initializer, in which case we need to pass
	 * the type value down to that initializer rather
	 * than trying to evaluate it as an expression
	 *
	 * A more complex case is when the initializer is
	 * dereferenced as part of a post-fix expression.
	 * We need to produce an expression that can be dereferenced.
	 */
	if (source->type == EXPR_INITIALIZER) {
		struct symbol *sym = expr->cast_type;
		struct expression *addr = alloc_expression(expr->pos, EXPR_SYMBOL);

		sym->initializer = source;
		evaluate_symbol(sym);

		addr->ctype = &lazy_ptr_ctype;	/* Lazy eval */
		addr->symbol = sym;
		if (sym->ctype.modifiers & MOD_TOPLEVEL)
			addr->flags |= CEF_ADDR;

		expr->type = EXPR_PREOP;
		expr->op = '*';
		expr->unop = addr;
		expr->ctype = sym;

		return sym;
	}

	ctype = examine_symbol_type(expr->cast_type);
	expr->ctype = ctype;
	expr->cast_type = ctype;

	evaluate_expression(source);
	degenerate(source);

	tclass = classify_type(ctype, &ttype);

	expr->flags = cast_flags(expr, source);

	/*
	 * You can always throw a value away by casting to
	 * "void" - that's an implicit "force". Note that
	 * the same is _not_ true of "void *".
	 */
	if (ttype == &void_ctype)
		goto out;

	stype = source->ctype;
	if (!stype) {
		expression_error(expr, "cast from unknown type");
		goto out;
	}
	sclass = classify_type(stype, &stype);

	if (expr->type == EXPR_FORCE_CAST)
		goto out;

	if (tclass & (TYPE_COMPOUND | TYPE_FN))
		warning(expr->pos, "cast to non-scalar");

	if (sclass & TYPE_COMPOUND)
		warning(expr->pos, "cast from non-scalar");

	/* allowed cast unfouls */
	if (sclass & TYPE_FOULED)
		stype = unfoul(stype);

	if (ttype != stype) {
		if ((tclass & TYPE_RESTRICT) && restricted_value(source, ttype))
			warning(expr->pos, "cast to %s",
				show_typename(ttype));
		if (sclass & TYPE_RESTRICT) {
			if (ttype == &bool_ctype) {
				if (sclass & TYPE_FOULED)
					warning(expr->pos, "%s degrades to integer",
						show_typename(stype));
			} else {
				warning(expr->pos, "cast from %s",
					show_typename(stype));
			}
		}
	}

	if (ttype == &ulong_ctype && !Wcast_from_as)
		tas = &bad_address_space;
	else if (tclass == TYPE_PTR) {
		examine_pointer_target(ttype);
		tas = ttype->ctype.as;
	}

	if (stype == &ulong_ctype && !Wcast_from_as)
		sas = &bad_address_space;
	else if (sclass == TYPE_PTR) {
		examine_pointer_target(stype);
		sas = stype->ctype.as;
	}

	if (!tas && valid_as(sas))
		warning(expr->pos, "cast removes address space '%s' of expression", show_as(sas));
	if (valid_as(tas) && valid_as(sas) && tas != sas)
		warning(expr->pos, "cast between address spaces (%s -> %s)", show_as(sas), show_as(tas));
	if (valid_as(tas) && !sas &&
	    !is_null_pointer_constant(source) && Wcast_to_as)
		warning(expr->pos,
			"cast adds address space '%s' to expression", show_as(tas));

	if (!(ttype->ctype.modifiers & MOD_PTRINHERIT) && tclass == TYPE_PTR &&
	    !tas && (source->flags & CEF_ICE)) {
		if (ttype->ctype.base_type == &void_ctype) {
			if (is_zero_constant(source)) {
				/* NULL */
				expr->type = EXPR_VALUE;
				expr->ctype = &null_ctype;
				expr->value = 0;
				return expr->ctype;
			}
		}
	}

	if (ttype == &bool_ctype)
		cast_to_bool(expr);

	// checks pointers to restricted
	while (Wbitwise_pointer && tclass == TYPE_PTR && sclass == TYPE_PTR) {
		tclass = classify_type(ttype->ctype.base_type, &ttype);
		sclass = classify_type(stype->ctype.base_type, &stype);
		if (ttype == stype)
			break;
		if (!ttype || !stype)
			break;
		if (ttype == &void_ctype || stype == &void_ctype)
			break;
		if (tclass & TYPE_RESTRICT) {
			warning(expr->pos, "cast to %s", show_typename(ctype));
			break;
		}
		if (sclass & TYPE_RESTRICT) {
			warning(expr->pos, "cast from %s", show_typename(source->ctype));
			break;
		}
	}
out:
	return ctype;
}

/*
 * Evaluate a call expression with a symbol. This
 * should expand inline functions, and evaluate
 * builtins.
 */
static int evaluate_symbol_call(struct expression *expr)
{
	struct expression *fn = expr->fn;
	struct symbol *ctype = fn->ctype;

	if (fn->type != EXPR_PREOP)
		return 0;

	if (ctype->op && ctype->op->evaluate)
		return ctype->op->evaluate(expr);

	if (ctype->ctype.modifiers & MOD_INLINE) {
		int ret;
		struct symbol *curr = current_fn;

		if (ctype->definition)
			ctype = ctype->definition;

		current_fn = ctype->ctype.base_type;

		ret = inline_function(expr, ctype);

		/* restore the old function */
		current_fn = curr;
		return ret;
	}

	return 0;
}

static struct symbol *evaluate_call(struct expression *expr)
{
	int args, fnargs;
	struct symbol *ctype, *sym;
	struct expression *fn = expr->fn;
	struct expression_list *arglist = expr->args;

	if (!evaluate_expression(fn))
		return NULL;
	sym = ctype = fn->ctype;
	if (ctype->type == SYM_NODE)
		ctype = ctype->ctype.base_type;
	if (ctype->type == SYM_PTR)
		ctype = get_base_type(ctype);

	if (ctype->type != SYM_FN) {
		struct expression *arg;
		expression_error(expr, "not a function %s",
			     show_ident(sym->ident));
		/* do typechecking in arguments */
		FOR_EACH_PTR (arglist, arg) {
			evaluate_expression(arg);
		} END_FOR_EACH_PTR(arg);
		return NULL;
	}

	examine_fn_arguments(ctype);
        if (sym->type == SYM_NODE && fn->type == EXPR_PREOP &&
	    sym->op && sym->op->args) {
		if (!sym->op->args(expr))
			return NULL;
	} else {
		if (!evaluate_arguments(ctype, arglist))
			return NULL;
		args = expression_list_size(expr->args);
		fnargs = symbol_list_size(ctype->arguments);
		if (args < fnargs) {
			expression_error(expr,
				     "not enough arguments for function %s",
				     show_ident(sym->ident));
			return NULL;
		}
		if (args > fnargs && !ctype->variadic)
			expression_error(expr,
				     "too many arguments for function %s",
				     show_ident(sym->ident));
	}
	expr->ctype = ctype->ctype.base_type;
	if (sym->type == SYM_NODE) {
		if (evaluate_symbol_call(expr))
			return expr->ctype;
	}
	return expr->ctype;
}

static struct symbol *evaluate_offsetof(struct expression *expr)
{
	struct expression *e = expr->down;
	struct symbol *ctype = expr->in;
	int class;

	if (expr->op == '.') {
		struct symbol *field;
		int offset = 0;
		if (!ctype) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}
		examine_symbol_type(ctype);
		class = classify_type(ctype, &ctype);
		if (class != TYPE_COMPOUND) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}

		field = find_identifier(expr->ident, ctype->symbol_list, &offset);
		if (!field) {
			expression_error(expr, "unknown member");
			return NULL;
		}
		ctype = field;
		expr->type = EXPR_VALUE;
		expr->flags = CEF_SET_ICE;
		expr->value = offset;
		expr->taint = 0;
		expr->ctype = size_t_ctype;
	} else {
		if (!ctype) {
			expression_error(expr, "expected structure or union");
			return NULL;
		}
		examine_symbol_type(ctype);
		class = classify_type(ctype, &ctype);
		if (class != (TYPE_COMPOUND | TYPE_PTR)) {
			expression_error(expr, "expected array");
			return NULL;
		}
		ctype = ctype->ctype.base_type;
		if (!expr->index) {
			expr->type = EXPR_VALUE;
			expr->flags = CEF_SET_ICE;
			expr->value = 0;
			expr->taint = 0;
			expr->ctype = size_t_ctype;
		} else {
			struct expression *idx = expr->index, *m;
			struct symbol *i_type = evaluate_expression(idx);
			unsigned old_idx_flags;
			int i_class = classify_type(i_type, &i_type);

			if (!is_int(i_class)) {
				expression_error(expr, "non-integer index");
				return NULL;
			}
			unrestrict(idx, i_class, &i_type);
			old_idx_flags = idx->flags;
			idx = cast_to(idx, size_t_ctype);
			idx->flags = old_idx_flags;
			m = alloc_const_expression(expr->pos,
						   bits_to_bytes(ctype->bit_size));
			m->ctype = size_t_ctype;
			m->flags = CEF_SET_INT;
			expr->type = EXPR_BINOP;
			expr->left = idx;
			expr->right = m;
			expr->op = '*';
			expr->ctype = size_t_ctype;
			expr->flags = m->flags & idx->flags & ~CEF_CONST_MASK;
		}
	}
	if (e) {
		struct expression *copy = __alloc_expression(0);
		*copy = *expr;
		if (e->type == EXPR_OFFSETOF)
			e->in = ctype;
		if (!evaluate_expression(e))
			return NULL;
		expr->type = EXPR_BINOP;
		expr->flags = e->flags & copy->flags & ~CEF_CONST_MASK;
		expr->op = '+';
		expr->ctype = size_t_ctype;
		expr->left = copy;
		expr->right = e;
	}
	return size_t_ctype;
}

struct symbol *evaluate_expression(struct expression *expr)
{
	if (!expr)
		return NULL;
	if (expr->ctype)
		return expr->ctype;

	switch (expr->type) {
	case EXPR_VALUE:
	case EXPR_FVALUE:
		expression_error(expr, "value expression without a type");
		return NULL;
	case EXPR_STRING:
		return evaluate_string(expr);
	case EXPR_SYMBOL:
		return evaluate_symbol_expression(expr);
	case EXPR_BINOP:
		evaluate_expression(expr->left);
		evaluate_expression(expr->right);
		if (!valid_subexpr_type(expr))
			return NULL;
		return evaluate_binop(expr);
	case EXPR_LOGICAL:
		return evaluate_logical(expr);
	case EXPR_COMMA:
		evaluate_expression(expr->left);
		if (!evaluate_expression(expr->right))
			return NULL;
		return evaluate_comma(expr);
	case EXPR_COMPARE:
		evaluate_expression(expr->left);
		evaluate_expression(expr->right);
		if (!valid_subexpr_type(expr))
			return NULL;
		return evaluate_compare(expr);
	case EXPR_ASSIGNMENT:
		evaluate_expression(expr->left);
		evaluate_expression(expr->right);
		if (!valid_subexpr_type(expr))
			return NULL;
		return evaluate_assignment(expr);
	case EXPR_PREOP:
		if (!evaluate_expression(expr->unop))
			return NULL;
		return evaluate_preop(expr);
	case EXPR_POSTOP:
		if (!evaluate_expression(expr->unop))
			return NULL;
		return evaluate_postop(expr);
	case EXPR_CAST:
	case EXPR_FORCE_CAST:
	case EXPR_IMPLIED_CAST:
		return evaluate_cast(expr);
	case EXPR_SIZEOF:
		return evaluate_sizeof(expr);
	case EXPR_PTRSIZEOF:
		return evaluate_ptrsizeof(expr);
	case EXPR_ALIGNOF:
		return evaluate_alignof(expr);
	case EXPR_DEREF:
		return evaluate_member_dereference(expr);
	case EXPR_CALL:
		return evaluate_call(expr);
	case EXPR_SELECT:
	case EXPR_CONDITIONAL:
		return evaluate_conditional_expression(expr);
	case EXPR_STATEMENT:
		expr->ctype = evaluate_statement(expr->statement);
		return expr->ctype;

	case EXPR_LABEL:
		expr->ctype = &ptr_ctype;
		return &ptr_ctype;

	case EXPR_TYPE:
		/* Evaluate the type of the symbol .. */
		evaluate_symbol(expr->symbol);
		/* .. but the type of the _expression_ is a "type" */
		expr->ctype = &type_ctype;
		return &type_ctype;

	case EXPR_OFFSETOF:
		return evaluate_offsetof(expr);

	/* These can not exist as stand-alone expressions */
	case EXPR_INITIALIZER:
	case EXPR_IDENTIFIER:
	case EXPR_INDEX:
	case EXPR_POS:
		expression_error(expr, "internal front-end error: initializer in expression");
		return NULL;
	case EXPR_SLICE:
		expression_error(expr, "internal front-end error: SLICE re-evaluated");
		return NULL;
	case EXPR_ASM_OPERAND:
		expression_error(expr, "internal front-end error: ASM_OPERAND evaluated");
		return NULL;
	}
	return NULL;
}

void check_duplicates(struct symbol *sym)
{
	int declared = 0;
	struct symbol *next = sym;
	int initialized = sym->initializer != NULL;

	while ((next = next->same_symbol) != NULL) {
		const char *typediff;
		evaluate_symbol(next);
		if (initialized && next->initializer) {
			sparse_error(sym->pos, "symbol '%s' has multiple initializers (originally initialized at %s:%d)",
				show_ident(sym->ident),
				stream_name(next->pos.stream), next->pos.line);
			/* Only warn once */
			initialized = 0;
		}
		declared++;
		typediff = type_difference(&sym->ctype, &next->ctype, 0, 0);
		if (typediff) {
			sparse_error(sym->pos, "symbol '%s' redeclared with different type (originally declared at %s:%d) - %s",
				show_ident(sym->ident),
				stream_name(next->pos.stream), next->pos.line, typediff);
			return;
		}
	}
	if (!declared) {
		unsigned long mod = sym->ctype.modifiers;
		if (mod & (MOD_STATIC | MOD_REGISTER))
			return;
		if (!(mod & MOD_TOPLEVEL))
			return;
		if (!Wdecl)
			return;
		if (sym->ident == &main_ident)
			return;
		warning(sym->pos, "symbol '%s' was not declared. Should it be static?", show_ident(sym->ident));
	}
}

static struct symbol *evaluate_symbol(struct symbol *sym)
{
	struct symbol *base_type;

	if (!sym)
		return sym;
	if (sym->evaluated)
		return sym;
	sym->evaluated = 1;

	sym = examine_symbol_type(sym);
	base_type = get_base_type(sym);
	if (!base_type)
		return NULL;

	/* Evaluate the initializers */
	if (sym->initializer)
		evaluate_initializer(sym, &sym->initializer);

	/* And finally, evaluate the body of the symbol too */
	if (base_type->type == SYM_FN) {
		struct symbol *curr = current_fn;

		if (sym->definition && sym->definition != sym)
			return evaluate_symbol(sym->definition);

		current_fn = base_type;

		examine_fn_arguments(base_type);
		if (!base_type->stmt && base_type->inline_stmt)
			uninline(sym);
		if (base_type->stmt)
			evaluate_statement(base_type->stmt);

		current_fn = curr;
	}

	return base_type;
}

void evaluate_symbol_list(struct symbol_list *list)
{
	struct symbol *sym;

	FOR_EACH_PTR(list, sym) {
		has_error &= ~ERROR_CURR_PHASE;
		evaluate_symbol(sym);
		check_duplicates(sym);
	} END_FOR_EACH_PTR(sym);
}

static struct symbol *evaluate_return_expression(struct statement *stmt)
{
	struct expression *expr = stmt->expression;
	struct symbol *fntype;

	evaluate_expression(expr);
	fntype = current_fn->ctype.base_type;
	if (!fntype || fntype == &void_ctype) {
		if (expr && expr->ctype != &void_ctype)
			expression_error(expr, "return expression in %s function", fntype?"void":"typeless");
		if (expr && Wreturn_void)
			warning(stmt->pos, "returning void-valued expression");
		return NULL;
	}

	if (!expr) {
		sparse_error(stmt->pos, "return with no return value");
		return NULL;
	}
	if (!expr->ctype)
		return NULL;
	compatible_assignment_types(expr, fntype, &stmt->expression, "return expression");
	return NULL;
}

static void evaluate_if_statement(struct statement *stmt)
{
	if (!stmt->if_conditional)
		return;

	evaluate_conditional(stmt->if_conditional, 0);
	evaluate_statement(stmt->if_true);
	evaluate_statement(stmt->if_false);
}

static void evaluate_iterator(struct statement *stmt)
{
	evaluate_symbol_list(stmt->iterator_syms);
	evaluate_conditional(stmt->iterator_pre_condition, 1);
	evaluate_conditional(stmt->iterator_post_condition,1);
	evaluate_statement(stmt->iterator_pre_statement);
	evaluate_statement(stmt->iterator_statement);
	evaluate_statement(stmt->iterator_post_statement);
}

static void verify_output_constraint(struct expression *expr, const char *constraint)
{
	switch (*constraint) {
	case '=':	/* Assignment */
	case '+':	/* Update */
		break;
	default:
		expression_error(expr, "output constraint is not an assignment constraint (\"%s\")", constraint);
	}
}

static void verify_input_constraint(struct expression *expr, const char *constraint)
{
	switch (*constraint) {
	case '=':	/* Assignment */
	case '+':	/* Update */
		expression_error(expr, "input constraint with assignment (\"%s\")", constraint);
	}
}

static void evaluate_asm_statement(struct statement *stmt)
{
	struct expression *expr;
	struct expression *op;
	struct symbol *sym;

	expr = stmt->asm_string;
	if (!expr || expr->type != EXPR_STRING) {
		sparse_error(stmt->pos, "need constant string for inline asm");
		return;
	}

	FOR_EACH_PTR(stmt->asm_outputs, op) {
		/* Identifier */

		/* Constraint */
		expr = op->constraint;
		if (!expr || expr->type != EXPR_STRING) {
			sparse_error(expr ? expr->pos : stmt->pos, "asm output constraint is not a string");
			op->constraint = NULL;
		} else
			verify_output_constraint(expr, expr->string->data);

		/* Expression */
		expr = op->expr;
		if (!evaluate_expression(expr))
			return;
		if (!lvalue_expression(expr))
			warning(expr->pos, "asm output is not an lvalue");
		evaluate_assign_to(expr, expr->ctype);
	} END_FOR_EACH_PTR(op);

	FOR_EACH_PTR(stmt->asm_inputs, op) {
		/* Identifier */

		/* Constraint */
		expr = op->constraint;
		if (!expr || expr->type != EXPR_STRING) {
			sparse_error(expr ? expr->pos : stmt->pos, "asm input constraint is not a string");
			op->constraint = NULL;
		} else
			verify_input_constraint(expr, expr->string->data);

		/* Expression */
		if (!evaluate_expression(op->expr))
			return;
	} END_FOR_EACH_PTR(op);

	FOR_EACH_PTR(stmt->asm_clobbers, expr) {
		if (!expr) {
			sparse_error(stmt->pos, "bad asm clobbers");
			return;
		}
		if (expr->type == EXPR_STRING)
			continue;
		expression_error(expr, "asm clobber is not a string");
	} END_FOR_EACH_PTR(expr);

	FOR_EACH_PTR(stmt->asm_labels, sym) {
		if (!sym || sym->type != SYM_LABEL) {
			sparse_error(stmt->pos, "bad asm label");
			return;
		}
	} END_FOR_EACH_PTR(sym);
}

static void evaluate_case_statement(struct statement *stmt)
{
	evaluate_expression(stmt->case_expression);
	evaluate_expression(stmt->case_to);
	evaluate_statement(stmt->case_statement);
}

static void check_case_type(struct expression *switch_expr,
			    struct expression *case_expr,
			    struct expression **enumcase)
{
	struct symbol *switch_type, *case_type;
	int sclass, cclass;

	if (!case_expr)
		return;

	switch_type = switch_expr->ctype;
	case_type = evaluate_expression(case_expr);

	if (!switch_type || !case_type)
		goto Bad;
	if (enumcase) {
		if (*enumcase)
			warn_for_different_enum_types(case_expr->pos, case_type, (*enumcase)->ctype);
		else if (is_enum_type(case_type))
			*enumcase = case_expr;
	}

	sclass = classify_type(switch_type, &switch_type);
	cclass = classify_type(case_type, &case_type);

	/* both should be arithmetic */
	if (!(sclass & cclass & TYPE_NUM))
		goto Bad;

	/* neither should be floating */
	if ((sclass | cclass) & TYPE_FLOAT)
		goto Bad;

	/* if neither is restricted, we are OK */
	if (!((sclass | cclass) & TYPE_RESTRICT))
		return;

	if (!restricted_binop_type(SPECIAL_EQUAL, case_expr, switch_expr,
				   cclass, sclass, case_type, switch_type)) {
		unrestrict(case_expr, cclass, &case_type);
		unrestrict(switch_expr, sclass, &switch_type);
	}
	return;

Bad:
	expression_error(case_expr, "incompatible types for 'case' statement");
}

static void evaluate_switch_statement(struct statement *stmt)
{
	struct symbol *sym;
	struct expression *enumcase = NULL;
	struct expression **enumcase_holder = &enumcase;
	struct expression *sel = stmt->switch_expression;

	evaluate_expression(sel);
	evaluate_statement(stmt->switch_statement);
	if (!sel)
		return;
	if (sel->ctype && is_enum_type(sel->ctype))
		enumcase_holder = NULL; /* Only check cases against switch */

	FOR_EACH_PTR(stmt->switch_case->symbol_list, sym) {
		struct statement *case_stmt = sym->stmt;
		check_case_type(sel, case_stmt->case_expression, enumcase_holder);
		check_case_type(sel, case_stmt->case_to, enumcase_holder);
	} END_FOR_EACH_PTR(sym);
}

static void evaluate_goto_statement(struct statement *stmt)
{
	struct symbol *label = stmt->goto_label;

	if (label && !label->stmt && label->ident && !lookup_keyword(label->ident, NS_KEYWORD))
		sparse_error(stmt->pos, "label '%s' was not declared", show_ident(label->ident));

	evaluate_expression(stmt->goto_expression);
}

struct symbol *evaluate_statement(struct statement *stmt)
{
	if (!stmt)
		return NULL;

	switch (stmt->type) {
	case STMT_DECLARATION: {
		struct symbol *s;
		FOR_EACH_PTR(stmt->declaration, s) {
			evaluate_symbol(s);
		} END_FOR_EACH_PTR(s);
		return NULL;
	}

	case STMT_RETURN:
		return evaluate_return_expression(stmt);

	case STMT_EXPRESSION:
		if (!evaluate_expression(stmt->expression))
			return NULL;
		if (stmt->expression->ctype == &null_ctype)
			stmt->expression = cast_to(stmt->expression, &ptr_ctype);
		return degenerate(stmt->expression);

	case STMT_COMPOUND: {
		struct statement *s;
		struct symbol *type = NULL;

		/* Evaluate the return symbol in the compound statement */
		evaluate_symbol(stmt->ret);

		/*
		 * Then, evaluate each statement, making the type of the
		 * compound statement be the type of the last statement
		 */
		type = evaluate_statement(stmt->args);
		FOR_EACH_PTR(stmt->stmts, s) {
			type = evaluate_statement(s);
		} END_FOR_EACH_PTR(s);
		if (!type)
			type = &void_ctype;
		return type;
	}
	case STMT_IF:
		evaluate_if_statement(stmt);
		return NULL;
	case STMT_ITERATOR:
		evaluate_iterator(stmt);
		return NULL;
	case STMT_SWITCH:
		evaluate_switch_statement(stmt);
		return NULL;
	case STMT_CASE:
		evaluate_case_statement(stmt);
		return NULL;
	case STMT_LABEL:
		return evaluate_statement(stmt->label_statement);
	case STMT_GOTO:
		evaluate_goto_statement(stmt);
		return NULL;
	case STMT_NONE:
		break;
	case STMT_ASM:
		evaluate_asm_statement(stmt);
		return NULL;
	case STMT_CONTEXT:
		evaluate_expression(stmt->expression);
		return NULL;
	case STMT_RANGE:
		evaluate_expression(stmt->range_expression);
		evaluate_expression(stmt->range_low);
		evaluate_expression(stmt->range_high);
		return NULL;
	}
	return NULL;
}
