View Issue Details

IDProjectCategoryView StatusLast Update
0021310FPCCompilerpublic2019-09-13 15:56
ReporterMarco van de VoortAssigned ToSven Barth 
PrioritynormalSeverityminorReproducibilityhave not tried
Status assignedResolutionopen 
Product Version2.7.1Product Build2011-02-15 
Target VersionFixed in Version 
Summary0021310: Global Generic template references static symtable
DescriptionExample code that compiles with Delphi XE gives above error.

Problem seems to be the (pure?!) constants in the implementation.
Tagsgenerics
Fixed in Revision
FPCOldBugId0
FPCTarget
Attached Files
  • baseimagegen.pas (784 bytes)
    unit baseimagegen;
    // part of code that allocates a 64-bit  aligned buffer based on a generic type.
    // original code and this sample compiles with Delphi XE
    interface
    
    {$ifdef fpc}{$mode delphi}{$endif}
    
    Type
     
      tbwimagegen <T > = Class
                     Type
                        BaseUnit = T;
                        RefT= ^BaseUnit;
                     private
                      allocptr:reft;
                     protected
                     public
                      procedure alloc;   
                     end;
    
    implementation
    
    Const
      aligndefault = 64;
      alignpower2minus1 = aligndefault-1; // and mask
    procedure tbwimagegen<T>.alloc;
    var alignbytes : integer;
    
    begin
         alignbytes:=aligndefault-(integer(allocptr) and alignpower2minus1);      
    end;
    
    end.
    
    
    baseimagegen.pas (784 bytes)

Relationships

related to 0024064 resolvedSven Barth Global Generic template references static symtable for procedure 

Activities

2012-02-17 14:01

 

baseimagegen.pas (784 bytes)
unit baseimagegen;
// part of code that allocates a 64-bit  aligned buffer based on a generic type.
// original code and this sample compiles with Delphi XE
interface

{$ifdef fpc}{$mode delphi}{$endif}

Type
 
  tbwimagegen <T > = Class
                 Type
                    BaseUnit = T;
                    RefT= ^BaseUnit;
                 private
                  allocptr:reft;
                 protected
                 public
                  procedure alloc;   
                 end;

implementation

Const
  aligndefault = 64;
  alignpower2minus1 = aligndefault-1; // and mask
procedure tbwimagegen<T>.alloc;
var alignbytes : integer;

begin
     alignbytes:=aligndefault-(integer(allocptr) and alignpower2minus1);      
end;

end.

baseimagegen.pas (784 bytes)

Marco van de Voort

2012-06-04 12:57

manager   ~0060255

Last edited: 2012-06-04 12:57

If I can get around the need for constraints(0020854), this is my high prio item btw.

Sven Barth

2012-06-06 14:43

manager   ~0060309

I'd like to give you a fix for this, but while the case of freshly compiled units is rather easy, I have the feeling that the "loading from PPU" one will be a lot more complicated (based on my experience of the last time when I tried to work with reloaded staticsymtables). Thus I have decided (even before you assigned this bug to me) to postbone this until I work in a branch again to implement generic methods and constraints (where I also hope to implement some simplifications for some generic related conditions in the parser as well...).

Regards,
Sven

Marco van de Voort

2013-01-11 13:48

manager   ~0064814

Status?

Sven Barth

2013-01-11 16:16

manager   ~0064818

Still as problematic as before... the difference to Delphi is that Delphi stores the generated nodes and thus the constant is already resolved and you can use the generic without problems (but this only works with untyped ordinal or float constants!). In FPC however we store the token stream and thus we try to find the symbol for the const which would work without problems if the generic's unit is currently compiled as well, but if we loaded the unit from the ppu we don't load it's implementation symbols! While we could load them of course for every loaded ppu (though I don't know yet how) I'd like to avoid that to not blow up the compiler's memory usage a thousandfold...

Couldn't you declare the constant as a "private const" as a workaround or in a third unit?

Regards,
Sven

Marco van de Voort

2015-01-06 22:47

manager   ~0080164

No, I would prefer not. I use these quite a lot, and also outside the generic.

Marco van de Voort

2015-02-27 14:44

manager   ~0081481

An interesting, possibly related, detail is btw that if you assign a function to a generic proceduretype, the function must be exported, otherwise you get

[dcc32 Error] genlight.pas(818): E2506 Method of parameterized type declared in interface section must not use local symbol 'comparedatetime'

in my XE3.

Sven Barth

2015-04-17 15:31

manager   ~0083003

Yes, the point is that Delphi allows local ordinal and float constants, because unlike us they don't store the token stream, but the generated node tree for the generic and thus the constant is already replaced with its constant value. This does not work for string constants or method/function pointers.

Regards,
Sven

Marco van de Voort

2015-04-20 10:39

manager   ~0083059

Last edited: 2015-12-29 15:21

View 2 revisions

Now I'm paying attention to it using delphi, there are more such cases.

Delphi doesn't mind if I use a normal constant, but if I change

const
  alignpower2minus1 = (aligndefault-1); // and mask

to

const
  alignpower2minus1 = ptruint(aligndefault-1); // and mask


the above "local symbol" error already appears.


The reason to fix is mainly when classes don't inherit, but use the same constants. And of course implementation vs interface. (modularization/information hiding, and no (strict) private is not the same)

Alexander Mintek

2019-01-25 16:49

reporter   ~0113617

Hi, any progress here?

Sven Barth

2019-01-31 10:48

manager   ~0113753

Nope and there won't be for the foreseeable future as this is a complicated topic.

Serge Anvarov

2019-01-31 11:48

reporter   ~0113755

Workaround. Put the constants inside procedures, or redefine them in the procedure:

procedure tbwimagegen<T>.alloc;
const
  aligndefault = baseimagegen.aligndefault;
  alignpower2minus1 = baseimagegen.alignpower2minus1;
var
  alignbytes: PtrInt;
begin
  alignbytes := aligndefault - (PtrInt(allocptr) and alignpower2minus1);
end;

Thaddy de Koning

2019-02-01 15:40

reporter   ~0113780

PtrInt?
Your idea works, but should be unsigned?

Alexander Mintek

2019-09-04 23:55

reporter   ~0117956

Yet another workaround, that may give some clue as well.

This error is raised for object's method when it references unit-private routines.
Making them public or moving to other unit helps.

Sven Barth

2019-09-13 15:56

manager   ~0118062

There is no need for a clue. It's simply that the generic architecture inside the compiler explicitly disallows this and one first needs to think about a solution for this.

Issue History

Date Modified Username Field Change
2012-02-17 14:01 Marco van de Voort New Issue
2012-02-17 14:01 Marco van de Voort File Added: baseimagegen.pas
2012-02-17 14:01 Marco van de Voort FPCOldBugId => 0
2012-05-09 16:43 Marco van de Voort Status new => assigned
2012-05-09 16:43 Marco van de Voort Assigned To => Sven Barth
2012-05-12 16:32 Sven Barth Tag Attached: generics
2012-06-04 12:57 Marco van de Voort Note Added: 0060255
2012-06-04 12:57 Marco van de Voort Note Edited: 0060255
2012-06-04 12:57 Marco van de Voort Note Edited: 0060255
2012-06-06 14:43 Sven Barth Note Added: 0060309
2013-01-11 13:48 Marco van de Voort Note Added: 0064814
2013-01-11 16:16 Sven Barth Note Added: 0064818
2013-08-13 11:20 Sven Barth Relationship added related to 0024064
2015-01-06 22:47 Marco van de Voort Note Added: 0080164
2015-02-27 14:44 Marco van de Voort Note Added: 0081481
2015-04-17 15:31 Sven Barth Note Added: 0083003
2015-04-20 10:39 Marco van de Voort Note Added: 0083059
2015-12-29 15:21 Marco van de Voort Note Edited: 0083059 View Revisions
2019-01-25 16:49 Alexander Mintek Note Added: 0113617
2019-01-31 10:48 Sven Barth Note Added: 0113753
2019-01-31 11:48 Serge Anvarov Note Added: 0113755
2019-02-01 15:40 Thaddy de Koning Note Added: 0113780
2019-09-04 23:55 Alexander Mintek Note Added: 0117956
2019-09-13 15:56 Sven Barth Note Added: 0118062