mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 09:32:00 +01:00 
			
		
		
		
	* several small bugs in the handling of implements fixed, resolves #14418
git-svn-id: trunk@13615 -
This commit is contained in:
		
							parent
							
								
									a8c6d9ec3a
								
							
						
					
					
						commit
						e8dff46f8e
					
				
							
								
								
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @ -9223,6 +9223,7 @@ tests/webtbs/tw14307.pp svneol=native#text/plain | |||||||
| tests/webtbs/tw1433.pp svneol=native#text/plain | tests/webtbs/tw1433.pp svneol=native#text/plain | ||||||
| tests/webtbs/tw14363.pp svneol=native#text/plain | tests/webtbs/tw14363.pp svneol=native#text/plain | ||||||
| tests/webtbs/tw14403.pp svneol=native#text/plain | tests/webtbs/tw14403.pp svneol=native#text/plain | ||||||
|  | tests/webtbs/tw14418.pp svneol=native#text/plain | ||||||
| tests/webtbs/tw1445.pp svneol=native#text/plain | tests/webtbs/tw1445.pp svneol=native#text/plain | ||||||
| tests/webtbs/tw1450.pp svneol=native#text/plain | tests/webtbs/tw1450.pp svneol=native#text/plain | ||||||
| tests/webtbs/tw1451.pp svneol=native#text/plain | tests/webtbs/tw1451.pp svneol=native#text/plain | ||||||
|  | |||||||
| @ -518,8 +518,8 @@ implementation | |||||||
|         for i:=0 to _class.ImplementedInterfaces.count-1 do |         for i:=0 to _class.ImplementedInterfaces.count-1 do | ||||||
|           begin |           begin | ||||||
|             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); |             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|             { if it implements itself } |             { if it implements itself and if it's not implemented by delegation } | ||||||
|             if ImplIntf.VtblImplIntf=ImplIntf then |             if (ImplIntf.VtblImplIntf=ImplIntf) and (ImplIntf.IType=etStandard) then | ||||||
|               begin |               begin | ||||||
|                 { allocate a pointer in the object memory } |                 { allocate a pointer in the object memory } | ||||||
|                 with tObjectSymtable(_class.symtable) do |                 with tObjectSymtable(_class.symtable) do | ||||||
| @ -536,7 +536,7 @@ implementation | |||||||
|           begin |           begin | ||||||
|             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); |             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]); | ||||||
|             if ImplIntf.VtblImplIntf<>ImplIntf then |             if ImplIntf.VtblImplIntf<>ImplIntf then | ||||||
|               ImplIntf.Ioffset:=ImplIntf.VtblImplIntf.Ioffset; |               ImplIntf.IOffset:=ImplIntf.VtblImplIntf.IOffset; | ||||||
|           end; |           end; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| @ -1106,9 +1106,9 @@ implementation | |||||||
|         current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0)); |         current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0)); | ||||||
|         { IOffset field } |         { IOffset field } | ||||||
|         case AImplIntf.VtblImplIntf.IType of |         case AImplIntf.VtblImplIntf.IType of | ||||||
|  |           etFieldValue, | ||||||
|           etStandard: |           etStandard: | ||||||
|             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset)); |             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset)); | ||||||
|           etFieldValue, |  | ||||||
|           etVirtualMethodResult, |           etVirtualMethodResult, | ||||||
|           etStaticMethodResult: |           etStaticMethodResult: | ||||||
|             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(0)); |             current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(0)); | ||||||
|  | |||||||
| @ -740,6 +740,7 @@ implementation | |||||||
|              if found then |              if found then | ||||||
|                begin |                begin | ||||||
|                  ImplIntf.ImplementsGetter:=p; |                  ImplIntf.ImplementsGetter:=p; | ||||||
|  |                  ImplIntf.VtblImplIntf:=ImplIntf; | ||||||
|                  case p.propaccesslist[palt_read].firstsym^.sym.typ of |                  case p.propaccesslist[palt_read].firstsym^.sym.typ of | ||||||
|                    procsym : |                    procsym : | ||||||
|                      begin |                      begin | ||||||
| @ -749,7 +750,11 @@ implementation | |||||||
|                          ImplIntf.IType:=etStaticMethodResult; |                          ImplIntf.IType:=etStaticMethodResult; | ||||||
|                      end; |                      end; | ||||||
|                    fieldvarsym : |                    fieldvarsym : | ||||||
|  |                      begin | ||||||
|                        ImplIntf.IType:=etFieldValue; |                        ImplIntf.IType:=etFieldValue; | ||||||
|  |                        { this must be done more sophisticated, here is also probably the wrong place } | ||||||
|  |                        ImplIntf.IOffset:=tfieldvarsym(p.propaccesslist[palt_read].firstsym^.sym).fieldoffset; | ||||||
|  |                      end | ||||||
|                    else |                    else | ||||||
|                      internalerror(200802161); |                      internalerror(200802161); | ||||||
|                  end; |                  end; | ||||||
|  | |||||||
| @ -4397,7 +4397,7 @@ implementation | |||||||
|       begin |       begin | ||||||
|         result:=false; |         result:=false; | ||||||
|         { interfaces being implemented through delegation are not mergable (FK) } |         { interfaces being implemented through delegation are not mergable (FK) } | ||||||
|         if (MergingIntf.IType<>etStandard) or not(assigned(ProcDefs)) then |         if (IType<>etStandard) or (MergingIntf.IType<>etStandard) or not(assigned(ProcDefs)) then | ||||||
|           exit; |           exit; | ||||||
|         weight:=0; |         weight:=0; | ||||||
|         { empty interface is mergeable } |         { empty interface is mergeable } | ||||||
|  | |||||||
| @ -620,7 +620,7 @@ | |||||||
|               etFieldValue: |               etFieldValue: | ||||||
|                 begin |                 begin | ||||||
|                   // writeln('Doing etFieldValue cast of ', TObject(Instance).classname(), ' with offset = ', IEntry^.IOffset);
 |                   // writeln('Doing etFieldValue cast of ', TObject(Instance).classname(), ' with offset = ', IEntry^.IOffset);
 | ||||||
|                   Pointer(obj) := ppointer(Pbyte(Instance)+IEntry^.IOffset)^; |                   Pointer(obj) := PPointer(Pbyte(Instance)+IEntry^.IOffset)^; | ||||||
|                 end; |                 end; | ||||||
|               etVirtualMethodResult: |               etVirtualMethodResult: | ||||||
|                 begin |                 begin | ||||||
|  | |||||||
							
								
								
									
										88
									
								
								tests/webtbs/tw14418.pp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								tests/webtbs/tw14418.pp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | |||||||
|  | program project1; | ||||||
|  | 
 | ||||||
|  | {$mode objfpc}{$H+} | ||||||
|  | 
 | ||||||
|  | uses | ||||||
|  |   {$IFDEF UNIX}{$IFDEF UseCThreads} | ||||||
|  |   cthreads, | ||||||
|  |   {$ENDIF}{$ENDIF} | ||||||
|  |   Classes | ||||||
|  |   { you can add units after this }; | ||||||
|  | 
 | ||||||
|  | type | ||||||
|  |   IIntf1 = interface | ||||||
|  |     ['{87776F0F-8CE0-4881-B969-C76F5A9CA517}'] | ||||||
|  |     procedure M1; | ||||||
|  |   end; | ||||||
|  | 
 | ||||||
|  |   IIntf2 = interface | ||||||
|  |     ['{923C47DF-0A7E-4698-98B8-45175306CDF2}'] | ||||||
|  |     procedure M2; | ||||||
|  |   end; | ||||||
|  | 
 | ||||||
|  |   { TObjIntf2 } | ||||||
|  | 
 | ||||||
|  |   TObjIntf2 = class(TInterfacedObject, IIntf2) | ||||||
|  |     procedure M2; | ||||||
|  |   end; | ||||||
|  | 
 | ||||||
|  |   { TObj } | ||||||
|  | 
 | ||||||
|  |   TObj = class(TInterfacedObject, IIntf1, IIntf2) | ||||||
|  |     private | ||||||
|  |       FObjIntf2:IIntf2; | ||||||
|  |     public | ||||||
|  |       constructor Create; | ||||||
|  | 
 | ||||||
|  |       procedure M1; | ||||||
|  | 
 | ||||||
|  |       //when implementing IIntf2 using delegation, | ||||||
|  |       //TObj1.M1 is called instead of TObjIntf2 | ||||||
|  |       property I2:IIntf2 read FObjIntf2 implements IIntf2; | ||||||
|  | 
 | ||||||
|  |       //when implementing M2 directly it works right. | ||||||
|  |       //procedure M2; | ||||||
|  |   end; | ||||||
|  | 
 | ||||||
|  | { TObjIntf2 } | ||||||
|  | 
 | ||||||
|  | procedure TObjIntf2.M2; | ||||||
|  | begin | ||||||
|  |   Writeln('TObjIntf2.M2 called'); | ||||||
|  | end; | ||||||
|  | 
 | ||||||
|  | { TObj } | ||||||
|  | 
 | ||||||
|  | constructor TObj.Create; | ||||||
|  | begin | ||||||
|  |   FObjIntf2:=TObjIntf2.Create; | ||||||
|  | end; | ||||||
|  | 
 | ||||||
|  | procedure TObj.M1; | ||||||
|  | begin | ||||||
|  |   Writeln('TObj.M1 called'); | ||||||
|  | end; | ||||||
|  | 
 | ||||||
|  | { | ||||||
|  | procedure TObj.M2; | ||||||
|  | begin | ||||||
|  |   Writeln('TObj.M2 called'); | ||||||
|  | end; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | var O:TObj; | ||||||
|  |     i1:IIntf1; | ||||||
|  |     i2:IIntf2; | ||||||
|  | begin | ||||||
|  |   O:=TObj.Create; | ||||||
|  |   i1:=O; | ||||||
|  | 
 | ||||||
|  |   //all tries are unsuccessful | ||||||
|  |   //i2:=O as IIntf2; | ||||||
|  |   //(O as IIntf1).QueryInterface(IIntf2, i2); | ||||||
|  |   i1.QueryInterface(IIntf2, i2); | ||||||
|  | 
 | ||||||
|  |   //still calls TObj1.M1 | ||||||
|  |   i2.M2; | ||||||
|  | end. | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 florian
						florian