Browse Source

Merge branch 'main' into mos6502

Nikolay Nikolov 1 month ago
parent
commit
4298bc09e1
53 changed files with 1018 additions and 155 deletions
  1. 6 1
      compiler/Makefile
  2. 7 1
      compiler/Makefile.fpc
  3. 3 1
      compiler/aasmbase.pas
  4. 1 1
      compiler/aasmcnst.pas
  5. 13 3
      compiler/aggas.pas
  6. 17 2
      compiler/aoptobj.pas
  7. 67 0
      compiler/avr/navrutil.pas
  8. 2 0
      compiler/fpcdefs.inc
  9. 9 0
      compiler/globals.pas
  10. 2 1
      compiler/htypechk.pas
  11. 16 1
      compiler/nadd.pas
  12. 8 2
      compiler/ncal.pas
  13. 2 1
      compiler/ogbase.pas
  14. 2 1
      compiler/ogcoff.pas
  15. 2 1
      compiler/ogelf.pas
  16. 2 1
      compiler/ogrel.pas
  17. 2 1
      compiler/ogwasm.pas
  18. 4 2
      compiler/omfbase.pas
  19. 2 0
      compiler/pgentype.pas
  20. 13 15
      compiler/pgenutil.pas
  21. 1 0
      compiler/powerpc/agppcmpw.pas
  22. 198 50
      compiler/riscv/cgrv.pas
  23. 2 20
      compiler/riscv64/cgcpu.pas
  24. 12 0
      compiler/scandir.pas
  25. 1 1
      compiler/symdef.pas
  26. 1 1
      compiler/symsym.pas
  27. 10 0
      compiler/symtable.pas
  28. 2 0
      compiler/x86/agx86int.pas
  29. 2 1
      compiler/x86/agx86nsm.pas
  30. 2 1
      compiler/z80/agsdasz80.pas
  31. 2 1
      compiler/z80/agz80vasm.pas
  32. 136 6
      packages/fcl-jsonschema/src/fpjson.schema.codegen.pp
  33. 16 3
      packages/fcl-jsonschema/src/fpjson.schema.pascaltypes.pp
  34. 8 8
      packages/fcl-openapi/src/fpopenapi.generators.pp
  35. 63 24
      packages/fcl-openapi/src/fpopenapi.pascaltypes.pp
  36. 2 2
      packages/rtl-console/src/unix/keyboard.pp
  37. 1 1
      rtl/inc/exeinfo.pp
  38. 1 1
      rtl/morphos/si_prc.pp
  39. 22 0
      tests/tbs/tb0162.pp
  40. 17 0
      tests/tbs/tb0723.pp
  41. 23 0
      tests/tbs/tb0724.pp
  42. 17 0
      tests/tbs/ub0724a.pp
  43. 10 0
      tests/tbs/ub0724b.pp
  44. 10 0
      tests/tbs/ub0724c.pp
  45. 28 0
      tests/test/tgeneric128.pp
  46. 18 0
      tests/test/tgeneric129.pp
  47. 22 0
      tests/test/toperator97.pp
  48. 57 0
      tests/test/tpointermath4.pp
  49. 27 0
      tests/test/tpointermath5.pp
  50. 15 0
      tests/test/tpointermath6.pp
  51. 68 0
      tests/webtbs/tw39917.pp
  52. 9 0
      tests/webtbs/tw41458.pp
  53. 35 0
      tests/webtbs/uw41458.pp

+ 6 - 1
compiler/Makefile

@@ -5409,6 +5409,11 @@ endif
 ifeq ($(COMPILEREXENAME),)
 ifeq ($(COMPILEREXENAME),)
 COMPILEREXENAME:=$(EXENAME)
 COMPILEREXENAME:=$(EXENAME)
 endif
 endif
+ifeq ($(OS_SOURCE),morphos)
+COMPILEREXEDIR:=$(shell echo $(BASEDIR) | sed 's/\///;s/\//:/')
+else
+COMPILEREXEDIR:=$(BASEDIR)
+endif
 .PHONY : revision
 .PHONY : revision
 revision :
 revision :
 	$(DEL) revision.inc
 	$(DEL) revision.inc
@@ -5429,7 +5434,7 @@ else
 endif
 endif
 	$(COMPILER) version.pas
 	$(COMPILER) version.pas
 endif
 endif
-	$(COMPILER) -o$(BASEDIR)/$(COMPILEREXENAME) pp.pas
+	$(COMPILER) -o$(COMPILEREXEDIR)/$(COMPILEREXENAME) pp.pas
 	$(EXECPPAS)
 	$(EXECPPAS)
 .PHONY: cycle full full_targets fullcycle wpocycle
 .PHONY: cycle full full_targets fullcycle wpocycle
 ifeq ($(CPU_SOURCE),$(PPC_TARGET))
 ifeq ($(CPU_SOURCE),$(PPC_TARGET))

+ 7 - 1
compiler/Makefile.fpc

@@ -919,6 +919,12 @@ ifeq ($(COMPILEREXENAME),)
 COMPILEREXENAME:=$(EXENAME)
 COMPILEREXENAME:=$(EXENAME)
 endif
 endif
 
 
+ifeq ($(OS_SOURCE),morphos)
+COMPILEREXEDIR:=$(shell echo $(BASEDIR) | sed 's/\///;s/\//:/')
+else
+COMPILEREXEDIR:=$(BASEDIR)
+endif
+
 .PHONY : revision
 .PHONY : revision
 
 
 revision :
 revision :
@@ -943,7 +949,7 @@ else
 endif
 endif
         $(COMPILER) version.pas
         $(COMPILER) version.pas
 endif
 endif
-        $(COMPILER) -o$(BASEDIR)/$(COMPILEREXENAME) pp.pas
+        $(COMPILER) -o$(COMPILEREXEDIR)/$(COMPILEREXENAME) pp.pas
         $(EXECPPAS)
         $(EXECPPAS)
 
 
 #####################################################################
 #####################################################################

+ 3 - 1
compiler/aasmbase.pas

@@ -181,7 +181,9 @@ interface
          sec_heap,
          sec_heap,
          { dwarf based/gcc style exception handling }
          { dwarf based/gcc style exception handling }
          sec_gcc_except_table,
          sec_gcc_except_table,
-         sec_arm_attribute
+         sec_arm_attribute,
+         { Used for GNU .note sections }
+         sec_note
        );
        );
 
 
        TObjCAsmSectionType = sec_objc_class..sec_objc_protolist;
        TObjCAsmSectionType = sec_objc_class..sec_objc_protolist;

+ 1 - 1
compiler/aasmcnst.pas

@@ -1021,7 +1021,7 @@ implementation
               if not(section in [low(TObjCAsmSectionType)..high(TObjCAsmSectionType)]) then
               if not(section in [low(TObjCAsmSectionType)..high(TObjCAsmSectionType)]) then
                 prelist.concat(tai_directive.Create(asd_reference,asmsym.name))
                 prelist.concat(tai_directive.Create(asd_reference,asmsym.name))
              end
              end
-           else if section<>sec_fpc then
+           else if not(section in [sec_fpc,sec_note]) then
              internalerror(2015101402);
              internalerror(2015101402);
          end;
          end;
 
 

+ 13 - 3
compiler/aggas.pas

@@ -206,6 +206,7 @@ implementation
            create_smartlink_sections and
            create_smartlink_sections and
            (atype<>sec_toc) and
            (atype<>sec_toc) and
            (atype<>sec_user) and
            (atype<>sec_user) and
+           (atype<>sec_note) and
            { on embedded systems every byte counts, so smartlink bss too }
            { on embedded systems every byte counts, so smartlink bss too }
            ((atype<>sec_bss) or (target_info.system in (systems_embedded+systems_freertos)));
            ((atype<>sec_bss) or (target_info.system in (systems_embedded+systems_freertos)));
       end;
       end;
@@ -282,7 +283,8 @@ implementation
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
         secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
         secnames_pic : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
           '.text',
           '.text',
@@ -343,7 +345,8 @@ implementation
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           '.gcc_except_table',
           '.gcc_except_table',
-          '..ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
       var
       var
         sep     : string[3];
         sep     : string[3];
@@ -398,6 +401,9 @@ implementation
         if atype=sec_user then
         if atype=sec_user then
           secname:=aname;
           secname:=aname;
 
 
+        if atype=sec_note then
+          secname:='.note'+aname;
+
         if is_smart_section(atype) and (aname<>'') then
         if is_smart_section(atype) and (aname<>'') then
           begin
           begin
             case aorder of
             case aorder of
@@ -580,6 +586,7 @@ implementation
              if not(atype in [sec_data,sec_rodata,sec_rodata_norel]) and
              if not(atype in [sec_data,sec_rodata,sec_rodata_norel]) and
                 not(asminfo^.id=as_solaris_as) and
                 not(asminfo^.id=as_solaris_as) and
                 not(atype=sec_fpc) and
                 not(atype=sec_fpc) and
+                not(atype=sec_note) and
                 not(target_info.system in (systems_embedded+systems_freertos)) then
                 not(target_info.system in (systems_embedded+systems_freertos)) then
                begin
                begin
                  usesectionflags:=true;
                  usesectionflags:=true;
@@ -646,6 +653,8 @@ implementation
                     internalerror(2006031101);
                     internalerror(2006031101);
                 end;
                 end;
               end;
               end;
+            sec_note :
+              writer.AsmWrite(', "", @note');
           else
           else
             { GNU AS won't recognize '.text.n_something' section name as belonging
             { GNU AS won't recognize '.text.n_something' section name as belonging
               to '.text' and assigns default attributes to it, which is not
               to '.text' and assigns default attributes to it, which is not
@@ -2264,7 +2273,8 @@ implementation
          sec_none (* sec_stack *),
          sec_none (* sec_stack *),
          sec_none (* sec_heap *),
          sec_none (* sec_heap *),
          sec_none (* gcc_except_table *),
          sec_none (* gcc_except_table *),
-         sec_none (* sec_arm_attribute *)
+         sec_none (* sec_arm_attribute *),
+         sec_none (* sec_note *)
         );
         );
       begin
       begin
         Result := inherited SectionName (SecXTable [AType], AName, AOrder);
         Result := inherited SectionName (SecXTable [AType], AName, AOrder);

+ 17 - 2
compiler/aoptobj.pas

@@ -29,7 +29,7 @@ Unit AoptObj;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
-{$if not defined(JVM) and not defined(WASM) and not defined(POWERPC) and not defined (POWERPC64)}
+{$if not defined(JVM) and not defined(WASM)}
 {$define CPU_SUPPORTS_OPT_COND_JUMP}
 {$define CPU_SUPPORTS_OPT_COND_JUMP}
 {$endif}
 {$endif}
 
 
@@ -1261,13 +1261,28 @@ Unit AoptObj;
 
 
       class function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
       class function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
       Var TempP: Tai;
       Var TempP: Tai;
+{$ifdef CPU_BC_HAS_SIZE_LIMIT}
+         count: ASizeUInt;
+{$endif CPU_BC_HAS_SIZE_LIMIT}
       Begin
       Begin
         TempP := hp;
         TempP := hp;
+{$ifdef CPU_BC_HAS_SIZE_LIMIT}
+        count:=0;
+{$endif CPU_BC_HAS_SIZE_LIMIT}
         While Assigned(TempP) and
         While Assigned(TempP) and
+{$ifdef CPU_BC_HAS_SIZE_LIMIT}
+	     (count < BC_max_distance) and
+{$endif CPU_BC_HAS_SIZE_LIMIT}
              (TempP.typ In SkipInstr + [ait_label,ait_align]) Do
              (TempP.typ In SkipInstr + [ait_label,ait_align]) Do
           If (TempP.typ <> ait_Label) Or
           If (TempP.typ <> ait_Label) Or
              (Tai_label(TempP).labsym <> L)
              (Tai_label(TempP).labsym <> L)
-            Then GetNextInstruction(TempP, TempP)
+            Then
+               begin
+                 GetNextInstruction(TempP, TempP);
+{$ifdef CPU_BC_HAS_SIZE_LIMIT}
+		 inc(count);
+{$endif CPU_BC_HAS_SIZE_LIMIT}
+               end
             Else
             Else
               Begin
               Begin
                 hp := TempP;
                 hp := TempP;

+ 67 - 0
compiler/avr/navrutil.pas

@@ -34,9 +34,14 @@ interface
 
 
 
 
   type
   type
+
+    { tavrnodeutils }
+
     tavrnodeutils = class(tnodeutils)
     tavrnodeutils = class(tnodeutils)
     protected
     protected
       class procedure insert_init_final_table(main: tmodule; entries:tfplist); override;
       class procedure insert_init_final_table(main: tmodule; entries:tfplist); override;
+    public
+      class procedure InsertMemorySizes; override;
     end;
     end;
 
 
 implementation
 implementation
@@ -108,6 +113,68 @@ implementation
       inherited insert_init_final_table(main,entries);
       inherited insert_init_final_table(main,entries);
     end;
     end;
 
 
+  class procedure tavrnodeutils.InsertMemorySizes;
+    var
+      tcb: ttai_typedconstbuilder;
+      notename, strtable: shortstring;
+      sym: tasmsymbol;
+      defstr, defu32: tdef;
+    begin
+      { Store device information in the .note.gnu.avr.deviceinfo section.
+
+        Layout of.note.gnu.avr.deviceinfo:
+         note_name_len: dword
+         note_desc_len: dword // Size of the Tavr_desc data record
+         note_type: dword = 1
+         Tavr_desc = record
+           note_name: char[note_name_len] = 'AVR'#0;
+           flash_start,
+           flash_size,
+           sram_start,
+           sram_size,
+           eeprom_start,
+           eeprom_size: dword;
+           offset_table_len: dword;
+           offset_table: char[] = #0+mcuname#0+#0;
+         end }
+
+      notename:='AVR'#0;
+      strtable:=#0+lower(embedded_controllers[current_settings.controllertype].controllertypestr)+#0#0;
+      tcb:=ctai_typedconstbuilder.create([tcalo_no_dead_strip]);
+      defu32:=corddef.create(u32bit,0,$FFFFFFFF,false);
+      tcb.maybe_begin_aggregate(defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(length(notename)),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(length(strtable)+32),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(1),defu32);
+      defstr:=carraydef.getreusable(cansichartype,length(notename));
+      tcb.maybe_begin_aggregate(defstr);
+      tcb.emit_tai(Tai_string.Create(notename),defstr);
+      tcb.maybe_begin_aggregate(defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(embedded_controllers[current_settings.controllertype].flashbase),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(embedded_controllers[current_settings.controllertype].flashsize),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(embedded_controllers[current_settings.controllertype].srambase),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(embedded_controllers[current_settings.controllertype].sramsize),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(embedded_controllers[current_settings.controllertype].eeprombase),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(embedded_controllers[current_settings.controllertype].eepromsize),defu32);
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(8),defu32);  // Size of string offset table
+      tcb.emit_tai(tai_const.Create_32bit_unaligned(1),defu32);  // Offset of string in table
+      tcb.maybe_begin_aggregate(defstr);
+      tcb.emit_tai(Tai_string.Create(strtable),defstr);
+      tcb.maybe_end_aggregate(defstr);
+      tcb.maybe_end_aggregate(defu32);
+      tcb.maybe_end_aggregate(defstr);
+      tcb.maybe_end_aggregate(defu32);
+
+      sym:=current_asmdata.DefineAsmSymbol('__AVR_deviceinfo',AB_LOCAL,AT_DATA,defstr);
+      current_asmdata.asmlists[al_globals].concatlist(
+        tcb.get_final_asmlist(sym,defstr,sec_note,'.gnu.avr.deviceinfo',const_align(32))
+      );
+      defu32.free;
+      tcb.free;
+
+      inherited InsertMemorySizes;
+    end;
+
 begin
 begin
   cnodeutils:=tavrnodeutils;
   cnodeutils:=tavrnodeutils;
 end.
 end.

+ 2 - 0
compiler/fpcdefs.inc

@@ -183,6 +183,7 @@
   {$define cpurefshaveindexreg}
   {$define cpurefshaveindexreg}
   {$define SUPPORT_SAFECALL}
   {$define SUPPORT_SAFECALL}
   {$define SUPPORT_GET_FRAME}
   {$define SUPPORT_GET_FRAME}
+  {$define CPU_BC_HAS_SIZE_LIMIT}
 {$endif powerpc}
 {$endif powerpc}
 
 
 {$ifdef powerpc64}
 {$ifdef powerpc64}
@@ -196,6 +197,7 @@
   {$define cpurefshaveindexreg}
   {$define cpurefshaveindexreg}
   {$define cpuno32bitops}
   {$define cpuno32bitops}
   {$define SUPPORT_SAFECALL}
   {$define SUPPORT_SAFECALL}
+  {$define CPU_BC_HAS_SIZE_LIMIT}
 {$endif powerpc64}
 {$endif powerpc64}
 
 
 {$ifdef arm}
 {$ifdef arm}

+ 9 - 0
compiler/globals.pas

@@ -232,6 +232,15 @@ Const
 
 
     const
     const
       LinkMapWeightDefault = 1000;
       LinkMapWeightDefault = 1000;
+{$ifdef CPU_BC_HAS_SIZE_LIMIT}
+    {$if defined(POWERPC) or defined(POWERPC64)}
+      { instructions are 4-byte long and relative jump distance
+        a signed 16-bit signed integer, code as
+        reduced by a small amount to avoid troubles
+        as distance can be modified by optimizations. }
+      BC_max_distance = ($8000 div 4) - $100;
+    {$endif}
+{$endif CPU_BC_HAS_SIZE_LIMIT}
 
 
     type
     type
       TLinkRec = record
       TLinkRec = record

+ 2 - 1
compiler/htypechk.pas

@@ -528,7 +528,8 @@ implementation
                  { <dyn. array> + <dyn. array> is handled by the compiler }
                  { <dyn. array> + <dyn. array> is handled by the compiler }
                  if (m_array_operators in current_settings.modeswitches) and
                  if (m_array_operators in current_settings.modeswitches) and
                      (treetyp=addn) and
                      (treetyp=addn) and
-                     (is_dynamic_array(ld) or is_dynamic_array(rd)) then
+                     (is_dynamic_array(ld) or is_array_constructor(ld)) and
+                     (is_dynamic_array(rd) or is_array_constructor(rd)) then
                     begin
                     begin
                       allowed:=false;
                       allowed:=false;
                       exit;
                       exit;

+ 16 - 1
compiler/nadd.pas

@@ -2874,7 +2874,22 @@ const
                         inserttypeconv(right,left.resultdef)
                         inserttypeconv(right,left.resultdef)
                        else if is_voidpointer(left.resultdef) then
                        else if is_voidpointer(left.resultdef) then
                         inserttypeconv(left,right.resultdef)
                         inserttypeconv(left,right.resultdef)
-                       else if not(equal_defs(ld,rd)) then
+                       else if not (
+                           { in Delphi two different pointer types can be compared
+                             if either $POINTERMATH is currently enabled or if
+                             both pointer defs were declared with $POINTERMATH
+                             enabled }
+                           (m_delphi in current_settings.modeswitches) and
+                           (ld.typ=pointerdef) and
+                           (rd.typ=pointerdef) and
+                           (
+                             (cs_pointermath in current_settings.localswitches) or
+                             (
+                               tpointerdef(ld).has_pointer_math and
+                               tpointerdef(rd).has_pointer_math
+                             )
+                           )
+                         ) and not(equal_defs(ld,rd)) then
                         IncompatibleTypes(ld,rd);
                         IncompatibleTypes(ld,rd);
                      end
                      end
                     else
                     else

+ 8 - 2
compiler/ncal.pas

@@ -4265,9 +4265,15 @@ implementation
 
 
                    { if the final procedure definition is not yet owned,
                    { if the final procedure definition is not yet owned,
                      ensure that it is }
                      ensure that it is }
-                   procdefinition.register_def;
                    if (procdefinition.typ=procdef) and assigned(tprocdef(procdefinition).procsym) then
                    if (procdefinition.typ=procdef) and assigned(tprocdef(procdefinition).procsym) then
-                     tprocdef(procdefinition).procsym.register_sym;
+                     begin
+                       { if the procdef does not yet have an owner (e.g. because it has just been
+                         specialized) then insert it into the same owner as the procsym }
+                       if not assigned(procdefinition.owner) and assigned(tprocdef(procdefinition).procsym.owner) then
+                         tprocdef(procdefinition).procsym.owner.insertdef(procdefinition);
+                       tprocdef(procdefinition).procsym.register_sym;
+                     end;
+                   procdefinition.register_def;
 
 
                    if procdefinition.is_specialization and (procdefinition.typ=procdef) then
                    if procdefinition.is_specialization and (procdefinition.typ=procdef) then
                      maybe_add_pending_specialization(procdefinition,candidates.para_anon_syms);
                      maybe_add_pending_specialization(procdefinition,candidates.para_anon_syms);

+ 2 - 1
compiler/ogbase.pas

@@ -1532,7 +1532,8 @@ implementation
           {stack} [oso_load,oso_write],
           {stack} [oso_load,oso_write],
           {heap} [oso_load,oso_write],
           {heap} [oso_load,oso_write],
           {gcc_except_table} [oso_data,oso_load],
           {gcc_except_table} [oso_data,oso_load],
-          {arm_attribute} [oso_data]
+          {arm_attribute} [oso_data],
+          {note} [oso_Data,oso_note]
         );
         );
       begin
       begin
         if target_asm.id in asms_int_coff then
         if target_asm.id in asms_int_coff then

+ 2 - 1
compiler/ogcoff.pas

@@ -986,7 +986,8 @@ implementation
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
 
 
 const go32v2stub : array[0..2047] of byte=(
 const go32v2stub : array[0..2047] of byte=(

+ 2 - 1
compiler/ogelf.pas

@@ -568,7 +568,8 @@ implementation
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
       var
       var
         sep : string[3];
         sep : string[3];

+ 2 - 1
compiler/ogrel.pas

@@ -318,7 +318,8 @@ implementation
           '_STACK',
           '_STACK',
           '_HEAP',
           '_HEAP',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
       begin
       begin
         if atype=sec_user then
         if atype=sec_user then

+ 2 - 1
compiler/ogwasm.pas

@@ -1015,7 +1015,8 @@ implementation
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
       var
       var
         sep     : string[3];
         sep     : string[3];

+ 4 - 2
compiler/omfbase.pas

@@ -88,7 +88,8 @@ interface
       'stack',
       'stack',
       'heap',
       'heap',
       'gcc_except_table',
       'gcc_except_table',
-      'ARM_attributes'
+      'ARM_attributes',
+      'note'
     );
     );
 
 
     { OMF record types }
     { OMF record types }
@@ -2966,7 +2967,8 @@ implementation
         {stack} 'STACK',
         {stack} 'STACK',
         {heap} 'HEAP',
         {heap} 'HEAP',
         {gcc_except_table} 'DATA',
         {gcc_except_table} 'DATA',
-        {ARM_attributes} 'DATA'
+        {ARM_attributes} 'DATA',
+        {note} 'DATA'
       );
       );
     begin
     begin
       result:=segclass[atype];
       result:=segclass[atype];

+ 2 - 0
compiler/pgentype.pas

@@ -27,6 +27,7 @@ interface
 
 
 uses
 uses
   cclasses,
   cclasses,
+  tokens,
   globtype,
   globtype,
   symtype,symbase;
   symtype,symbase;
 
 
@@ -41,6 +42,7 @@ type
     oldgenericdummysyms   : tfphashobjectlist;
     oldgenericdummysyms   : tfphashobjectlist;
     oldspecializestate    : pspecializationstate;
     oldspecializestate    : pspecializationstate;
     oldcurrent_genericdef : tdef;
     oldcurrent_genericdef : tdef;
+    oldoptoken            : ttoken;
   end;
   end;
 
 
   tspecializationcontext=class
   tspecializationcontext=class

+ 13 - 15
compiler/pgenutil.pas

@@ -2784,6 +2784,8 @@ uses
       state.oldgenericdummysyms:=current_module.genericdummysyms;
       state.oldgenericdummysyms:=current_module.genericdummysyms;
       state.oldcurrent_genericdef:=current_genericdef;
       state.oldcurrent_genericdef:=current_genericdef;
       state.oldspecializestate:=pspecializationstate(current_module.specializestate);
       state.oldspecializestate:=pspecializationstate(current_module.specializestate);
+      state.oldoptoken:=optoken;
+      optoken:=NOTOKEN;
       current_module.specializestate:=@state;
       current_module.specializestate:=@state;
       current_module.extendeddefs:=TFPHashObjectList.create(true);
       current_module.extendeddefs:=TFPHashObjectList.create(true);
       current_module.genericdummysyms:=tfphashobjectlist.create(true);
       current_module.genericdummysyms:=tfphashobjectlist.create(true);
@@ -2821,23 +2823,18 @@ uses
               that we specialize a generic in a different unit that was used
               that we specialize a generic in a different unit that was used
               in the implementation section of the generic's unit and were the
               in the implementation section of the generic's unit and were the
               interface is still being parsed and thus the localsymtable is in
               interface is still being parsed and thus the localsymtable is in
-              reality the global symtable }
+              reality the global symtable
+
+              In addition to that it can also be the case that neither the
+              global- nor the localsymtable is set, namely when the compiler
+              didn't yet have the chance to process on of the units in the
+              (implementation) uses clause simply due to the orders, so don't
+              add anything of that unit yet (once routine bodies need to be
+              specialized everything needed should be in place however). }
             if pu.u.in_interface then
             if pu.u.in_interface then
               begin
               begin
-                {
-                  MVC: The case where localsymtable is also nil can appear in complex cases and still produce valid code.
-                  In order to allow people in this case to continue, SKIP_INTERNAL20231102 can be defined.
-                  Default behaviour is to raise an internal error.
-                  See also
-                  https://gitlab.com/freepascal.org/fpc/source/-/issues/40502
-                }
-                {$IFDEF SKIP_INTERNAL20231102}
-                if (pu.u.localsymtable<>Nil) then
-                {$ELSE}
-                if (pu.u.localsymtable=Nil) then
-                  internalerror(20231102);
-                {$ENDIF}
-                  symtablestack.push(pu.u.localsymtable);
+                if assigned(pu.u.localsymtable) then
+                  symtablestack.push(pu.u.localsymtable)
               end
               end
             else
             else
               internalerror(200705153)
               internalerror(200705153)
@@ -2865,6 +2862,7 @@ uses
       current_module.genericdummysyms.free;
       current_module.genericdummysyms.free;
       current_module.genericdummysyms:=state.oldgenericdummysyms;
       current_module.genericdummysyms:=state.oldgenericdummysyms;
       current_module.specializestate:=state.oldspecializestate;
       current_module.specializestate:=state.oldspecializestate;
+      optoken:=state.oldoptoken;
       symtablestack.free;
       symtablestack.free;
       symtablestack:=state.oldsymtablestack;
       symtablestack:=state.oldsymtablestack;
       { clear the state record to be on the safe side }
       { clear the state record to be on the safe side }

+ 1 - 0
compiler/powerpc/agppcmpw.pas

@@ -123,6 +123,7 @@ interface
         '',
         '',
         '',
         '',
         '',
         '',
+        '',
         ''
         ''
       );
       );
 
 

+ 198 - 50
compiler/riscv/cgrv.pas

@@ -50,6 +50,8 @@ unit cgrv;
 
 
         procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); override;
         procedure a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister); override;
         procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override;
         procedure a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister); override;
+        procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); override;
+        procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
 
 
         procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
         procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
 
 
@@ -67,6 +69,8 @@ unit cgrv;
 
 
         procedure g_profilecode(list: TAsmList); override;
         procedure g_profilecode(list: TAsmList); override;
 
 
+        procedure g_overflowcheck_loc(list: TAsmList; const Loc: tlocation; def: tdef; ovloc: tlocation); override;
+
         { fpu move instructions }
         { fpu move instructions }
         procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
         procedure a_loadfpu_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;
         procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
         procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
@@ -216,64 +220,29 @@ unit cgrv;
 
 
     procedure tcgrv.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
     procedure tcgrv.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
       var
       var
-        tmpreg: TRegister;
+        ovloc: tlocation;
       begin
       begin
-        optimize_op_const(size,op,a);
-
-        if op=OP_NONE then
-          begin
-            a_load_reg_reg(list,size,size,src,dst);
-            exit;
-          end;
-
-        if op=OP_SUB then
-          begin
-            op:=OP_ADD;
-            a:=-a;
-          end;
-
-{$ifdef RISCV64}
-        if (op=OP_SHL) and
-               (size=OS_S32) then
-          begin
-            list.concat(taicpu.op_reg_reg_const(A_SLLIW,dst,src,a));
-            maybeadjustresult(list,op,size,dst);
-          end
-        else if (op=OP_SHR) and
-               (size=OS_S32) then
-          begin
-            list.concat(taicpu.op_reg_reg_const(A_SRLIW,dst,src,a));
-            maybeadjustresult(list,op,size,dst);
-          end
-        else if (op=OP_SAR) and
-               (size=OS_S32) then
-          begin
-            list.concat(taicpu.op_reg_reg_const(A_SRAIW,dst,src,a));
-            maybeadjustresult(list,op,size,dst);
-          end
-        else
-{$endif RISCV64}
-        if (TOpCG2AsmConstOp[op]<>A_None) and
-           is_imm12(a) then
-          begin
-            list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a));
-            maybeadjustresult(list,op,size,dst);
-          end
-        else
-          begin
-            tmpreg:=getintregister(list,size);
-            a_load_const_reg(list,size,a,tmpreg);
-            a_op_reg_reg_reg(list,op,size,tmpreg,src,dst);
-          end;
-      end;   
+        a_op_const_reg_reg_checkoverflow(list, op, size, a, src, dst, false, ovloc);
+      end;
 
 
 
 
-    procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
+    procedure tcgrv.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
       var
       var
         name: String;
         name: String;
         pd: tprocdef;
         pd: tprocdef;
         paraloc1, paraloc2: tcgpara;
         paraloc1, paraloc2: tcgpara;
+        ai: taicpu;
+        tmpreg1, tmpreg2: TRegister;
       begin
       begin
+        if setflags and
+          { do we know overflow checking for this operation? fix me! }(size in [OS_32,OS_S32]) and (op in [OP_ADD,OP_SUB,OP_MUL,OP_IMUL,OP_IDIV,OP_NEG]) then
+          begin
+            ovloc.loc:=LOC_JUMP;
+            current_asmdata.getjumplabel(ovloc.truelabel);
+            current_asmdata.getjumplabel(ovloc.falselabel);
+          end
+        else
+          ovloc.loc:=LOC_VOID;
         if op=OP_NOT then
         if op=OP_NOT then
           begin
           begin
             list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
             list.concat(taicpu.op_reg_reg_const(A_XORI,dst,src1,-1));
@@ -282,6 +251,15 @@ unit cgrv;
         else if op=OP_NEG then
         else if op=OP_NEG then
           begin
           begin
             list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
             list.concat(taicpu.op_reg_reg_reg(A_SUB,dst,NR_X0,src1));
+
+            if setflags then
+              begin
+                { if dst and src are equal, an overflow happened }
+                a_cmp_reg_reg_label(list,OS_INT,OC_NE,dst,src1,ovloc.falselabel);
+
+                a_jmp_always(list,ovloc.truelabel);
+              end;
+
             maybeadjustresult(list,op,size,dst);
             maybeadjustresult(list,op,size,dst);
           end
           end
         else
         else
@@ -358,13 +336,168 @@ unit cgrv;
               end
               end
             else
             else
               begin
               begin
+                if setflags and (op=OP_MUL) and (size=OS_32) then
+                  begin
+                    tmpreg1:=getintregister(list,size);
+                    list.concat(taicpu.op_reg_reg_reg(A_MULHU,tmpreg1,src2,src1));
+                  end
+                else
+                  tmpreg1:=NR_NO;
                 list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
                 list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOp[op],dst,src2,src1));
+                if setflags and (size in [OS_S32,OS_32]) then
+                  begin
+                    case op of
+                      OP_ADD:
+                        begin
+                          if size=OS_SINT then
+                            begin
+                              tmpreg1:=getintregister(list,size);
+                              list.concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg1,dst,src2));
+                              tmpreg2:=getintregister(list,size);
+                              list.concat(taicpu.op_reg_reg_const(A_SLTI,tmpreg2,src1,0));
+                              a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg1,tmpreg2,ovloc.falselabel)
+                            end
+                          else if size=OS_INT then
+                            begin
+                              ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,dst,src2,ovloc.falselabel,0);
+                              ai.condition:=C_GEU;
+                              list.concat(ai);
+                            end
+                          else
+                            Internalerror(2025102003);
+                          a_jmp_always(list,ovloc.truelabel);
+                        end;
+                      OP_SUB:
+                        begin
+                          if size=OS_S32 then
+                            begin
+                              tmpreg1:=getintregister(list,size);
+                              list.concat(taicpu.op_reg_reg_reg(A_SLT,tmpreg1,src2,dst));
+                              tmpreg2:=getintregister(list,size);
+                              list.concat(taicpu.op_reg_reg_const(A_SLTI,tmpreg2,src1,0));
+                              a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg1,tmpreg2,ovloc.falselabel)
+                            end
+                          else if size=OS_32 then
+                            begin
+                              ai:=taicpu.op_reg_reg_sym_ofs(A_Bxx,src2,dst,ovloc.falselabel,0);
+                              ai.condition:=C_GEU;
+                              list.concat(ai);
+                            end
+                          else
+                            Internalerror(2025102002);
+                          a_jmp_always(list,ovloc.truelabel);
+                        end;
+                      OP_MUL:
+                        begin
+                          if size=OS_INT then
+                            a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg1,NR_X0,ovloc.falselabel)
+                          else
+                            Internalerror(2025102002);
+                          a_jmp_always(list,ovloc.truelabel);
+                        end;
+                      OP_IMUL:
+                        begin
+                          if size=OS_SINT then
+                            begin
+                              tmpreg1:=getintregister(list,size);
+                              list.concat(taicpu.op_reg_reg_reg(A_MULH,tmpreg1,src2,src1));
+                              tmpreg2:=getintregister(list,size);
+                              list.concat(taicpu.op_reg_reg_const(A_SRAI,tmpreg2,dst,31));
+                              a_cmp_reg_reg_label(list,OS_INT,OC_EQ,tmpreg1,tmpreg2,ovloc.falselabel);
+                            end
+                          else
+                            Internalerror(2025102004);
+                          a_jmp_always(list,ovloc.truelabel);
+                        end;
+                      OP_IDIV:
+                        begin
+                          { Only overflow if dst is all 1's }
+                          tmpreg1:=getintregister(list,OS_INT);
+                          list.Concat(taicpu.op_reg_reg_const(A_ADDI,tmpreg1,dst,1));
+
+                          a_cmp_reg_reg_label(list,OS_INT,OC_NE,tmpreg1,NR_X0,ovloc.falselabel);
+
+                          a_jmp_always(list,ovloc.truelabel);
+                        end;
+                      else
+                        ;
+                    end
+                  end;
                 maybeadjustresult(list,op,size,dst);
                 maybeadjustresult(list,op,size,dst);
               end;
               end;
           end;
           end;
       end;
       end;
 
 
 
 
+    procedure tcgrv.a_op_reg_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister);
+      var
+        ovloc: tlocation;
+      begin
+        a_op_reg_reg_reg_checkoverflow(list, op, size, src1, src2, dst, false, ovloc);
+      end;
+
+
+    procedure tcgrv.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean;
+      var ovloc: tlocation);
+      var
+        tmpreg: TRegister;
+      begin
+        optimize_op_const(size,op,a);
+
+        if op=OP_NONE then
+          begin
+            a_load_reg_reg(list,size,size,src,dst);
+            exit;
+          end;
+
+        if op=OP_SUB then
+          begin
+            op:=OP_ADD;
+            a:=-a;
+          end;
+
+{$ifdef RISCV64}
+        if (op=OP_SHL) and
+               (size=OS_S32) then
+          begin
+            list.concat(taicpu.op_reg_reg_const(A_SLLIW,dst,src,a));
+            maybeadjustresult(list,op,size,dst);
+          end
+        else if (op=OP_SHR) and
+               (size=OS_S32) then
+          begin
+            list.concat(taicpu.op_reg_reg_const(A_SRLIW,dst,src,a));
+            maybeadjustresult(list,op,size,dst);
+          end
+        else if (op=OP_SAR) and
+               (size=OS_S32) then
+          begin
+            list.concat(taicpu.op_reg_reg_const(A_SRAIW,dst,src,a));
+            maybeadjustresult(list,op,size,dst);
+          end
+        else
+{$endif RISCV64}
+        if (TOpCG2AsmConstOp[op]<>A_None) and
+           is_imm12(a) and not(setflags) then
+          begin
+            list.concat(taicpu.op_reg_reg_const(TOpCG2AsmConstOp[op],dst,src,a));
+            maybeadjustresult(list,op,size,dst);
+          end
+        else if setflags then
+          begin
+            tmpreg:=getintregister(list,size);
+            a_load_const_reg(list,size,a,tmpreg);
+            a_op_reg_reg_reg_checkoverflow(list,op,size,tmpreg,src,dst,true,ovloc);
+          end
+        else
+          begin
+            tmpreg:=getintregister(list,size);
+            a_load_const_reg(list,size,a,tmpreg);
+            a_op_reg_reg_reg(list,op,size,tmpreg,src,dst);
+          end;
+      end;
+
+
     procedure tcgrv.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
     procedure tcgrv.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
       var
       var
         href: treference;
         href: treference;
@@ -727,6 +860,21 @@ unit cgrv;
       end;
       end;
 
 
 
 
+    procedure tcgrv.g_overflowcheck_loc(list: TAsmList; const Loc: tlocation; def: tdef; ovloc: tlocation);
+      begin
+        if not(cs_check_overflow in current_settings.localswitches) then
+          exit;
+        { no overflow checking yet generated }
+        if ovloc.loc=LOC_VOID then
+          exit;
+        if ovloc.loc<>LOC_JUMP then
+          Internalerror(2025102001);
+        a_label(list,ovloc.truelabel);
+        a_call_name(list,'FPC_OVERFLOW',false);
+        a_label(list,ovloc.falselabel);
+      end;
+
+
     procedure tcgrv.a_call_reg(list : TAsmList;reg: tregister);
     procedure tcgrv.a_call_reg(list : TAsmList;reg: tregister);
       begin
       begin
         list.concat(taicpu.op_reg_reg(A_JALR,NR_RETURN_ADDRESS_REG,reg));
         list.concat(taicpu.op_reg_reg(A_JALR,NR_RETURN_ADDRESS_REG,reg));

+ 2 - 20
compiler/riscv64/cgcpu.pas

@@ -41,7 +41,6 @@ unit cgcpu;
         procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;     
         procedure a_load_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister); override;     
         procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister); override;
         procedure a_load_const_reg(list: TAsmList; size: tcgsize; a: tcgint; register: tregister); override;
 
 
-        procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
         procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
         procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation); override;
 
 
         procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
         procedure g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef); override;
@@ -204,24 +203,6 @@ implementation
       end;
       end;
 
 
 
 
-    procedure tcgrv64.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister; setflags: boolean; var ovloc: tlocation);
-      var
-        signed: Boolean;
-        l: TAsmLabel;
-        tmpreg: tregister;
-        ai: taicpu;
-      begin
-        if setflags then
-          begin
-            tmpreg:=getintregister(list,size);
-            a_load_const_reg(list,size,a,tmpreg);
-            a_op_reg_reg_reg_checkoverflow(list,op,size,tmpreg,src,dst,setflags,ovloc);
-          end
-        else
-          a_op_const_reg_reg(list,op,size,a,src,dst);
-      end;
-
-
     procedure tcgrv64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
     procedure tcgrv64.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister; setflags: boolean; var ovloc: tlocation);
         var
         var
         signed: Boolean;
         signed: Boolean;
@@ -230,6 +211,7 @@ implementation
         ai: taicpu;
         ai: taicpu;
       begin
       begin
         signed:=tcgsize2unsigned[size]<>size;
         signed:=tcgsize2unsigned[size]<>size;
+        ovloc.loc:=LOC_VOID;
 
 
         if setflags then
         if setflags then
           case op of
           case op of
@@ -362,7 +344,7 @@ implementation
               internalerror(2019051032);
               internalerror(2019051032);
           end
           end
         else
         else
-          a_op_reg_reg_reg(list,op,size,src1,src2,dst);
+          inherited a_op_reg_reg_reg_checkoverflow(list,op,size,src1,src2,dst,false,ovloc);
       end;
       end;
 
 
 
 

+ 12 - 0
compiler/scandir.pas

@@ -475,6 +475,11 @@ unit scandir;
         do_delphiswitch('D');
         do_delphiswitch('D');
       end;
       end;
 
 
+    procedure dir_definitioninfo;
+      begin
+        do_delphiswitch('Y');
+      end;
+
     procedure dir_denypackageunit;
     procedure dir_denypackageunit;
       begin
       begin
         do_moduleflagswitch(mf_package_deny,true);
         do_moduleflagswitch(mf_package_deny,true);
@@ -2015,6 +2020,11 @@ unit scandir;
         do_delphiswitch('J');
         do_delphiswitch('J');
       end;
       end;
 
 
+    procedure dir_yd;
+      begin
+        HandleSwitch('Y','+');
+      end;
+
     procedure dir_z1;
     procedure dir_z1;
       begin
       begin
         current_settings.packenum:=1;
         current_settings.packenum:=1;
@@ -2198,6 +2208,7 @@ unit scandir;
         AddDirective('COPYRIGHT',directive_all, @dir_copyright);
         AddDirective('COPYRIGHT',directive_all, @dir_copyright);
         AddDirective('D',directive_all, @dir_description);
         AddDirective('D',directive_all, @dir_description);
         AddDirective('DEBUGINFO',directive_all, @dir_debuginfo);
         AddDirective('DEBUGINFO',directive_all, @dir_debuginfo);
+        AddDirective('DEFINITIONINFO',directive_all, @dir_definitioninfo);
         AddDirective('DENYPACKAGEUNIT',directive_all,@dir_denypackageunit);
         AddDirective('DENYPACKAGEUNIT',directive_all,@dir_denypackageunit);
         AddDirective('DESCRIPTION',directive_all, @dir_description);
         AddDirective('DESCRIPTION',directive_all, @dir_description);
         AddDirective('ENDREGION',directive_all, @dir_endregion);
         AddDirective('ENDREGION',directive_all, @dir_endregion);
@@ -2309,6 +2320,7 @@ unit scandir;
         AddDirective('WARNINGS',directive_all, @dir_warnings);
         AddDirective('WARNINGS',directive_all, @dir_warnings);
         AddDirective('WEAKPACKAGEUNIT',directive_all, @dir_weakpackageunit);
         AddDirective('WEAKPACKAGEUNIT',directive_all, @dir_weakpackageunit);
         AddDirective('WRITEABLECONST',directive_all, @dir_writeableconst);
         AddDirective('WRITEABLECONST',directive_all, @dir_writeableconst);
+        AdDDirective('YD',directive_all, @dir_yd);
         AddDirective('Z1',directive_all, @dir_z1);
         AddDirective('Z1',directive_all, @dir_z1);
         AddDirective('Z2',directive_all, @dir_z2);
         AddDirective('Z2',directive_all, @dir_z2);
         AddDirective('Z4',directive_all, @dir_z4);
         AddDirective('Z4',directive_all, @dir_z4);

+ 1 - 1
compiler/symdef.pas

@@ -2684,7 +2684,7 @@ implementation
            tmod:=find_module_from_symtable(owner);
            tmod:=find_module_from_symtable(owner);
             if assigned(tmod) and assigned(current_module) and (tmod<>current_module) then
             if assigned(tmod) and assigned(current_module) and (tmod<>current_module) then
               begin
               begin
-                comment(v_error,'Definition '+fullownerhierarchyname(false)+' from module '+tmod.mainsource+' regitered with current module '+current_module.mainsource);
+                comment(v_error,'Definition '+fullownerhierarchyname(false)+' from module '+tmod.mainsource+' registered with current module '+current_module.mainsource);
               end;
               end;
            if not assigned(tmod) then
            if not assigned(tmod) then
              tmod:=current_module;
              tmod:=current_module;

+ 1 - 1
compiler/symsym.pas

@@ -751,7 +751,7 @@ implementation
             tmod:=find_module_from_symtable(owner);
             tmod:=find_module_from_symtable(owner);
             if assigned(tmod) and assigned(current_module) and (tmod<>current_module) then
             if assigned(tmod) and assigned(current_module) and (tmod<>current_module) then
               begin
               begin
-                comment(v_error,'Symbol '+realname+' from module '+tmod.mainsource+' regitered with current module '+current_module.mainsource);
+                comment(v_error,'Symbol '+realname+' from module '+tmod.mainsource+' registered with current module '+current_module.mainsource);
               end;
               end;
 	    if not assigned(tmod) then
 	    if not assigned(tmod) then
               tmod:=current_module;
               tmod:=current_module;

+ 10 - 0
compiler/symtable.pas

@@ -4275,6 +4275,16 @@ implementation
         if result=nil then
         if result=nil then
           result:=search_specific_assignment_operator(_ASSIGNMENT,from_def,to_def);
           result:=search_specific_assignment_operator(_ASSIGNMENT,from_def,to_def);
 
 
+        { if we're assigning to a typed pointer, but we did not find a suitable assignement
+          operator then we also check for a untyped pointer assignment operator }
+        if not assigned(result) and is_pointer(to_def) and not is_voidpointer(to_def) then
+          begin
+            if explicit then
+              result:=search_specific_assignment_operator(_OP_EXPLICIT,from_def,voidpointertype);
+            if not assigned(result) then
+              result:=search_specific_assignment_operator(_ASSIGNMENT,from_def,voidpointertype);
+          end;
+
         { restore symtable stack }
         { restore symtable stack }
         if to_def.typ in [recorddef,objectdef] then
         if to_def.typ in [recorddef,objectdef] then
           symtablestack.pop(tabstractrecorddef(to_def).symtable);
           symtablestack.pop(tabstractrecorddef(to_def).symtable);

+ 2 - 0
compiler/x86/agx86int.pas

@@ -154,6 +154,7 @@ implementation
         '',
         '',
         '',
         '',
         '',
         '',
+        '',
         ''
         ''
       );
       );
 
 
@@ -210,6 +211,7 @@ implementation
         '',
         '',
         '',
         '',
         '',
         '',
+        '',
         ''
         ''
       );
       );
 
 

+ 2 - 1
compiler/x86/agx86nsm.pas

@@ -592,7 +592,8 @@ interface
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           ',gcc_except_table',
           ',gcc_except_table',
-          ',ARM_attributes'
+          ',ARM_attributes',
+          ',note'
         );
         );
       var
       var
         secname,secgroup: string;
         secname,secgroup: string;

+ 2 - 1
compiler/z80/agsdasz80.pas

@@ -273,7 +273,8 @@ unit agsdasz80;
           '_STACK',
           '_STACK',
           '_HEAP',
           '_HEAP',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
       begin
       begin
         if atype=sec_user then
         if atype=sec_user then

+ 2 - 1
compiler/z80/agz80vasm.pas

@@ -289,7 +289,8 @@ unit agz80vasm;
           '.stack',
           '.stack',
           '.heap',
           '.heap',
           '.gcc_except_table',
           '.gcc_except_table',
-          '.ARM.attributes'
+          '.ARM.attributes',
+          '.note'
         );
         );
       var
       var
         sep: string[3];
         sep: string[3];

+ 136 - 6
packages/fcl-jsonschema/src/fpjson.schema.codegen.pp

@@ -20,9 +20,9 @@ interface
 
 
 uses
 uses
   {$IFDEF FPC_DOTTEDUNITS}
   {$IFDEF FPC_DOTTEDUNITS}
-  System.Classes, System.SysUtils, System.DateUtils, Pascal.CodeGenerator,
+  System.Classes, System.SysUtils, System.DateUtils, Pascal.CodeGenerator,  System.Contnrs,
   {$ELSE}
   {$ELSE}
-  Classes, SysUtils, dateutils, pascodegen,
+  Classes, SysUtils, dateutils, pascodegen, contnrs,
   {$ENDIF}
   {$ENDIF}
   fpjson.schema.types,
   fpjson.schema.types,
   fpjson.schema.Pascaltypes;
   fpjson.schema.Pascaltypes;
@@ -58,15 +58,22 @@ Type
   TTypeCodeGenerator = class(TJSONSchemaCodeGenerator)
   TTypeCodeGenerator = class(TJSONSchemaCodeGenerator)
   private
   private
     FTypeParentClass: string;
     FTypeParentClass: string;
+    FGenerated : TFPObjectHashTable;
+    procedure GenerateClassForwardTypes(aData: TSchemaData);
     procedure GenerateClassTypes(aData: TSchemaData);
     procedure GenerateClassTypes(aData: TSchemaData);
+    procedure GenerateIntegerTypes(aData: TSchemaData);
     procedure GeneratePascalArrayTypes(aData: TSchemaData);
     procedure GeneratePascalArrayTypes(aData: TSchemaData);
     procedure GenerateStringTypes(aData: TSchemaData);
     procedure GenerateStringTypes(aData: TSchemaData);
     procedure WriteDtoConstructor(aType: TPascalTypeData); virtual;
     procedure WriteDtoConstructor(aType: TPascalTypeData); virtual;
     procedure WriteDtoField(aType: TPascalTypeData; aProperty: TPascalPropertyData); virtual;
     procedure WriteDtoField(aType: TPascalTypeData; aProperty: TPascalPropertyData); virtual;
     procedure WriteDtoType(aType: TPascalTypeData); virtual;
     procedure WriteDtoType(aType: TPascalTypeData); virtual;
+    procedure WriteDtoForwardType(aType: TPascalTypeData); virtual;
     procedure WriteDtoArrayType(aType: TPascalTypeData); virtual;
     procedure WriteDtoArrayType(aType: TPascalTypeData); virtual;
+    procedure WriteDtoArrayRefType(aType: TPascalTypeData); virtual;
     procedure WriteStringArrayType(aType: TPascalTypeData);
     procedure WriteStringArrayType(aType: TPascalTypeData);
+    procedure WriteIntegerArrayType(aType: TPascalTypeData);
     procedure WriteStringType(aType: TPascalTypeData); virtual;
     procedure WriteStringType(aType: TPascalTypeData); virtual;
+    procedure WriteIntegerType(aType: TPascalTypeData); virtual;
   public
   public
     constructor Create(AOwner: TComponent); override;
     constructor Create(AOwner: TComponent); override;
     procedure Execute(aData: TSchemaData);
     procedure Execute(aData: TSchemaData);
@@ -275,6 +282,7 @@ var
   I: integer;
   I: integer;
 
 
 begin
 begin
+  fGenerated.Add(aType.PascalName,aType);
   if WriteClassType then
   if WriteClassType then
     Addln('%s = Class(%s)', [aType.PascalName, TypeParentClass])
     Addln('%s = Class(%s)', [aType.PascalName, TypeParentClass])
   else
   else
@@ -289,17 +297,38 @@ begin
   Addln('');
   Addln('');
 end;
 end;
 
 
+procedure TTypeCodeGenerator.WriteDtoForwardType(aType: TPascalTypeData);
+begin
+  Addln('%s = class;',[aType.PascalName]);
+end;
+
 procedure TTypeCodeGenerator.WriteDtoArrayType(aType: TPascalTypeData);
 procedure TTypeCodeGenerator.WriteDtoArrayType(aType: TPascalTypeData);
 
 
 var
 var
   Fmt : String;
   Fmt : String;
 
 
+begin
+  if FGenerated.Items[aType.PascalName]<>Nil then
+    exit;
+  FGenerated.Add(aType.PascalName,aType);
+  if DelphiCode then
+    Fmt:='%s = TArray<%s>;'
+  else
+    Fmt:='%s = Array of %s;';
+  Addln(Fmt,[aType.PascalName,aType.ElementTypeData.PascalName]);
+end;
+
+procedure TTypeCodeGenerator.WriteDtoArrayRefType(aType: TPascalTypeData);
+var
+  Fmt : String;
+  lName : string;
 begin
 begin
   if DelphiCode then
   if DelphiCode then
     Fmt:='%s = TArray<%s>;'
     Fmt:='%s = TArray<%s>;'
   else
   else
     Fmt:='%s = Array of %s;';
     Fmt:='%s = Array of %s;';
   Addln(Fmt,[aType.PascalName,aType.ElementTypeData.PascalName]);
   Addln(Fmt,[aType.PascalName,aType.ElementTypeData.PascalName]);
+
 end;
 end;
 
 
 procedure TTypeCodeGenerator.WriteStringArrayType(aType: TPascalTypeData);
 procedure TTypeCodeGenerator.WriteStringArrayType(aType: TPascalTypeData);
@@ -308,12 +337,53 @@ begin
   WriteDtoArrayType(aType);
   WriteDtoArrayType(aType);
 end;
 end;
 
 
+procedure TTypeCodeGenerator.WriteIntegerArrayType(aType: TPascalTypeData);
+begin
+  WriteDtoArrayType(aType);
+end;
+
 procedure TTypeCodeGenerator.WriteStringType(aType: TPascalTypeData);
 procedure TTypeCodeGenerator.WriteStringType(aType: TPascalTypeData);
 
 
 begin
 begin
+  FGenerated.Add(aType.PascalName,aType);
   Addln('%s = string;',[aType.PascalName]);
   Addln('%s = string;',[aType.PascalName]);
 end;
 end;
 
 
+procedure TTypeCodeGenerator.WriteIntegerType(aType: TPascalTypeData);
+var
+  I,lEl,lMin,lMax : Integer;
+  lName: string;
+begin
+  lMin:=0;
+  lMax:=0;
+  FGenerated.Add(aType.PascalName,aType);
+  if aType.Schema.Validations.HasKeywordData(jskEnum) and
+     (aType.Schema.Validations.Enum.Count>0) then
+    begin
+    lMin:=aType.Schema.Validations.Enum.Items[0].AsInteger;
+    lMax:=aType.Schema.Validations.Enum.Items[0].AsInteger;
+    for I:=1 to aType.Schema.Validations.Enum.Count-1 do
+      begin
+      lEl:=aType.Schema.Validations.Enum.Items[i].AsInteger;
+      if lEl<lMin then
+        lMin:=lEl;
+      if lEl>lMax then
+        lMax:=lEl;
+      end;
+    if (lMax-lMin+1)<>aType.Schema.Validations.Enum.Count then
+      begin
+      lMin:=0;
+      lMax:=0;
+      end;
+    end;
+  lName:=aType.PascalName;
+  if lMin<>lMax then
+    Addln('%s = %d..%d;',[lName,lMin,lMax])
+  else
+    Addln('%s = Integer;',[lName]);
+
+end;
+
 
 
 constructor TTypeCodeGenerator.Create(AOwner: TComponent);
 constructor TTypeCodeGenerator.Create(AOwner: TComponent);
 begin
 begin
@@ -348,6 +418,49 @@ begin
     AddLn('');
     AddLn('');
 end;
 end;
 
 
+procedure TTypeCodeGenerator.GenerateIntegerTypes(aData : TSchemaData);
+
+var
+  I,lCount: integer;
+  lType,lArray : TPascalTypeData;
+begin
+  lCount:=0;
+  for I := 0 to aData.TypeCount-1 do
+    begin
+    lType:=aData.Types[I];
+    if (lType.PascalType=ptInteger) then
+      begin
+      DoLog('Generating integer type %s', [lType.PascalName]);
+      WriteIntegerType(lType);
+      inc(lCount);
+      lArray:=aData.FindSchemaTypeData('['+lType.SchemaName+']');
+      if lArray<>Nil then
+        begin
+        WriteIntegerArrayType(lArray);
+        inc(lCount);
+        end;
+      end;
+    end;
+  if lCount>0 then
+    AddLn('');
+end;
+
+procedure TTypeCodeGenerator.GenerateClassForwardTypes(aData: TSchemaData);
+var
+  I: integer;
+  lArray : TPascalTypeData;
+  lName : string;
+begin
+  for I := 0 to aData.TypeCount-1 do
+    if aData.Types[I].PascalType in [ptSchemaStruct,ptAnonStruct] then
+      begin
+        DoLog('Generating DTO class forward type %s', [aData.Types[I].PascalName]);
+        lName:=aData.Types[I].PascalName;
+        WriteDtoForwardType(aData.Types[I]);
+      end
+
+end;
+
 procedure TTypeCodeGenerator.GenerateClassTypes(aData : TSchemaData);
 procedure TTypeCodeGenerator.GenerateClassTypes(aData : TSchemaData);
 
 
 var
 var
@@ -374,6 +487,7 @@ procedure TTypeCodeGenerator.GeneratePascalArrayTypes(aData : TSchemaData);
 var
 var
   I, lCount: integer;
   I, lCount: integer;
   lType : TPascalTypeData;
   lType : TPascalTypeData;
+  lName : string;
 
 
 begin
 begin
   lCount := 0;
   lCount := 0;
@@ -383,13 +497,12 @@ begin
     // It is an array
     // It is an array
     if (lType.PascalType=ptArray) then
     if (lType.PascalType=ptArray) then
       begin
       begin
-      // the element type is a standard type
-      if (lType.ElementTypeData.Schema=Nil) then
+      if (lType.ElementTypeData.PascalName<>'') then
         begin
         begin
         DoLog('Generating array type %s', [lType.PascalName]);
         DoLog('Generating array type %s', [lType.PascalName]);
         WriteDtoArrayType(lType);
         WriteDtoArrayType(lType);
         inc(lCount);
         inc(lCount);
-        end;
+        end
       end;
       end;
     end;
     end;
   if lCount>0 then
   if lCount>0 then
@@ -400,9 +513,11 @@ procedure TTypeCodeGenerator.Execute(aData: TSchemaData);
 
 
 var
 var
   I: integer;
   I: integer;
+  False: Boolean;
 
 
 begin
 begin
   FData := aData;
   FData := aData;
+  FGenerated:=TFPObjectHashTable.Create(False);
   GenerateHeader;
   GenerateHeader;
   try
   try
     Addln('unit %s;', [OutputUnitName]);
     Addln('unit %s;', [OutputUnitName]);
@@ -419,6 +534,9 @@ begin
     EnsureSection(csType);
     EnsureSection(csType);
     Addln('');
     Addln('');
     indent;
     indent;
+    if WriteClassType then
+      GenerateClassForwardTypes(aData);
+    GenerateIntegerTypes(aData);
     GenerateStringTypes(aData);
     GenerateStringTypes(aData);
     GeneratePascalArrayTypes(aData);
     GeneratePascalArrayTypes(aData);
     GenerateClassTypes(aData);
     GenerateClassTypes(aData);
@@ -951,6 +1069,8 @@ begin
 end;
 end;
 
 
 procedure TSerializerCodeGenerator.WriteArrayHelperSerializeArray(aType: TPascalTypeData);
 procedure TSerializerCodeGenerator.WriteArrayHelperSerializeArray(aType: TPascalTypeData);
+var
+  lSerializeCall : String;
 begin
 begin
   Addln('');
   Addln('');
   Addln('function %s.SerializeArray : TJSONArray;',[aType.SerializerName]);
   Addln('function %s.SerializeArray : TJSONArray;',[aType.SerializerName]);
@@ -965,7 +1085,15 @@ begin
   indent;
   indent;
   Addln('For I:=0 to length(Self)-1 do');
   Addln('For I:=0 to length(Self)-1 do');
   Indent;
   Indent;
-  Addln('Result.Add(self[i]);');
+  if aType.ElementTypeData.Pascaltype in [ptSchemaStruct,ptAnonStruct] then
+    lSerializeCall:='.SerializeObject'
+  else  if aType.ElementTypeData.Pascaltype=ptArray then
+    lSerializeCall:='.SerializeArray'
+  else if aType.ElementTypeData.schema=Nil then
+    lSerializeCall:=''
+  else
+    Raise EJSONSchema.CreateFmt('Cannot decide how to serialize %',[aType.ElementTypeData.PascalName]);
+  Addln('Result.Add(self[i]%s);',[lSerializeCall]);
   undent;
   undent;
   undent;
   undent;
   Addln('except');
   Addln('except');
@@ -1150,6 +1278,7 @@ begin
               begin
               begin
               WriteArrayHelper(ElementTypeData);
               WriteArrayHelper(ElementTypeData);
               end;
               end;
+            WriteArrayHelper(lType);
             end;
             end;
     end;
     end;
     undent;
     undent;
@@ -1186,6 +1315,7 @@ begin
             begin
             begin
             WriteArrayHelperImpl(lType.ElementTypeData);
             WriteArrayHelperImpl(lType.ElementTypeData);
             end;
             end;
+          WriteArrayHelperImpl(lType);
           end;
           end;
       end;
       end;
     end;
     end;

+ 16 - 3
packages/fcl-jsonschema/src/fpjson.schema.pascaltypes.pp

@@ -63,8 +63,6 @@ Type
   TPropertyType = TPascalType;
   TPropertyType = TPascalType;
   TPropertyTypes = TPascalTypes;
   TPropertyTypes = TPascalTypes;
 
 
-  { TPascalProperty }
-
   { TPascalPropertyData }
   { TPascalPropertyData }
 
 
   TPascalPropertyData = class(TObject)
   TPascalPropertyData = class(TObject)
@@ -674,12 +672,27 @@ procedure TSchemaData.CheckDependencies;
 var
 var
   I : Integer;
   I : Integer;
   lData : TPascalTypeData;
   lData : TPascalTypeData;
+  lName : string;
 
 
 begin
 begin
   For I:=0 to TypeCount-1 do
   For I:=0 to TypeCount-1 do
     begin
     begin
     lData:=Types[I];
     lData:=Types[I];
-    CheckProps(lData,lData);
+    Case lData.Pascaltype of
+      ptAnonStruct,
+      ptSchemaStruct:
+        CheckProps(lData,lData) ;
+      ptArray:
+        begin
+        // Resolve element type ref
+        if (lData.Schema.Items.Count=1) then
+          begin
+          lName:=lData.Schema.Items[0].Ref;
+          if lName<>'' then
+            lData.ElementTypeData:=GetPascalTypeDataFromRef(lName);
+          end;
+        end;
+    end;
     end;
     end;
 end;
 end;
 
 

+ 8 - 8
packages/fcl-openapi/src/fpopenapi.generators.pp

@@ -23,7 +23,7 @@ uses
   {$IFDEF FPC_DOTTEDUNITS}
   {$IFDEF FPC_DOTTEDUNITS}
   System.Classes, System.SysUtils, System.DateUtils, System.Contnrs, Pascal.CodeGenerator,
   System.Classes, System.SysUtils, System.DateUtils, System.Contnrs, Pascal.CodeGenerator,
   {$ELSE}
   {$ELSE}
-  Classes, SysUtils, strutils, dateutils,  pascodegen, inifiles,
+  Classes, SysUtils, strutils, dateutils,  pascodegen,
   {$ENDIF}
   {$ENDIF}
   fpjson.schema.types,
   fpjson.schema.types,
   fpjson.schema.Pascaltypes,
   fpjson.schema.Pascaltypes,
@@ -411,7 +411,7 @@ begin
     lBodyType:=aMethod.RequestBodyDataType.GetTypeName(ntPascal);
     lBodyType:=aMethod.RequestBodyDataType.GetTypeName(ntPascal);
   if lBodyType<>'' then
   if lBodyType<>'' then
     AddTo(lParams, 'aRequest : '+lBodyType);
     AddTo(lParams, 'aRequest : '+lBodyType);
-  if aMethod.ResultDataType.BinaryData then
+  if Assigned(aMethod.ResultDataType) and aMethod.ResultDataType.BinaryData then
     AddTo(lParams, 'aResponseStream : TStream');
     AddTo(lParams, 'aResponseStream : TStream');
   if AsyncService then
   if AsyncService then
     AddTo(lParams, 'aCallback : '+MethodResultCallbackName(aMethod));
     AddTo(lParams, 'aCallback : '+MethodResultCallbackName(aMethod));
@@ -805,10 +805,10 @@ begin
     lBodyArg:='aRequest.Serialize'
     lBodyArg:='aRequest.Serialize'
   else
   else
     lBodyArg:='aRequest';
     lBodyArg:='aRequest';
-  if aMethod.ResultDataType.BinaryData then
-    Addln('lResponse:=ExecuteRequest(''%s'',lURL,%s,aResponseStream);', [lHTTPMethod, lBodyArg])
-  else
-    Addln('lResponse:=ExecuteRequest(''%s'',lURL,%s);', [lHTTPMethod, lBodyArg]);
+  if Assigned(aMethod.ResultDataType) and aMethod.ResultDataType.BinaryData then
+      Addln('lResponse:=ExecuteRequest(''%s'',lURL,%s,aResponseStream);', [lHTTPMethod, lBodyArg])
+    else
+      Addln('lResponse:=ExecuteRequest(''%s'',lURL,%s);', [lHTTPMethod, lBodyArg]);
   AddLn('Result:=%s.Create(lResponse);', [GetMethodResultType(aMethod)]);
   AddLn('Result:=%s.Create(lResponse);', [GetMethodResultType(aMethod)]);
   lResultType:=aMethod.ResultDataType;
   lResultType:=aMethod.ResultDataType;
   if (aMethod.ResultDataType=nil) then
   if (aMethod.ResultDataType=nil) then
@@ -909,9 +909,9 @@ begin
   Addln('uses');
   Addln('uses');
   indent;
   indent;
   if DelphiCode then
   if DelphiCode then
-    Addln('System.SysUtils')
+    Addln('System.SysUtils, System.DateUtils')
   else
   else
-    Addln('SysUtils');
+    Addln('SysUtils, DateUtils');
   Addln(', %s;', [SerializerUnit]);
   Addln(', %s;', [SerializerUnit]);
   undent;
   undent;
   Addln('');
   Addln('');

+ 63 - 24
packages/fcl-openapi/src/fpopenapi.pascaltypes.pp

@@ -408,12 +408,14 @@ var
   lType : TSchemaSimpleType;
   lType : TSchemaSimpleType;
 
 
 begin
 begin
-  lType:=TAPITypeData.ExtractFirstType(FParameter.Schema);
-  case lType of
-    sstInteger : Result:=Format('IntToStr(%s)',[Name]); // Also handles int64
-    sstString :  Result:=Name;
-    sstNumber : Result:=Format('FloatToStr(%s,cRestFormatSettings)',[Name]);
-    sstBoolean : Result:=Format('cRESTBooleans[%s]',[Name]);
+  Case FArgType of
+    ptInteger,
+    ptInt64: Result:=Format('IntToStr(%s)',[Name]); // Also handles int64
+    ptString : Result:=Name;
+    ptDateTime : Result:=Format('DateToISO8601(%s)',[Name]);
+    ptFloat32,
+    ptFloat64 : Result:=Format('FloatToStr(%s,cRestFormatSettings)',[Name]);
+    ptBoolean : Result:=Format('cRESTBooleans[%s]',[Name]);
   else
   else
     Result:=Name;
     Result:=Name;
   end;
   end;
@@ -833,8 +835,10 @@ begin
       if NeedsDeserialize(lData) then
       if NeedsDeserialize(lData) then
         Include(lSerTypes,stDeSerialize);
         Include(lSerTypes,stDeSerialize);
       end;
       end;
-    lData.SerializeTypes:=lSerTypes;
+    lData.SerializeTypes:=lData.SerializeTypes+lSerTypes;
     DoLog(etInfo,'%s needs serialize: %s, deserialize: %s',[lData.SchemaName,BoolToStr(stSerialize in lSerTypes,True),BoolToStr(stDeSerialize in lSerTypes,True)]);
     DoLog(etInfo,'%s needs serialize: %s, deserialize: %s',[lData.SchemaName,BoolToStr(stSerialize in lSerTypes,True),BoolToStr(stDeSerialize in lSerTypes,True)]);
+    if (lData.Pascaltype=ptArray) and Assigned(lData.ElementTypeData) then
+      lData.ElementTypeData.SerializeTypes:=lData.ElementTypeData.SerializeTypes+lSerTypes;
     end;
     end;
 end;
 end;
 
 
@@ -865,21 +869,55 @@ begin
     lName:=FAPI.Components.Schemas.Names[I];
     lName:=FAPI.Components.Schemas.Names[I];
     lSchema:=FAPI.Components.Schemas.Schemas[lName];
     lSchema:=FAPI.Components.Schemas.Schemas[lName];
     lType:=lSchema.Validations.GetFirstType;
     lType:=lSchema.Validations.GetFirstType;
-    if (lType in [sstObject,sstString]) then
+    if (lType in [sstArray,sstObject,sstInteger,sstString]) then
       begin
       begin
       lTypeName:=EscapeKeyWord(ObjectTypePrefix+Sanitize(lName)+ObjectTypeSuffix);
       lTypeName:=EscapeKeyWord(ObjectTypePrefix+Sanitize(lName)+ObjectTypeSuffix);
       case lType of
       case lType of
-        sstObject : lData:=CreatePascalType(I,ptSchemaStruct,lName,lTypeName,lSchema);
+        sstObject :
+          lData:=CreatePascalType(I,ptSchemaStruct,lName,lTypeName,lSchema);
         sstString :
         sstString :
           begin
           begin
           lData:=CreatePascalType(I,ptString,lName,lTypeName,lSchema);
           lData:=CreatePascalType(I,ptString,lName,lTypeName,lSchema);
           end;
           end;
+        sstInteger:
+          lData:=CreatePascalType(I,ptInteger,lName,lTypeName,lSchema);
+        sstArray:
+          lData:=CreatePascalType(I,ptArray,lName,lTypeName,lSchema);
       end;
       end;
       ConfigType(lData);
       ConfigType(lData);
       AddType(lName,lData);
       AddType(lName,lData);
       AddToTypeMap(lName,lData);
       AddToTypeMap(lName,lData);
       end;
       end;
     end;
     end;
+  For I:=0 to FAPI.Components.Parameters.Count-1 Do
+    begin
+    lName:=FAPI.Components.Parameters.Names[I];
+    if FAPI.Components.Parameters.ParameterOrReferences[lName].HasReference then
+      Continue;
+    lSchema:=FAPI.Components.Parameters.ParameterOrReferences[lName].Schema;
+    if assigned(lSchema) then
+    lType:=lSchema.Validations.GetFirstType;
+    if (lType in [sstArray,sstObject,sstInteger,sstString]) then
+      begin
+      lTypeName:=EscapeKeyWord(ObjectTypePrefix+Sanitize(lName)+ObjectTypeSuffix);
+      case lType of
+        sstObject :
+          lData:=CreatePascalType(I,ptSchemaStruct,lName,lTypeName,lSchema);
+        sstString :
+          begin
+          lData:=CreatePascalType(I,ptString,lName,lTypeName,lSchema);
+          end;
+        sstInteger:
+          lData:=CreatePascalType(I,ptInteger,lName,lTypeName,lSchema);
+        sstArray:
+          lData:=CreatePascalType(I,ptArray,lName,lTypeName,lSchema);
+      end;
+      ConfigType(lData);
+      AddType(lName,lData);
+      AddToTypeMap(lName,lData);
+      end;
+    end;
+
   // We do this here, so all API type references can be resolved
   // We do this here, so all API type references can be resolved
   For I:=0 to APITypeCount-1 do
   For I:=0 to APITypeCount-1 do
     AddProperties(APITypes[i]);
     AddProperties(APITypes[i]);
@@ -1070,28 +1108,29 @@ var
   S : String;
   S : String;
 
 
 begin
 begin
+  Result:=Nil;
   if AMethod.Operation.Responses.Count>0 then
   if AMethod.Operation.Responses.Count>0 then
     begin
     begin
     lResponse:=AMethod.Operation.Responses.ResponseByindex[0];
     lResponse:=AMethod.Operation.Responses.ResponseByindex[0];
-    lMedia:=lResponse.Content.MediaTypes['application/json'];
-    if lMedia=Nil then
+    if lResponse.Content.Count<>0 then
       begin
       begin
-      // Check if we must stream
-      For S in StreamContentTypes do
+      lMedia:=lResponse.Content.MediaTypes['application/json'];
+      if lMedia=Nil then
         begin
         begin
-        lMedia:=lResponse.Content.MediaTypes[S];
-        if lMedia<>nil then
-          break;
+        // Check if we must stream
+        For S in StreamContentTypes do
+          begin
+          lMedia:=lResponse.Content.MediaTypes[S];
+          if lMedia<>nil then
+            break;
+          end;
+        if lMedia=nil then
+          Raise EGenAPI.CreateFmt('No application/json response media type for %s.%s',[aMethod.Service.ServiceName,aMethod.MethodName]);
+        Result:=GetStreamTypeData(S);
         end;
         end;
-      if lMedia=nil then
-        Raise EGenAPI.CreateFmt('No application/json response media type for %s.%s',[aMethod.Service.ServiceName,aMethod.MethodName]);
-      Result:=GetStreamTypeData(S);
-      end
-    else
       Result:=GetSchemaTypeData(Nil,lMedia.Schema,True) as TAPITypeData;
       Result:=GetSchemaTypeData(Nil,lMedia.Schema,True) as TAPITypeData;
-    end
-  else
-    Result:=Nil; // FindApiType('boolean');
+      end;
+    end;
 end;
 end;
 
 
 function TAPIData.GetMethodResultType(aMethod : TAPIServiceMethod; aNameType : TNameType) : String;
 function TAPIData.GetMethodResultType(aMethod : TAPIServiceMethod; aNameType : TNameType) : String;

+ 2 - 2
packages/rtl-console/src/unix/keyboard.pp

@@ -2273,7 +2273,7 @@ var
 
 
     procedure DecodeAndPushWin32Key(const store: array of AnsiChar; arrayind: byte);
     procedure DecodeAndPushWin32Key(const store: array of AnsiChar; arrayind: byte);
 
 
-      function VKToScanCode(vk: Word): Byte;
+      function VKToScanCode(vk: Word): Word;
       begin
       begin
         case vk of
         case vk of
           // Standard keys
           // Standard keys
@@ -2328,7 +2328,7 @@ var
       i, p_idx, code: Integer;
       i, p_idx, code: Integer;
       st: string;
       st: string;
       ch: AnsiChar;
       ch: AnsiChar;
-      ScanCode: Byte;
+      ScanCode: Word;
       k: TEnhancedKeyEvent;
       k: TEnhancedKeyEvent;
     begin
     begin
       // 1. Parse the parameters: Vk;Sc;Uc;Kd;Cs;Rc
       // 1. Parse the parameters: Vk;Sc;Uc;Kd;Cs;Rc

+ 1 - 1
rtl/inc/exeinfo.pp

@@ -1013,7 +1013,7 @@ begin
           end;
           end;
       end;
       end;
 
 
-    if ((found_addr=ptruint(-1)) or (found_addr < ptruint(phdr))) and (ptruint(phdr)<ptruint(addr)) then
+    if (found_addr=ptruint(-1)) or ((found_addr < ptruint(phdr)) and (ptruint(phdr)<ptruint(addr))) then
       found_addr:=ptruint(phdr);
       found_addr:=ptruint(phdr);
     { Set pagesize to a default small value }
     { Set pagesize to a default small value }
     if (pagesize=ptruint(-1)) then
     if (pagesize=ptruint(-1)) then

+ 1 - 1
rtl/morphos/si_prc.pp

@@ -41,7 +41,7 @@ procedure PascalMainEntry; cdecl; forward;
   all .text.* section, so if we link any object with an unnamed .text
   all .text.* section, so if we link any object with an unnamed .text
   section, this won't be at the start of the executable, and we get
   section, this won't be at the start of the executable, and we get
   crashes. (KB) }
   crashes. (KB) }
-function _FPC_proc_start: longint; cdecl; public name '_start'; section '.text';
+function _FPC_proc_start: longint; cdecl; public name '_start'; {$IFNDEF VER3_2}section '.text';{$ENDIF}
 var
 var
   sst: TStackSwapStruct;
   sst: TStackSwapStruct;
   newStack: Pointer;
   newStack: Pointer;

+ 22 - 0
tests/tbs/tb0162.pp

@@ -79,6 +79,28 @@ begin
       doerror(8);
       doerror(8);
   end;
   end;
 
 
+  l := low(longint);
+  try
+    l := l div -1;
+    doerror(9);
+  except
+    on eintoverflow do
+      ;
+    else
+      doerror(10);
+  end;
+
+  l := low(longint);
+  try
+    l := -l;
+    doerror(109);
+  except
+    on eintoverflow do
+      ;
+    else
+      doerror(110);
+  end;
+
   c := high(cardinal);
   c := high(cardinal);
   try
   try
     c := c+1;
     c := c+1;

+ 17 - 0
tests/tbs/tb0723.pp

@@ -0,0 +1,17 @@
+{ %NORUN }
+{ %OPT=-Sew }
+
+{$warn 2041 off}
+program tb0723;
+
+
+{$YD}
+{$Y-}
+{$Y+}
+{$REFERENCEINFO ON}
+{$REFERENCEINFO OFF}
+{$DEFINITIONINFO ON}
+{$DEFINITIONINFO OFF}
+
+begin
+end.

+ 23 - 0
tests/tbs/tb0724.pp

@@ -0,0 +1,23 @@
+unit tb0724;
+
+{$mode delphi}{$H+}
+
+interface
+
+type
+  ITest<T> = interface
+  end;
+
+implementation
+
+uses
+  { when the compiler reaches ucycleb then depending on the order either ub0724b
+    or ub0724c will have neither its global- nor localsymtable set when the
+    compiler specializes ITest<>, because the compiler didn't yet reach the
+    point to compile either ucyclec or ucycled }
+  ub0724b,
+  ub0724a,
+  ub0724c;
+
+end.
+

+ 17 - 0
tests/tbs/ub0724a.pp

@@ -0,0 +1,17 @@
+unit ub0724a;
+
+{$mode delphi}{$H+}
+
+interface
+
+uses
+  tb0724;
+
+type
+  TTest = class(TInterfacedObject, ITest<TObject>)
+  end;
+
+implementation
+
+end.
+

+ 10 - 0
tests/tbs/ub0724b.pp

@@ -0,0 +1,10 @@
+unit ub0724b;
+
+{$mode objfpc}{$H+}
+
+interface
+
+implementation
+
+end.
+

+ 10 - 0
tests/tbs/ub0724c.pp

@@ -0,0 +1,10 @@
+unit ub0724c;
+
+{$mode objfpc}{$H+}
+
+interface
+
+implementation
+
+end.
+

+ 28 - 0
tests/test/tgeneric128.pp

@@ -0,0 +1,28 @@
+{ %NORUN }
+
+program tgeneric128;
+
+{$mode delphi}
+
+type
+  Foo<T> = record
+  public
+    class operator Equal(const left: Foo<T>; const right: T): Boolean;
+  end;
+
+  Bar<T> = record
+  public
+    class operator Implicit(const value: Bar<T>): Foo<T>;
+  end;
+
+class operator Foo<T>.Equal(const left: Foo<T>; const right: T): Boolean;
+begin
+end;
+
+class operator Bar<T>.Implicit(const value: Bar<T>): Foo<T>;
+begin
+end;
+
+begin
+
+end.

+ 18 - 0
tests/test/tgeneric129.pp

@@ -0,0 +1,18 @@
+{ %NORUN }
+
+program tgeneric129;
+
+{$mode delphi}
+
+type
+  Vector<T> = record
+  public
+    class operator Add(const left: TArray<T>; const right: Vector<T>): Vector<T>; inline;
+  end;
+
+class operator Vector<T>.Add(const left: TArray<T>; const right: Vector<T>): Vector<T>;
+begin
+end;
+
+begin
+end.

+ 22 - 0
tests/test/toperator97.pp

@@ -0,0 +1,22 @@
+{ %NORUN }
+
+program toperator97;
+
+{$mode objfpc}
+{$modeswitch advancedrecords}
+
+type
+  TTest = record
+    class operator :=(aArg: TTest): Pointer;
+  end;
+
+class operator TTest.:=(aArg: TTest): Pointer;
+begin
+end;
+
+var
+  b: PByte;
+  t: TTest;
+begin
+  b := t;
+end.

+ 57 - 0
tests/test/tpointermath4.pp

@@ -0,0 +1,57 @@
+{ %NORUN }
+
+program tpointermath4;
+
+{$mode delphi}
+
+type
+{$POINTERMATH ON}
+  PMyCardinal = ^Cardinal;
+  PMyByte = ^Byte;
+  PMyString = ^String;
+{$POINTERMATH OFF}
+
+procedure Test;
+var
+  pc: PMyCardinal;
+  pb: PMyByte;
+  ps: PMyString;
+  b: Boolean;
+begin
+  b := pc > pb;
+  b := pc < pb;
+  b := ps < pb;
+  b := ps > pb;
+  b := pc < ps;
+  b := pc > ps;
+
+  b := pc >= pb;
+  b := pc <= pb;
+  b := ps <= pb;
+  b := ps >= pb;
+  b := pc <= ps;
+  b := pc >= ps;
+end;
+
+{$pointermath on}
+
+var
+  pc: PCardinal = Nil;
+  pb: PByte = Nil;
+  ps: PString = Nil;
+  b: Boolean;
+begin
+  b := pc > pb;
+  b := pc < pb;
+  b := ps < pb;
+  b := ps > pb;
+  b := pc < ps;
+  b := pc > ps;
+
+  b := pc >= pb;
+  b := pc <= pb;
+  b := ps <= pb;
+  b := ps >= pb;
+  b := pc <= ps;
+  b := pc >= ps;
+end.

+ 27 - 0
tests/test/tpointermath5.pp

@@ -0,0 +1,27 @@
+{ %FAIL }
+
+program tpointermath5;
+
+{$mode delphi}
+
+{ both pointer types need to have POINTERMATH enabled for comparisons to be
+  supported between them }
+
+type
+  PMyCardinal = ^Cardinal;
+{$POINTERMATH ON}
+  PMyByte = ^Byte;
+{$POINTERMATH OFF}
+
+procedure Test;
+var
+  pc: PMyCardinal;
+  pb: PMyByte;
+  b: Boolean;
+begin
+  b := pc > pb;
+  b := pc < pb;
+end;
+
+begin
+end.

+ 15 - 0
tests/test/tpointermath6.pp

@@ -0,0 +1,15 @@
+{ %FAIL }
+
+program tpointermath6;
+
+{$mode objfpc}
+{$pointermath on}
+
+var
+  pc: PCardinal;
+  pb: PByte;
+  b: Boolean;
+begin
+  b := pc < pb;
+end.
+

+ 68 - 0
tests/webtbs/tw39917.pp

@@ -0,0 +1,68 @@
+{ %NORUN }
+{ %OPT=-O3 }
+
+program tw39917;
+
+{$mode objfpc}
+{$modeswitch anonymousfunctions}
+{$modeswitch functionreferences}
+{$optimization on}
+
+{ Test optimization.  The self param passed to DlgAsync() and Checkout() several
+  anon functions deep in TView.CopyFile cause compiler fatal internal error
+  200409241.  
+
+  If optimization is off there is no error.  If CopyFile is not an object method
+  then there is no problem (though values passed to DlgASync) and CheckOut must
+  be changed.  If DlgASync() and CheckOut() receive a value other than self there
+  is no problem.
+}
+
+type
+  TProc = reference to procedure;
+  TModalDoneProc = reference to procedure(ASuccess: Boolean);
+  TView = class(TObject)
+    procedure CopyFile;
+  end;
+
+procedure DlgAsync(AOwner: TObject; const AOnModalDone: TModalDoneProc);
+begin
+end;
+
+function Checkout(AOwner: TObject): Boolean;
+begin
+Result := True;
+end;
+
+procedure TView.CopyFile;
+
+  procedure Prompt(const AOnModalDone: TProc);
+  begin
+  end;
+
+begin
+Prompt(
+  procedure
+
+    procedure Prompt(const AOnModalDone: TProc);
+    begin
+    if True then
+      DlgAsync(Self,
+        procedure(ASuccess: Boolean)
+        begin
+        if ASuccess and CheckOut(Self) then
+          AOnModalDone()
+        end)
+    end;
+
+  begin
+  Prompt(
+    procedure
+    begin
+    end)
+  end)
+end;
+
+begin
+end.
+

+ 9 - 0
tests/webtbs/tw41458.pp

@@ -0,0 +1,9 @@
+{ %NORUN }
+
+program tw41458;
+
+uses uw41458;
+
+begin
+end.
+

+ 35 - 0
tests/webtbs/uw41458.pp

@@ -0,0 +1,35 @@
+unit uw41458;
+{$ifdef FPC}{$mode delphi}{$endif}
+
+interface
+
+type
+  TUtils = record
+    class procedure GenericMethod<T>; static;
+  end;
+  TMyObj = record
+    FAnsiString: AnsiString;
+    procedure method;
+  end;
+
+var
+  GlobObj: TMyObj;
+
+implementation
+
+class procedure TUtils.GenericMethod<T>;
+begin
+end;
+
+procedure impl_proc(a: Double; b: String);
+begin
+  TUtils.GenericMethod<byte>;
+end;
+
+procedure TMyObj.method;
+begin
+  impl_proc(1.2, '-');
+end;
+
+end.
+