Make alias_def take an offset.

alias_def now always creates an offset def (though the usual case has an
offset of 0). The if the alias escapes the bounds of the base def, an
internal error will be generated.
This commit is contained in:
Bill Currie 2012-12-03 11:50:26 +09:00
parent 9d0332ae30
commit 919ea8192a
3 changed files with 16 additions and 9 deletions

View file

@ -119,13 +119,18 @@ def_t *new_def (const char *name, struct type_s *type,
Aliasing a def to the same type is useless, but not checked. Aliasing a
def to a type larger than the def's type will generate an internal error.
If the offset is negative, or the offset plus the size of the aliasing type
is greater than the size of the def's type, then an internal error will
be generated.
\param def The def to be aliased.
\param type The type of the alias.
\param offset Offset of the alias relative to the def.
\return The def aliasing \a def.
\todo Make aliasing to the same type a no-op?
*/
def_t *alias_def (def_t *def, struct type_s *type);
def_t *alias_def (def_t *def, struct type_s *type, int offset);
/** Free a def.

View file

@ -145,7 +145,7 @@ new_def (const char *name, type_t *type, defspace_t *space,
}
def_t *
alias_def (def_t *def, type_t *type)
alias_def (def_t *def, type_t *type, int offset)
{
def_t *alias;
@ -157,9 +157,12 @@ alias_def (def_t *def, type_t *type)
}
if (type_size (type) > type_size (def->type))
internal_error (0, "aliasing a def to a larger type");
if (offset < 0 || offset + type_size (type) > type_size (def->type))
internal_error (0, "invalid alias offset");
ALLOC (16384, def_t, defs, alias);
alias->return_addr = __builtin_return_address (0);
alias->offset = def->offset;
alias->offset = offset;
alias->offset_reloc = 1;
alias->type = type;
alias->alias = def;
alias->line = pr.source_line;

View file

@ -72,7 +72,7 @@ get_value_def (ex_value_t *value, etype_t type)
}
def = emit_value (value, 0);
if (type != def->type->type)
return alias_def (def, ev_types[type]);
return alias_def (def, ev_types[type], 0);
return def;
}
@ -89,7 +89,7 @@ get_operand_def (expr_t *expr, operand_t *op)
case sy_var:
if (op->type != op->o.symbol->type->type)
return alias_def (op->o.symbol->s.def,
ev_types[op->type]);
ev_types[op->type], 0);
return op->o.symbol->s.def;
case sy_func:
return op->o.symbol->s.func->def;
@ -114,16 +114,15 @@ get_operand_def (expr_t *expr, operand_t *op)
case op_pointer:
def = op->o.value->v.pointer.def;
if (op->o.value->v.pointer.val || op->type != def->type->type) {
def = alias_def (def, ev_types[op->type]);
def->offset = op->o.value->v.pointer.val;
def->offset_reloc = 1;
def = alias_def (def, ev_types[op->type],
op->o.value->v.pointer.val);
}
return def;
case op_alias:
def = get_operand_def (expr, op->o.alias);
if (def->alias)
def = def->alias;
def = alias_def (def, ev_types[op->type]);
def = alias_def (def, ev_types[op->type], 0);
return def;
}
return 0;