瀏覽代碼

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

florian 4 年之前
父節點
當前提交
292be9029e
共有 3 個文件被更改,包括 41 次插入1 次删除
  1. 1 0
      compiler/nadd.pas
  2. 2 1
      compiler/ninl.pas
  3. 38 0
      tests/webtbs/tw39012.pp

+ 1 - 0
compiler/nadd.pas

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

+ 2 - 1
compiler/ninl.pas

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