2
0
Эх сурвалжийг харах

* when converting a*a into sqr(a), set the result type correctly
* removefloatupcasts takes care of cs_excessprecision, resolves #39012

florian 3 жил өмнө
parent
commit
292be9029e

+ 1 - 0
compiler/nadd.pas

@@ -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;

+ 2 - 1
compiler/ninl.pas

@@ -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 - 0
tests/webtbs/tw39012.pp

@@ -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.