Browse Source

* fixed internalerror when having to choose between different
overloads in case there is only one variant parameter and
one of the candidates has more hidden parameters than the
other at the start (e.g. function(para):char and
function(para):shortstring, depending on in which order the
hidden shortstring result and para are processed, mantis
#11139)

git-svn-id: trunk@10643 -

Jonas Maebe 17 years ago
parent
commit
76e23fc54e
3 changed files with 44 additions and 13 deletions
  1. 1 0
      .gitattributes
  2. 15 13
      compiler/htypechk.pas
  3. 28 0
      tests/webtbs/tw11139.pp

+ 1 - 0
.gitattributes

@@ -8135,6 +8135,7 @@ tests/webtbs/tw1104.pp svneol=native#text/plain
 tests/webtbs/tw11042.pp svneol=native#text/plain
 tests/webtbs/tw11042.pp svneol=native#text/plain
 tests/webtbs/tw11053.pp svneol=native#text/plain
 tests/webtbs/tw11053.pp svneol=native#text/plain
 tests/webtbs/tw1111.pp svneol=native#text/plain
 tests/webtbs/tw1111.pp svneol=native#text/plain
+tests/webtbs/tw11139.pp svneol=native#text/plain
 tests/webtbs/tw1117.pp svneol=native#text/plain
 tests/webtbs/tw1117.pp svneol=native#text/plain
 tests/webtbs/tw1122.pp svneol=native#text/plain
 tests/webtbs/tw1122.pp svneol=native#text/plain
 tests/webtbs/tw1123.pp svneol=native#text/plain
 tests/webtbs/tw1123.pp svneol=native#text/plain

+ 15 - 13
compiler/htypechk.pas

@@ -2364,8 +2364,20 @@ implementation
                   ord(currvcl in conflictvcls)-ord(bestvcl in conflictvcls);
                   ord(currvcl in conflictvcls)-ord(bestvcl in conflictvcls);
         end;
         end;
 
 
+
+        function getfirstrealparaidx(pd: pcandidate): integer;
+          begin
+            { can be different for currpd and bestpd in case of overloaded }
+            { functions, e.g. lowercase():char and lowercase():shortstring }
+            { (depending on the calling convention and parameter order)    }
+            result:=pd^.firstparaidx;
+            while (result>=0) and (vo_is_hidden_para in tparavarsym(pd^.data.paras[result]).varoptions) do
+              dec(result);
+            if (vo_is_hidden_para in tparavarsym(pd^.data.paras[result]).varoptions) then
+              internalerror(2006122803);
+          end;
+
       var
       var
-        paraidx : integer;
         currpara, bestpara: tparavarsym;
         currpara, bestpara: tparavarsym;
         currvcl, bestvcl: tvariantequaltype;
         currvcl, bestvcl: tvariantequaltype;
       begin
       begin
@@ -2375,18 +2387,8 @@ implementation
             < 0 when bestpd is better than currpd
             < 0 when bestpd is better than currpd
             = 0 when both are equal
             = 0 when both are equal
         }
         }
-        if (currpd^.firstparaidx<>bestpd^.firstparaidx) then
-          internalerror(2006122801);
-         paraidx:=currpd^.firstparaidx;
-         while (paraidx>=0) and (vo_is_hidden_para in tparavarsym(currpd^.data.paras[paraidx]).varoptions) do
-           if (vo_is_hidden_para in tparavarsym(bestpd^.data.paras[paraidx]).varoptions) then
-             dec(paraidx)
-           else
-             internalerror(2006122802);
-        if (vo_is_hidden_para in tparavarsym(currpd^.data.paras[paraidx]).varoptions) then
-          internalerror(2006122803);
-        currpara:=tparavarsym(currpd^.data.paras[paraidx]);
-        bestpara:=tparavarsym(bestpd^.data.paras[paraidx]);
+        currpara:=tparavarsym(currpd^.data.paras[getfirstrealparaidx(currpd)]);
+        bestpara:=tparavarsym(bestpd^.data.paras[getfirstrealparaidx(bestpd)]);
 
 
         { if one of the parameters is a regular variant, fall back to the }
         { if one of the parameters is a regular variant, fall back to the }
         { default algorithm                                               }
         { default algorithm                                               }

+ 28 - 0
tests/webtbs/tw11139.pp

@@ -0,0 +1,28 @@
+function f(c: char): char; overload;
+begin
+  halt(1);
+end;
+
+function f(const s: shortstring): shortstring; overload;
+begin
+  f:=lowercase(s);
+end;
+
+function f(const a: ansistring): ansistring; overload;
+begin
+  halt(3);
+end;
+
+Procedure DoIt;
+var avar:variant;
+      txt:String;
+Begin
+avar:='Hello';
+txt:=f(avar);//this line causes the compilation error
+if (txt<>'hello') then
+  halt(4);
+end;
+
+begin
+  doit;
+end.