Browse Source

* fixed r9243: that change should only be applied in case both the
parasym and the actual parameter are a shortstring rather than
when at least one isn't a shortstring

git-svn-id: trunk@9275 -

Jonas Maebe 17 years ago
parent
commit
8f187bf6e2
1 changed files with 38 additions and 27 deletions
  1. 38 27
      compiler/ncal.pas

+ 38 - 27
compiler/ncal.pas

@@ -693,38 +693,49 @@ implementation
                       else
                        begin
                          check_ranges(left.fileinfo,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);
+                         inserttypeconv(left,parasym.vardef);
                        end;
                       if codegenerror then
                         exit;
                    end;
 
+                { 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 is_shortstring(left.resultdef) and
+                    is_shortstring(parasym.vardef) and
+                    (parasym.varspez=vs_value) and
+                    not paramanager.push_addr_param(parasym.varspez,parasym.vardef,
+                          aktcallnode.procdefinition.proccalloption) and
+                    ((is_open_string(left.resultdef) and
+                      (tstringdef(parasym.vardef).len < 255)) or
+                     (not is_open_string(left.resultdef) and
+                      { when a stringconstn is typeconverted, then only its  }
+                      { def is modified, not the contents (needed because in }
+                      { Delphi/TP, if you pass a longer string to a const    }
+                      { parameter, then the callee has to see this longer    }
+                      { string)                                              }
+                      (((left.nodetype<>stringconstn) and
+                        (tstringdef(parasym.vardef).len<tstringdef(left.resultdef).len)) or
+                       ((left.nodetype=stringconstn) and
+                        (tstringdef(parasym.vardef).len<tstringconstnode(left).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;
+
                  { check var strings }
                  if (cs_strict_var_strings in current_settings.localswitches) and
                     is_shortstring(left.resultdef) and