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