Browse Source

* constrained generics are also compatible with formaldefs, resolves #34893

git-svn-id: trunk@40921 -
florian 6 years ago
parent
commit
925531b99c
3 changed files with 145 additions and 2 deletions
  1. 1 0
      .gitattributes
  2. 9 2
      compiler/defcmp.pas
  3. 135 0
      tests/webtbs/tw34893.pp

+ 1 - 0
.gitattributes

@@ -16479,6 +16479,7 @@ tests/webtbs/tw3479.pp svneol=native#text/plain
 tests/webtbs/tw34818.pp svneol=native#text/pascal
 tests/webtbs/tw34848.pp svneol=native#text/pascal
 tests/webtbs/tw3489.pp svneol=native#text/plain
+tests/webtbs/tw34893.pp -text svneol=native#text/pascal
 tests/webtbs/tw3490.pp svneol=native#text/plain
 tests/webtbs/tw3491.pp svneol=native#text/plain
 tests/webtbs/tw3492.pp svneol=native#text/plain

+ 9 - 2
compiler/defcmp.pas

@@ -289,8 +289,15 @@ implementation
              if assigned(tstoreddef(def_from).genconstraintdata) or
                  assigned(tstoreddef(def_to).genconstraintdata) then
                begin
-                 { constants could get another deftype (e.g. niln) }
-                 if (def_from.typ<>def_to.typ) and not(fromtreetype in nodetype_const) then
+                 { this is bascially a poor man's type checking, if there is a chance
+                   that the types are equal considering the constraints, this needs probably
+                   to be improved and maybe factored out or even result in a recursive compare_defs_ext }
+                 if (def_from.typ<>def_to.typ) and
+                   { formaldefs are compatible with everything }
+                   not(def_from.typ in [formaldef]) and
+                   not(def_to.typ in [formaldef]) and
+                   { constants could get another deftype (e.g. niln) }
+                   not(fromtreetype in nodetype_const) then
                    begin
                      { not compatible anyway }
                      doconv:=tc_not_possible;

+ 135 - 0
tests/webtbs/tw34893.pp

@@ -0,0 +1,135 @@
+unit tw34893;
+{$ifdef fpc}
+  {$mode delphi}
+{$endif}
+
+{$scopedenums on}
+
+interface
+
+uses
+  Classes, SysUtils;
+
+type TPasGLTFSizeInt=SizeInt;
+
+     TPasGLTFSizeUInt=SizeUInt;
+
+     TPasGLTFObjectList<T:class>=class
+      private
+       type TValueEnumerator=record
+             private
+              fObjectList:TPasGLTFObjectList<T>;
+              fIndex:TPasGLTFSizeInt;
+              function GetCurrent:T; inline;
+             public
+              constructor Create(const aObjectList:TPasGLTFObjectList<T>);
+              function MoveNext:boolean; inline;
+              property Current:T read GetCurrent;
+            end;
+      private
+       fItems:array of T;
+       fCount:TPasGLTFSizeInt;
+       fAllocated:TPasGLTFSizeInt;
+       fOwnsObjects:boolean;
+       function RoundUpToPowerOfTwoSizeUInt(x:TPasGLTFSizeUInt):TPasGLTFSizeUInt;
+       procedure SetCount(const pNewCount:TPasGLTFSizeInt);
+       function GetItem(const pIndex:TPasGLTFSizeInt):T;
+       procedure SetItem(const pIndex:TPasGLTFSizeInt;const pItem:T);
+      public
+       constructor Create;
+       destructor Destroy; override;
+       procedure Clear;
+       function IndexOf(const pItem:T):TPasGLTFSizeInt;
+       function Add(const pItem:T):TPasGLTFSizeInt;
+       procedure Insert(const pIndex:TPasGLTFSizeInt;const pItem:T);
+       procedure Delete(const pIndex:TPasGLTFSizeInt);
+       procedure Remove(const pItem:T);
+       procedure Exchange(const pIndex,pWithIndex:TPasGLTFSizeInt);
+       function GetEnumerator:TValueEnumerator;
+       property Count:TPasGLTFSizeInt read fCount write SetCount;
+       property Allocated:TPasGLTFSizeInt read fAllocated;
+       property Items[const pIndex:TPasGLTFSizeInt]:T read GetItem write SetItem; default;
+       property OwnsObjects:boolean read fOwnsObjects write fOwnsObjects;
+     end;
+
+implementation
+
+constructor TPasGLTFObjectList<T>.TValueEnumerator.Create(const aObjectList:TPasGLTFObjectList<T>);
+begin
+end;
+
+function TPasGLTFObjectList<T>.TValueEnumerator.MoveNext:boolean;
+begin
+end;
+
+function TPasGLTFObjectList<T>.TValueEnumerator.GetCurrent:T;
+begin
+end;
+
+constructor TPasGLTFObjectList<T>.Create;
+begin
+end;
+
+destructor TPasGLTFObjectList<T>.Destroy;
+begin
+end;
+
+function TPasGLTFObjectList<T>.RoundUpToPowerOfTwoSizeUInt(x:TPasGLTFSizeUInt):TPasGLTFSizeUInt;
+begin
+end;
+
+procedure TPasGLTFObjectList<T>.Clear;
+var Index:TPasGLTFSizeInt;
+begin
+end;
+
+procedure TPasGLTFObjectList<T>.SetCount(const pNewCount:TPasGLTFSizeInt);
+var Index,NewAllocated:TPasGLTFSizeInt;
+begin
+end;
+
+function TPasGLTFObjectList<T>.GetItem(const pIndex:TPasGLTFSizeInt):T;
+begin
+end;
+
+procedure TPasGLTFObjectList<T>.SetItem(const pIndex:TPasGLTFSizeInt;const pItem:T);
+begin
+end;
+
+function TPasGLTFObjectList<T>.IndexOf(const pItem:T):TPasGLTFSizeInt;
+var Index:TPasGLTFSizeInt;
+begin
+end;
+
+function TPasGLTFObjectList<T>.Add(const pItem:T):TPasGLTFSizeInt;
+begin
+end;
+
+procedure TPasGLTFObjectList<T>.Insert(const pIndex:TPasGLTFSizeInt;const pItem:T);
+var OldCount:TPasGLTFSizeInt;
+begin
+   System.Move(fItems[pIndex],fItems[pIndex+1],(OldCount-pIndex)*SizeOf(T));
+end;
+
+procedure TPasGLTFObjectList<T>.Delete(const pIndex:TPasGLTFSizeInt);
+var Old:T;
+begin
+
+end;
+
+procedure TPasGLTFObjectList<T>.Remove(const pItem:T);
+var Index:TPasGLTFSizeInt;
+begin
+end;
+
+procedure TPasGLTFObjectList<T>.Exchange(const pIndex,pWithIndex:TPasGLTFSizeInt);
+var Temporary:T;
+begin
+end;
+
+function TPasGLTFObjectList<T>.GetEnumerator:TPasGLTFObjectList<T>.TValueEnumerator;
+begin
+end;
+
+end.
+