瀏覽代碼

* fix for Mantis #31756: have array constructors prefer open array parameters instead of dynamic array parameters for backwards compatibility
+ added test

git-svn-id: trunk@36175 -

svenbarth 8 年之前
父節點
當前提交
5971e1327e
共有 3 個文件被更改,包括 58 次插入3 次删除
  1. 1 0
      .gitattributes
  2. 29 3
      compiler/defcmp.pas
  3. 28 0
      tests/test/tarrconstr6.pp

+ 1 - 0
.gitattributes

@@ -12093,6 +12093,7 @@ tests/test/tarrconstr2.pp svneol=native#text/pascal
 tests/test/tarrconstr3.pp svneol=native#text/pascal
 tests/test/tarrconstr4.pp svneol=native#text/pascal
 tests/test/tarrconstr5.pp svneol=native#text/pascal
+tests/test/tarrconstr6.pp svneol=native#text/pascal
 tests/test/tasm1.pp svneol=native#text/plain
 tests/test/tasm10.pp svneol=native#text/plain
 tests/test/tasm2.inc svneol=native#text/plain

+ 29 - 3
compiler/defcmp.pas

@@ -980,10 +980,36 @@ implementation
                            if is_array_constructor(def_from) then
                              begin
                                { array constructor -> dynamic array }
-                               if (tarraydef(def_from).elementdef=voidtype) or
-                                   (compare_defs(tarraydef(def_from).elementdef,tarraydef(def_to).elementdef,nothingn)>te_incompatible) then
+                               if is_void(tarraydef(def_from).elementdef) then
+                                 begin
+                                   { only needs to loose to [] -> open array }
+                                   eq:=te_convert_l2;
+                                   doconv:=tc_arrayconstructor_2_dynarray;
+                                 end
+                               else
                                  begin
-                                   eq:=te_convert_l1;
+                                   { this should loose to the array constructor -> open array conversions,
+                                     but it might happen that the end of the convert levels is reached :/ }
+                                   subeq:=compare_defs_ext(tarraydef(def_from).elementdef,
+                                                        tarraydef(def_to).elementdef,
+                                                        { reason for cdo_allow_variant: see webtbs/tw7070a and webtbs/tw7070b }
+                                                        arrayconstructorn,hct,hpd,[cdo_check_operator,cdo_allow_variant]);
+                                   if (subeq>=te_equal) then
+                                     begin
+                                       eq:=te_convert_l2;
+                                     end
+                                   else
+                                     { an array constructor is not a dynamic array, so
+                                       use a lower level of compatibility than that one of
+                                       of the elements }
+                                     if subeq>te_convert_l5 then
+                                      begin
+                                        eq:=pred(pred(subeq));
+                                      end
+                                    else if subeq>te_convert_l6 then
+                                      eq:=pred(subeq)
+                                    else
+                                      eq:=subeq;
                                    doconv:=tc_arrayconstructor_2_dynarray;
                                  end;
                              end

+ 28 - 0
tests/test/tarrconstr6.pp

@@ -0,0 +1,28 @@
+program tarrconstr6;
+
+type
+  TLongIntArray = array of LongInt;
+
+function Test(aArr: array of LongInt): Integer;
+begin
+  Test := 1;
+end;
+
+function Test(aArr: TLongIntArray): Integer;
+begin
+  Test := 2;
+end;
+
+var
+  la: TLongIntArray;
+begin
+  la := Nil;
+  if Test([]) <> 1 then
+    Halt(1);
+  if Test([1, 2, 3]) <> 1 then
+    Halt(2);
+  if Test(TLongIntArray.Create(1, 2, 3)) <> 2 then
+    Halt(3);
+  if Test(la) <> 2 then
+    Halt(4);
+end.