View Issue Details

IDProjectCategoryView StatusLast Update
0033875FPCCompilerpublic2018-11-07 22:02
ReporterDavid JenkinsAssigned ToJonas Maebe 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformOSOSX/LinuxOS Version
Product Version3.1.1Product Build39241 
Target VersionFixed in Version3.3.1 
Summary0033875: Compiler recently began to fail resolving overloaded functional call for UnicodeString and WideChar
DescriptionFor this code:

{$MODE DELPHI}

program CharOverload;

uses
  SysUtils;

procedure Foo(const aArg: UnicodeString); overload;
begin
  WriteLn('WideString: ', aArg);
end;

procedure Foo(c: WideChar); overload;
begin
  WriteLn('Char: ', c);
end;

begin
  Foo('abc');
end.

Compiler recently (since rev 36812) began failing with message

[odysseus:fpc-trunk$] compiler/ppc386 ~/Desktop/test/CharOverload.pp
Free Pascal Compiler version 3.1.1 [2018/06/18] for i386
Copyright (c) 1993-2018 by Florian Klaempfl and others
Target OS: Darwin for i386
Compiling /Users/djenkins/Desktop/test/CharOverload.pp
CharOverload.pp(19,3) Error: Can't determine which overloaded function to call
CharOverload.pp(19,12) Error: Illegal type conversion: "Constant String" to "WideChar"
CharOverload.pp(20,4) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted

True for OSX/Linux and also Mode Delphi and mode objfpc
Steps To Reproduce* save code segment above as test.pas
* compile with 'fpc test.pas'
TagsNo tags attached.
Fixed in Revision40009
FPCOldBugId
FPCTarget
Attached Files

Relationships

related to 0031605 resolvedJonas Maebe WideChar constants cannot be compiled 

Activities

Thaddy de Koning

2018-06-19 10:56

reporter   ~0108964

Last edited: 2018-06-19 12:40

View 3 revisions

{$MODE DELPHIUNICODE} and it works. (Or {$modeswitch unicodestrings})
Note in mode delphi sec constant string literals are AnsiString.

As can be demostrated by adding the following overload:

procedure Foo(const aArg: AnsiString); overload;
begin
  WriteLn('AnsiString: ', aArg);
end;

I think the behavoir is correct.

Thaddy de Koning

2018-06-19 19:39

reporter   ~0108971

See this for my experiments:
// play with these settings. {$modeswitch typehelpers} should always be on.
{$mode delphiunicode}{$modeswitch typehelpers}
type
  stringtypes =(ShortString,AnsiString,UnicodeString);
  stringhelper = type helper for string
  function StringType:Stringtypes;
  end;
  function stringhelper.stringtype:stringtypes;
  begin
    // crude first
    if SizeOf(char) = 2 then
    Result := UnicodeString else
    // less crude second
    {$ifopt h-}
    Result:= Shortstring;
    {$endif}
    // H-/+
    {$ifopt H+)}
    Result := AnsiString;
    {$endif}
  end;
var s:string = '';
begin
  writeln(s.stringtype); // actual string type
  writeln('123'.stringtype); // literal storage
end.

Bart Broersma

2018-06-19 20:48

reporter   ~0108972

@Thaddy: why would that be correct?
'abc' obviously never is a WideChar and the only other immplementation expects WideString, and should accept literal 'abc'.

Thaddy de Koning

2018-06-19 22:23

reporter   ~0108973

Last edited: 2018-06-19 22:24

View 2 revisions

Which it does as demonstrated, Bart.... I still have to test against old delphi versions like 7 and 2006/7, though. (non unicode)
The program works correct in the proper mode. Maybe too strict, but I would expect this. And it is not about the widechar: that is a single char in the presented code. Not a PWideChar...

Thaddy de Koning

2018-06-21 14:40

reporter   ~0108990

Last edited: 2018-06-21 14:43

View 2 revisions

David, were you comparing with a newer version of Delphi? That needs DelphiUnicode.
Your code *fails* on any Delphi version of the pre-unicode era too:
Tested D7 and 2007 with small modifications. Tested XP2, XP10.1.

Zoë Peterson

2018-06-21 18:21

reporter   ~0108993

Last edited: 2018-06-21 18:25

View 2 revisions

@Thaddy

No, David's code does not fail on Delphi 2007. It compiles and runs without issue as long as you change "UnicodeString" to "WideString". If you add a call to "Foo('a')" right after the "abc" line it does call the string variant for both cases, which is a bit unexpected, but not wrong. If you change the declared types to "string" and "char" instead, it just works, and calls the correct overload for both.

More importantly, this is a *regression*. It works perfectly in Free Pascal 3.0.4, in both DELPHI and DELPHIUNICODE mode. It even correctly chooses the UnicodeString or WideChar versions based on the length of the passed in constant, just like later releases of Delphi does.

Finally, I'm not sure what you're trying to show with the experiment code you posted, but it's incorrect. All you're checking is what string mode the compiler is in, at compile time. The fact that it's in a type helper doesn't change the behavior at all, because it isn't actually looking at the type of variable. It's also irrelevant, because the compiler is responsible for figuring out the type of a constant string where it's used. If I have "var1 = 'a'" in my code, the compiler has to emit different code if "var1" is a string or a char type.

David Jenkins

2018-11-07 22:02

reporter   ~0111846

Tested. Works

Issue History

Date Modified Username Field Change
2018-06-18 23:57 David Jenkins New Issue
2018-06-19 10:56 Thaddy de Koning Note Added: 0108964
2018-06-19 10:58 Thaddy de Koning Note Edited: 0108964 View Revisions
2018-06-19 12:40 Thaddy de Koning Note Edited: 0108964 View Revisions
2018-06-19 19:39 Thaddy de Koning Note Added: 0108971
2018-06-19 20:48 Bart Broersma Note Added: 0108972
2018-06-19 22:23 Thaddy de Koning Note Added: 0108973
2018-06-19 22:24 Thaddy de Koning Note Edited: 0108973 View Revisions
2018-06-21 14:40 Thaddy de Koning Note Added: 0108990
2018-06-21 14:43 Thaddy de Koning Note Edited: 0108990 View Revisions
2018-06-21 18:21 Zoë Peterson Note Added: 0108993
2018-06-21 18:25 Zoë Peterson Note Edited: 0108993 View Revisions
2018-10-21 19:31 Jonas Maebe Relationship added related to 0031605
2018-10-21 19:34 Jonas Maebe Fixed in Revision => 40009
2018-10-21 19:34 Jonas Maebe Status new => resolved
2018-10-21 19:34 Jonas Maebe Fixed in Version => 3.3.1
2018-10-21 19:34 Jonas Maebe Resolution open => fixed
2018-10-21 19:34 Jonas Maebe Assigned To => Jonas Maebe
2018-11-07 22:02 David Jenkins Note Added: 0111846
2018-11-07 22:02 David Jenkins Status resolved => closed