* when converting a*a into sqr(a), set the result type correctly

* removefloatupcasts takes care of cs_excessprecision, resolves #39012
This commit is contained in:
florian 2021-11-07 21:54:25 +01:00
parent 67e7dc0194
commit 292be9029e
3 changed files with 41 additions and 1 deletions

View File

@ -1682,6 +1682,7 @@ implementation
not(might_have_sideeffects(left)) then
begin
result:=cinlinenode.create(in_sqr_real,false,left);
inserttypeconv(result,resultdef);
left:=nil;
exit;
end;

View File

@ -2832,7 +2832,8 @@ implementation
which typechecks the arguments, possibly inserting conversion to valreal.
To handle smaller types without excess precision, we need to remove
these extra typecasts. }
if (p.nodetype=typeconvn) and
if not(cs_excessprecision in current_settings.localswitches) and
(p.nodetype=typeconvn) and
(ttypeconvnode(p).left.resultdef.typ=floatdef) and
(p.flags*[nf_explicit,nf_internal]=[]) and
(tfloatdef(ttypeconvnode(p).left.resultdef).floattype in (floattypes*[s32real,s64real,s80real,sc80real,s128real])) then

38
tests/webtbs/tw39012.pp Normal file
View File

@ -0,0 +1,38 @@
unit tw39012;
{$mode objfpc}
{$modeswitch advancedrecords}
interface
type
TPoint3D = record
x,y,z: single;
// procedure Offset(const point3D: TPoint3D);
// procedure Scale(AScale: single);
end;
{** Scalar product: multiplies components and returns the sum }
operator * (const v1,v2: TPoint3D): single; inline;
procedure Normalize3D(var v: TPoint3D); inline;
implementation
operator * (const v1,v2: TPoint3D): single; inline;
begin
result := v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
end;
procedure Normalize3D(var v: TPoint3D); inline;
var len: double;
begin
len := v*v;
// if len = 0 then exit;
// len := sqrt(len);
// v.x := v.x / len;
// v.y := v.y / len;
// v.z := v.z / len;
end;
end.