diff --git a/tools/qfcc/include/def.h b/tools/qfcc/include/def.h
index e282210c7..69b9ba0a6 100644
--- a/tools/qfcc/include/def.h
+++ b/tools/qfcc/include/def.h
@@ -76,6 +76,7 @@ extern storage_class_t current_storage;
 def_t *new_def (const char *name, struct type_s *type,
 				struct defspace_s *space, storage_class_t storage);
 def_t *alias_def (def_t *def, struct type_s *type);
+def_t *temp_def (etype_t type, int size);
 void free_def (def_t *def);
 
 void def_to_ddef (def_t *def, ddef_t *ddef, int aux);
diff --git a/tools/qfcc/include/statements.h b/tools/qfcc/include/statements.h
index d4b5da79a..86c07fe45 100644
--- a/tools/qfcc/include/statements.h
+++ b/tools/qfcc/include/statements.h
@@ -44,6 +44,7 @@ typedef struct operand_s {
 	struct operand_s *next;
 	op_type_e   op_type;
 	etype_t     type;			///< possibly override symbol's type
+	int         size;			///< for structures
 	union {
 		struct symbol_s *symbol;
 		struct ex_value_s *value;
diff --git a/tools/qfcc/source/def.c b/tools/qfcc/source/def.c
index 86575535a..55d5ed455 100644
--- a/tools/qfcc/source/def.c
+++ b/tools/qfcc/source/def.c
@@ -53,6 +53,7 @@ static __attribute__ ((used)) const char rcsid[] =
 #include "diagnostic.h"
 #include "emit.h"
 #include "expr.h"
+#include "function.h"
 #include "options.h"
 #include "reloc.h"
 #include "strpool.h"
@@ -142,12 +143,33 @@ alias_def (def_t *def, type_t *type)
 	def_t      *alias;
 
 	ALLOC (16384, def_t, defs, alias);
+	alias->return_addr = __builtin_return_address (0);
 	alias->offset = def->offset;
 	alias->type = type;
 	alias->alias = def;
 	return alias;
 }
 
+def_t *
+temp_def (etype_t type, int size)
+{
+	def_t      *temp;
+	defspace_t *space = current_func->symtab->space;
+
+	ALLOC (16384, def_t, defs, temp);
+	temp->return_addr = __builtin_return_address (0);
+	temp->name = save_string (va (".tmp%d", current_func->temp_num++));
+	temp->type = ev_types[type];
+	temp->file = pr.source_file;
+	temp->line = pr.source_line;
+	set_storage_bits (temp, st_local);
+	temp->offset = defspace_alloc_loc (space, size);
+	temp->space = space;
+	*space->def_tail = temp;
+	space->def_tail = &temp->next;
+	return temp;
+}
+
 void
 free_def (def_t *def)
 {
diff --git a/tools/qfcc/source/emit.c b/tools/qfcc/source/emit.c
index 2b074bed0..7651dff50 100644
--- a/tools/qfcc/source/emit.c
+++ b/tools/qfcc/source/emit.c
@@ -109,13 +109,8 @@ get_operand_def (expr_t *expr, operand_t *op)
 			zero_def.type = &type_short;
 			return &zero_def;	//FIXME
 		case op_temp:
-			if (!op->o.def) {
-				const char *temp_name;
-
-				temp_name = va (".tmp%d", current_func->temp_num++);
-				op->o.def = new_def (temp_name, ev_types[op->type],
-									 current_func->symtab->space, st_local);
-			}
+			if (!op->o.def)
+				op->o.def = temp_def (op->type, op->size);
 			return op->o.def;
 		case op_pointer:
 			def = op->o.pointer->def;
diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c
index 87e92b5f9..a240d02b0 100644
--- a/tools/qfcc/source/statements.c
+++ b/tools/qfcc/source/statements.c
@@ -217,6 +217,16 @@ free_sblock (sblock_t *sblock)
 	free_sblocks = sblock;
 }
 
+static operand_t *
+temp_operand (type_t *type)
+{
+	operand_t  *op = new_operand (op_temp);
+
+	op->type = low_level_type (type);
+	op->size = type_size (type);
+	return op;
+}
+
 static operand_t *
 short_operand (short short_val)
 {
@@ -486,8 +496,7 @@ lea_statement (operand_t *pointer, operand_t *offset, expr_t *e)
 	statement_t *s = new_statement ("&", e);
 	s->opa = pointer;
 	s->opb = offset;
-	s->opc = new_operand (op_temp);
-	s->opc->type = ev_pointer;
+	s->opc = temp_operand (&type_pointer);
 	return s;
 }
 
@@ -496,8 +505,7 @@ address_statement (operand_t *value, expr_t *e)
 {
 	statement_t *s = new_statement ("&", e);
 	s->opa = value;
-	s->opc = new_operand (op_temp);
-	s->opc->type = ev_pointer;
+	s->opc = temp_operand (&type_pointer);
 	return s;
 }
 
@@ -519,10 +527,8 @@ expr_deref (sblock_t *sblock, expr_t *deref, operand_t **op)
 		operand_t  *offs = 0;
 		sblock = statement_subexpr (sblock, e->e.expr.e1, &ptr);
 		sblock = statement_subexpr (sblock, e->e.expr.e2, &offs);
-		if (!*op) {
-			*op = new_operand (op_temp);
-			(*op)->type = low_level_type (type);
-		}
+		if (!*op)
+			*op = temp_operand (type);
 		if (low_level_type (type) == ev_void) {
 			operand_t  *src_addr;
 			operand_t  *dst_addr;
@@ -591,10 +597,8 @@ expr_expr (sblock_t *sblock, expr_t *e, operand_t **op)
 			s = new_statement (opcode, e);
 			sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
 			sblock = statement_subexpr (sblock, e->e.expr.e2, &s->opb);
-			if (!*op) {
-				*op = new_operand (op_temp);
-				(*op)->type = low_level_type (e->e.expr.type);
-			}
+			if (!*op)
+				*op = temp_operand (e->e.expr.type);
 			s->opc = *op;
 			sblock_add_statement (sblock, s);
 			break;
@@ -621,10 +625,8 @@ expr_cast (sblock_t *sblock, expr_t *e, operand_t **op)
 	sblock = statement_subexpr (sblock, e->e.expr.e1, &src);
 	if ((src->type == ev_integer && type->type == ev_float)
 		|| (src->type == ev_float && type->type == ev_integer)) {
-		if (!*op) {
-			(*op) = new_operand (op_temp);
-			(*op)->type = low_level_type (e->e.expr.type);
-		}
+		if (!*op)
+			*op = temp_operand (e->e.expr.type);
 		s = new_statement ("=", e);
 		s->opa = src;
 		s->opc = *op;
@@ -681,10 +683,8 @@ expr_uexpr (sblock_t *sblock, expr_t *e, operand_t **op)
 				internal_error (e, "ice ice baby");
 			s = new_statement (opcode, e);
 			sblock = statement_subexpr (sblock, e->e.expr.e1, &s->opa);
-			if (!*op) {
-				*op = new_operand (op_temp);
-				(*op)->type = low_level_type (e->e.expr.type);
-			}
+			if (!*op)
+				*op = temp_operand (e->e.expr.type);
 			s->opc = *op;
 			sblock_add_statement (sblock, s);
 	}
@@ -703,10 +703,8 @@ expr_symbol (sblock_t *sblock, expr_t *e, operand_t **op)
 static sblock_t *
 expr_temp (sblock_t *sblock, expr_t *e, operand_t **op)
 {
-	if (!e->e.temp.op) {
-		e->e.temp.op = new_operand (op_temp);
-		e->e.temp.op->type = low_level_type (e->e.temp.type);
-	}
+	if (!e->e.temp.op)
+		e->e.temp.op = temp_operand (e->e.temp.type);
 	*op = e->e.temp.op;
 	return sblock;
 }