View Issue Details

IDProjectCategoryView StatusLast Update
0025647LazarusLCLpublic2015-04-03 13:14
ReporterLenz KesslerAssigned ToMaxim Ganetsky 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformWin32OSWindowsOS Version7
Product Version1.3 (SVN)Product Buildtrunk revision 43849 
Target VersionFixed in Version1.2.0 
Summary0025647: Building Lazarus fails with compiler error in "dbgrids.pas" when using latest FPC
DescriptionWhen trying to build the entire Lazarus package with "make clean all bigide", while using latest FreePascal built from trunk revision 26620 (latest at this moment), build fails with error in "dbgrids.pas":

Compiling dbactns.pp
Compiling dbctrls.pp
Compiling maskedit.pp
Compiling calendar.pp
Compiling .\widgetset\wscalendar.pp
dbctrls.pp(1337,56) Warning: Symbol "Lookup" is deprecated
Compiling dbgrids.pas
Compiling grids.pas
Compiling dynamicarray.pas
Compiling .\widgetset\wsgrids.pp
grids.pas(6989,3) Note: Local variable "i" not used
dbgrids.pas(1149,18) Warning: Symbol "Lookup" is deprecated
dbgrids.pas(2996,54) Warning: Symbol "Lookup" is deprecated
dbgrids.pas(3017,28) Warning: Symbol "Lookup" is deprecated
dbgrids.pas(3697,30) Warning: Symbol "Lookup" is deprecated
dbgrids.pas(3991,32) Error: Can't take the address of constant expressions
dbgrids.pas(4035,30) Error: Can't take the address of constant expressions
dbgrids.pas(4050,30) Error: Can't take the address of constant expressions
dbgrids.pas(4126) Fatal: There were 3 errors compiling module, stopping
Fatal: Compilation aborted
make[1]: *** [alllclunits.ppu] Error 1
make[1]: Leaving directory `d:/FreePascal/Lazarus/lcl'
make: *** [lazbuild] Error 2

When using trunk revisions of both FreePascal and Lazarus from a couple of days ago, the compilation was successful.
TagsNo tags attached.
Fixed in Revision44011, 44015
LazTarget-
WidgetsetWin32/Win64
Attached Files
  • project2.zip (5,854 bytes)
  • dbgrids.pas.patch (1,470 bytes)
    Index: dbgrids.pas
    ===================================================================
    --- dbgrids.pas	(revision 43864)
    +++ dbgrids.pas	(working copy)
    @@ -3988,7 +3988,8 @@
         if not AValue then begin
           FDataset.FreeBookmark(Pointer(Items[Index]));
           {$IFNDEF noautomatedbookmark}
    -      SetLength(TBookmark(FList[Index]),0); // decrease reference count
    +      Bookmark := FList[Index];
    +      SetLength(TBookmark(Bookmark),0); // decrease reference count
           {$ENDIF noautomatedbookmark}
           FList.Delete(Index);
           FGrid.Invalidate;
    @@ -4027,12 +4028,14 @@
     procedure TBookmarkList.Clear;
     var
       i: Integer;
    +  Bookmark: pointer;
     begin
       for i:=0 to FList.Count-1 do
       begin
         FDataset.FreeBookmark(Items[i]);
         {$IFNDEF noautomatedbookmark}
    -    SetLength(TBookmark(FList[i]),0); // decrease reference count
    +    Bookmark := FList[i];
    +    SetLength(TBookmark(Bookmark),0); // decrease reference count
         {$ENDIF noautomatedbookmark}
       end;
       FList.Clear;
    @@ -4042,12 +4045,14 @@
     procedure TBookmarkList.Delete;
     var
       i: Integer;
    +  Bookmark: pointer;
     begin
       for i := 0 to FList.Count - 1 do begin
         FDataset.GotoBookmark(Items[i]);
         FDataset.Delete;
         {$IFNDEF noautomatedbookmark}
    -    SetLength(TBookmark(FList[i]),0); // decrease reference count
    +    Bookmark := FList[i];
    +    SetLength(TBookmark(Bookmark),0); // decrease reference count
         {$ENDIF noautomatedbookmark}
         FList.Delete(i);
       end;
    
    dbgrids.pas.patch (1,470 bytes)
  • error1.JPG (54,879 bytes)
    error1.JPG (54,879 bytes)
  • dbgrids-another.diff (2,238 bytes)
    Index: dbgrids.pas
    ===================================================================
    --- dbgrids.pas	(revision 43866)
    +++ dbgrids.pas	(working copy)
    @@ -3968,13 +3968,13 @@
     
     procedure TBookmarkList.SetCurrentRowSelected(const AValue: boolean);
     var
    -  Bookmark: pointer;
    +  Bookmark: TBookmark;
       Index: Integer;
     begin
       CheckActive;
     
       Bookmark := nil;
    -  TBookmark(Bookmark) := FGrid.Datasource.Dataset.GetBookmark; // fetch and increase reference count
    +  Bookmark := FGrid.Datasource.Dataset.GetBookmark; // fetch and increase reference count
       if Bookmark = nil then
         Exit;
     
    @@ -3988,7 +3988,8 @@
         if not AValue then begin
           FDataset.FreeBookmark(Pointer(Items[Index]));
           {$IFNDEF noautomatedbookmark}
    -      SetLength(TBookmark(FList[Index]),0); // decrease reference count
    +      Bookmark := TBookmark(FList[Index]);
    +      SetLength(Bookmark,0); // decrease reference count
           {$ENDIF noautomatedbookmark}
           FList.Delete(Index);
           FGrid.Invalidate;
    @@ -3997,7 +3998,7 @@
         if AValue then begin
           // the reference count of Bookmark was increased above, so it is save to
           // store it here as pointer
    -      FList.Insert(Index, Bookmark);
    +      FList.Insert(Index, Pointer(Bookmark));
           FGrid.Invalidate;
         end else
           FDataset.FreeBookmark(Bookmark);
    @@ -4027,12 +4028,14 @@
     procedure TBookmarkList.Clear;
     var
       i: Integer;
    +  Bookmark: TBookmark;
     begin
       for i:=0 to FList.Count-1 do
       begin
         FDataset.FreeBookmark(Items[i]);
         {$IFNDEF noautomatedbookmark}
    -    SetLength(TBookmark(FList[i]),0); // decrease reference count
    +    Bookmark := TBookmark(FList[i]);
    +    SetLength(Bookmark,0); // decrease reference count
         {$ENDIF noautomatedbookmark}
       end;
       FList.Clear;
    @@ -4042,12 +4045,14 @@
     procedure TBookmarkList.Delete;
     var
       i: Integer;
    +  Bookmark: TBookmark;
     begin
       for i := 0 to FList.Count - 1 do begin
         FDataset.GotoBookmark(Items[i]);
         FDataset.Delete;
         {$IFNDEF noautomatedbookmark}
    -    SetLength(TBookmark(FList[i]),0); // decrease reference count
    +    Bookmark := TBookmark(FList[i]);
    +    SetLength(Bookmark,0); // decrease reference count
         {$ENDIF noautomatedbookmark}
         FList.Delete(i);
       end;
    
    dbgrids-another.diff (2,238 bytes)
  • dbgrids-another-test.pas (1,937 bytes)
    Program test1;
    
    {$MODE OBJFPC}
    
    Uses Classes;
    
    //========== Global Types ====================================================//
    
    Type
    
      // TDynArray //
    
      PDynArray = ^TDynArray;
      TDynArray = Packed Record
        RefCount : PtrInt;
        HighValue : SizeInt;
      End; { Record }
    
      // TBytes //
    
      TBytes = Array OF Byte;
    
    //========== Global Variables ================================================//
    
    Var
    
      P     : Pointer;
      B2    : TBytes;
      Bytes : TBytes;
      List  : TFPList;  
    
    //========== Global Functions ================================================//
    
    Procedure ShowRefLen(Const B : TBytes);
    Begin
      With PDynArray(Pointer(B) - SizeOF(TDynArray) )^ 
       DO Writeln('High:', HighValue, ', Ref:', RefCount);
    End; { Procedure }
    
    Begin
    
      List := TFPList.Create;
    
      Try
    
        // Set Bytes to 10 //
    
        SetLength(Bytes, 10);
        ShowRefLen(Bytes); // Ref Count: 1
    
        // Type-cast and add Bytes (no ref count added) to list as Pointer //
    
        List.Add(Pointer(Bytes) );
        ShowRefLen(Bytes); // Ref Count: 1
    
        // B2 is TBytes and getting assigned to the original Bytes, therefor increasing Ref-Count //
    
        B2 := TBytes(List[0] );
        ShowRefLen(Bytes); // Ref Count: 2
    
        // Let's decrease Reference Count //
    
        SetLength(B2, 0);
        ShowRefLen(Bytes); // Ref Count: 1! (We're back to one, which means the SetLength was useless) //
        
        // Delete the Item and let's try again //
    
        List.Delete(0);
    
        SetLength(Bytes, 10);
        List.Add(Pointer(Bytes) );
    
        // This time we grab it as a normal Pointer (P) //
    
        P := List[0];
        ShowRefLen(Bytes); // Ref Count: 1
    
        // De-Allocate the original Bytes //
    
        SetLength(TBytes(P), 0); // Properly decrease reference count, Ref Count: 0
        ShowRefLen(Bytes); // Don't do this call as it will show the Reference Count of a dangling Pointer at this point
    
        // Just because :p //
    
        List.Delete(0);
    
      Finally
        List.Free;
      End; { Try, Finally }
    
    End.
    
    dbgrids-another-test.pas (1,937 bytes)

Relationships

has duplicate 0025659 closedMaxim Ganetsky Patches [Patch] a little patch to fix compilation with FPC trunk (should not break latest stable, too) 
has duplicate 0025663 resolvedMaxim Ganetsky Lazarus LCL/DBGrids.pas doesn't compile due to SetLength(<const>, #) issues. 

Activities

Lenz Kessler

2014-01-30 03:20

reporter   ~0072777

Last edited: 2014-01-30 04:38

View 2 revisions

Note that this is probably due to changes in compiler, as Lazarus package compiles successfully with FreePascal 2.6.2, or FreePascal from trunk revision 26534 (dated January 20, 2014).

Compiling with FreePascal from trunk revision 26578 (January 24, 2014) also succeeds.

Vincent Snijders

2014-01-30 16:27

manager   ~0072779

Caused by http://svn.freepascal.org/cgi-bin/viewvc.cgi?view=revision&revision=26608

See also:
http://lists.lazarus.freepascal.org/pipermail/lazarus/2014-January/085573.html

Cyrax

2014-01-30 19:08

reporter  

project2.zip (5,854 bytes)

Cyrax

2014-01-30 19:09

reporter   ~0072780

Added demo project.

This bug report should be moved to FPC side.

Marco van de Voort

2014-01-31 10:47

manager   ~0072785

It passes a value of a property ( a string) to something VAR (setlength), so there is some truth in the message.

Jonas Maebe

2014-01-31 11:19

manager   ~0072786

Marco is correct, that code is not supposed to compile. It's a case of http://wiki.freepascal.org/User_Changes_2.6.0#Taking_the_address_of_fields_of_record_properties that wasn't caught before.

Udo Schmal

2014-02-01 15:13

reporter  

dbgrids.pas.patch (1,470 bytes)
Index: dbgrids.pas
===================================================================
--- dbgrids.pas	(revision 43864)
+++ dbgrids.pas	(working copy)
@@ -3988,7 +3988,8 @@
     if not AValue then begin
       FDataset.FreeBookmark(Pointer(Items[Index]));
       {$IFNDEF noautomatedbookmark}
-      SetLength(TBookmark(FList[Index]),0); // decrease reference count
+      Bookmark := FList[Index];
+      SetLength(TBookmark(Bookmark),0); // decrease reference count
       {$ENDIF noautomatedbookmark}
       FList.Delete(Index);
       FGrid.Invalidate;
@@ -4027,12 +4028,14 @@
 procedure TBookmarkList.Clear;
 var
   i: Integer;
+  Bookmark: pointer;
 begin
   for i:=0 to FList.Count-1 do
   begin
     FDataset.FreeBookmark(Items[i]);
     {$IFNDEF noautomatedbookmark}
-    SetLength(TBookmark(FList[i]),0); // decrease reference count
+    Bookmark := FList[i];
+    SetLength(TBookmark(Bookmark),0); // decrease reference count
     {$ENDIF noautomatedbookmark}
   end;
   FList.Clear;
@@ -4042,12 +4045,14 @@
 procedure TBookmarkList.Delete;
 var
   i: Integer;
+  Bookmark: pointer;
 begin
   for i := 0 to FList.Count - 1 do begin
     FDataset.GotoBookmark(Items[i]);
     FDataset.Delete;
     {$IFNDEF noautomatedbookmark}
-    SetLength(TBookmark(FList[i]),0); // decrease reference count
+    Bookmark := FList[i];
+    SetLength(TBookmark(Bookmark),0); // decrease reference count
     {$ENDIF noautomatedbookmark}
     FList.Delete(i);
   end;
dbgrids.pas.patch (1,470 bytes)

Udo Schmal

2014-02-01 15:15

reporter   ~0072794

Last edited: 2014-02-01 15:18

View 2 revisions

not nice but with dbgrids.pas.patch (see Attached Files) building Lazarus doesn't fails

Derit Agustin

2014-02-02 03:34

reporter  

error1.JPG (54,879 bytes)
error1.JPG (54,879 bytes)

Maxim Ganetsky

2014-02-02 21:20

developer  

dbgrids-another.diff (2,238 bytes)
Index: dbgrids.pas
===================================================================
--- dbgrids.pas	(revision 43866)
+++ dbgrids.pas	(working copy)
@@ -3968,13 +3968,13 @@
 
 procedure TBookmarkList.SetCurrentRowSelected(const AValue: boolean);
 var
-  Bookmark: pointer;
+  Bookmark: TBookmark;
   Index: Integer;
 begin
   CheckActive;
 
   Bookmark := nil;
-  TBookmark(Bookmark) := FGrid.Datasource.Dataset.GetBookmark; // fetch and increase reference count
+  Bookmark := FGrid.Datasource.Dataset.GetBookmark; // fetch and increase reference count
   if Bookmark = nil then
     Exit;
 
@@ -3988,7 +3988,8 @@
     if not AValue then begin
       FDataset.FreeBookmark(Pointer(Items[Index]));
       {$IFNDEF noautomatedbookmark}
-      SetLength(TBookmark(FList[Index]),0); // decrease reference count
+      Bookmark := TBookmark(FList[Index]);
+      SetLength(Bookmark,0); // decrease reference count
       {$ENDIF noautomatedbookmark}
       FList.Delete(Index);
       FGrid.Invalidate;
@@ -3997,7 +3998,7 @@
     if AValue then begin
       // the reference count of Bookmark was increased above, so it is save to
       // store it here as pointer
-      FList.Insert(Index, Bookmark);
+      FList.Insert(Index, Pointer(Bookmark));
       FGrid.Invalidate;
     end else
       FDataset.FreeBookmark(Bookmark);
@@ -4027,12 +4028,14 @@
 procedure TBookmarkList.Clear;
 var
   i: Integer;
+  Bookmark: TBookmark;
 begin
   for i:=0 to FList.Count-1 do
   begin
     FDataset.FreeBookmark(Items[i]);
     {$IFNDEF noautomatedbookmark}
-    SetLength(TBookmark(FList[i]),0); // decrease reference count
+    Bookmark := TBookmark(FList[i]);
+    SetLength(Bookmark,0); // decrease reference count
     {$ENDIF noautomatedbookmark}
   end;
   FList.Clear;
@@ -4042,12 +4045,14 @@
 procedure TBookmarkList.Delete;
 var
   i: Integer;
+  Bookmark: TBookmark;
 begin
   for i := 0 to FList.Count - 1 do begin
     FDataset.GotoBookmark(Items[i]);
     FDataset.Delete;
     {$IFNDEF noautomatedbookmark}
-    SetLength(TBookmark(FList[i]),0); // decrease reference count
+    Bookmark := TBookmark(FList[i]);
+    SetLength(Bookmark,0); // decrease reference count
     {$ENDIF noautomatedbookmark}
     FList.Delete(i);
   end;
dbgrids-another.diff (2,238 bytes)

Maxim Ganetsky

2014-02-02 21:22

developer   ~0072816

Last edited: 2014-02-02 21:27

View 2 revisions

Uploaded another version of the patch by Mario Ray Mahardhika (dbgrids-another.diff).

Dennis Fehr

2014-02-02 23:29

reporter  

dbgrids-another-test.pas (1,937 bytes)
Program test1;

{$MODE OBJFPC}

Uses Classes;

//========== Global Types ====================================================//

Type

  // TDynArray //

  PDynArray = ^TDynArray;
  TDynArray = Packed Record
    RefCount : PtrInt;
    HighValue : SizeInt;
  End; { Record }

  // TBytes //

  TBytes = Array OF Byte;

//========== Global Variables ================================================//

Var

  P     : Pointer;
  B2    : TBytes;
  Bytes : TBytes;
  List  : TFPList;  

//========== Global Functions ================================================//

Procedure ShowRefLen(Const B : TBytes);
Begin
  With PDynArray(Pointer(B) - SizeOF(TDynArray) )^ 
   DO Writeln('High:', HighValue, ', Ref:', RefCount);
End; { Procedure }

Begin

  List := TFPList.Create;

  Try

    // Set Bytes to 10 //

    SetLength(Bytes, 10);
    ShowRefLen(Bytes); // Ref Count: 1

    // Type-cast and add Bytes (no ref count added) to list as Pointer //

    List.Add(Pointer(Bytes) );
    ShowRefLen(Bytes); // Ref Count: 1

    // B2 is TBytes and getting assigned to the original Bytes, therefor increasing Ref-Count //

    B2 := TBytes(List[0] );
    ShowRefLen(Bytes); // Ref Count: 2

    // Let's decrease Reference Count //

    SetLength(B2, 0);
    ShowRefLen(Bytes); // Ref Count: 1! (We're back to one, which means the SetLength was useless) //
    
    // Delete the Item and let's try again //

    List.Delete(0);

    SetLength(Bytes, 10);
    List.Add(Pointer(Bytes) );

    // This time we grab it as a normal Pointer (P) //

    P := List[0];
    ShowRefLen(Bytes); // Ref Count: 1

    // De-Allocate the original Bytes //

    SetLength(TBytes(P), 0); // Properly decrease reference count, Ref Count: 0
    ShowRefLen(Bytes); // Don't do this call as it will show the Reference Count of a dangling Pointer at this point

    // Just because :p //

    List.Delete(0);

  Finally
    List.Free;
  End; { Try, Finally }

End.
dbgrids-another-test.pas (1,937 bytes)

Dennis Fehr

2014-02-02 23:31

reporter   ~0072820

About that last patch "dbgrids-another.diff", it won't do what you expect it to do, as it doesn't properly decrease the Reference Count. The test-case I uploaded will show why it doesn't work. My bug report here: http://bugs.freepascal.org/view.php?id=25663 will have a patch that addresses this. (Or use the original patch as it is almost exactly the same)

Maxim Ganetsky

2014-02-11 23:07

developer   ~0073009

Patch (the first one) applied and merged to fixes_1_2. Thanks for it and for the test.

Please test and close if OK.

Lenz Kessler

2014-02-14 00:07

reporter   ~0073052

Fix confirmed as of fpc trunk revision 26764 and lazarus trunk revision 44057

Issue History

Date Modified Username Field Change
2014-01-30 03:13 Lenz Kessler New Issue
2014-01-30 03:20 Lenz Kessler Note Added: 0072777
2014-01-30 04:38 Lenz Kessler Note Edited: 0072777 View Revisions
2014-01-30 16:27 Vincent Snijders Note Added: 0072779
2014-01-30 19:08 Cyrax File Added: project2.zip
2014-01-30 19:09 Cyrax Note Added: 0072780
2014-01-30 20:53 Maxim Ganetsky Project Lazarus => FPC
2014-01-31 10:47 Marco van de Voort Note Added: 0072785
2014-01-31 11:19 Jonas Maebe Note Added: 0072786
2014-01-31 11:19 Jonas Maebe Project FPC => Lazarus
2014-02-01 15:13 Udo Schmal File Added: dbgrids.pas.patch
2014-02-01 15:15 Udo Schmal Note Added: 0072794
2014-02-01 15:18 Udo Schmal Note Edited: 0072794 View Revisions
2014-02-02 03:34 Derit Agustin File Added: error1.JPG
2014-02-02 21:20 Maxim Ganetsky File Added: dbgrids-another.diff
2014-02-02 21:21 Maxim Ganetsky Relationship added has duplicate 0025659
2014-02-02 21:22 Maxim Ganetsky Note Added: 0072816
2014-02-02 21:27 Maxim Ganetsky Note Edited: 0072816 View Revisions
2014-02-02 23:29 Dennis Fehr File Added: dbgrids-another-test.pas
2014-02-02 23:31 Dennis Fehr Note Added: 0072820
2014-02-03 00:12 Maxim Ganetsky Relationship added has duplicate 0025663
2014-02-11 22:37 Maxim Ganetsky Assigned To => Maxim Ganetsky
2014-02-11 22:37 Maxim Ganetsky Status new => assigned
2014-02-11 23:07 Maxim Ganetsky Fixed in Revision => 44011, 44015
2014-02-11 23:07 Maxim Ganetsky LazTarget => -
2014-02-11 23:07 Maxim Ganetsky Note Added: 0073009
2014-02-11 23:07 Maxim Ganetsky Status assigned => resolved
2014-02-11 23:07 Maxim Ganetsky Fixed in Version => 1.2.0
2014-02-11 23:07 Maxim Ganetsky Resolution open => fixed
2014-02-14 00:07 Lenz Kessler Note Added: 0073052
2014-02-14 00:07 Lenz Kessler Status resolved => closed