fix(codegen): QBE stores float to implicit-Self field with stored/stores
Assigning a float value to a class field via an implicit Self reference
(e.g. `V := d` in a method/constructor where V: Double) emitted a hardcoded
`storel` on a `d`/`s` SSA value, which QBE rejects ("invalid type for first
operand in storel"). The implicit-Self field-store path in EmitAssignment
fell through to a literal `storel` instead of StoreInstrFor(field type), and
lacked the d<->s width coercion the EmitFieldAssignment path already has.
Use StoreInstrFor(ISFld.TypeDesc) (-> stored/stores for tyDouble/tySingle) and
add the Single<->Double truncd/exts coercion before the store. Surfaced by the
new float-constructor e2e tests, which run on both backends.
This commit is contained in:
parent
74da3eadcc
commit
ef19c01cb7
|
|
@ -4056,7 +4056,24 @@ begin
|
||||||
EmitLine(Format(' call $_ClassAddRef(l %s)', [ValTemp]));
|
EmitLine(Format(' call $_ClassAddRef(l %s)', [ValTemp]));
|
||||||
EmitLine(Format(' call $_ClassRelease(l %s)', [OldTemp]));
|
EmitLine(Format(' call $_ClassRelease(l %s)', [OldTemp]));
|
||||||
end;
|
end;
|
||||||
EmitLine(Format(' storel %s, %s', [ValTemp, ObjTemp]));
|
{ Float-width coercion before the store: a real-typed RHS lands in the
|
||||||
|
SSA as 'd' even when the field is a 32-bit Single ('s'), and vice
|
||||||
|
versa. Without this an implicit-Self 'V := d' float-field store
|
||||||
|
emitted 'storel' on a 'd' value — a QBE type error. }
|
||||||
|
if (QType = 's') and (QbeTypeOf(AAssign.Expr.ResolvedType) = 'd') then
|
||||||
|
begin
|
||||||
|
ExtTemp := AllocTemp();
|
||||||
|
EmitLine(Format(' %s =s truncd %s', [ExtTemp, ValTemp]));
|
||||||
|
ValTemp := ExtTemp;
|
||||||
|
end
|
||||||
|
else if (QType = 'd') and (QbeTypeOf(AAssign.Expr.ResolvedType) = 's') then
|
||||||
|
begin
|
||||||
|
ExtTemp := AllocTemp();
|
||||||
|
EmitLine(Format(' %s =d exts %s', [ExtTemp, ValTemp]));
|
||||||
|
ValTemp := ExtTemp;
|
||||||
|
end;
|
||||||
|
EmitLine(Format(' %s %s, %s',
|
||||||
|
[StoreInstrFor(ISFld.TypeDesc), ValTemp, ObjTemp]));
|
||||||
end;
|
end;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue