ソースを参照

* truncate constant shortstrings at the callee side if they are passed
to a value parameter with a shorter length, and if they would not be
implicitly passed by reference (if they are passed by reference, then
the callee will perform a shortstring assign which will do the length
truncation). Fixes tarray3 on x86_64

git-svn-id: trunk@9243 -

Jonas Maebe 17 年 前
コミット
2e9db26750
1 ファイル変更31 行追加2 行削除
  1. 31 2
      compiler/ncal.pas

+ 31 - 2
compiler/ncal.pas

@@ -585,7 +585,10 @@ implementation
     procedure tcallparanode.insert_typeconv(do_count : boolean);
       var
         olddef  : tdef;
-        hp       : tnode;
+        hp      : tnode;
+        block : tblocknode;
+        statements : tstatementnode;
+        temp : ttempcreatenode;
       begin
          { Be sure to have the resultdef }
          if not assigned(left.resultdef) then
@@ -688,7 +691,33 @@ implementation
                       else
                        begin
                          check_ranges(left.fileinfo,left,parasym.vardef);
-                         inserttypeconv(left,parasym.vardef);
+                         { truncate shortstring value parameters at the caller side if }
+                         { they are passed by value (if passed by reference, then the  }
+                         { callee will truncate when copying in the string)            }
+                         { This happens e.g. on x86_64 for small strings               }
+                         if (parasym.varspez=vs_value) and
+                            not paramanager.push_addr_param(parasym.varspez,parasym.vardef,
+                                  aktcallnode.procdefinition.proccalloption) and
+                            (tstringdef(parasym.vardef).len<tstringdef(left.resultdef).len) then
+                           begin
+                             block:=internalstatements(statements);
+                             { temp for the new string }
+                             temp:=ctempcreatenode.create(parasym.vardef,parasym.vardef.size,
+                               tt_persistent,true);
+                             addstatement(statements,temp);
+                             { assign parameter to temp }
+                             addstatement(statements,cassignmentnode.create(ctemprefnode.create(temp),left));
+                             left:=nil;
+                             { release temp after next use }
+                             addstatement(statements,ctempdeletenode.create_normal_temp(temp));
+                             addstatement(statements,ctemprefnode.create(temp));
+                             typecheckpass(block);
+                             left:=block;
+                           end
+                         else
+                           { type conversions perform no truncation for constant strings, }
+                           { which is TP/Delphi compatible                                }
+                           inserttypeconv(left,parasym.vardef);
                        end;
                       if codegenerror then
                         exit;