View Issue Details

IDProjectCategoryView StatusLast Update
0038207FPCCompilerpublic2021-04-05 12:59
ReporterJulian Puhl Assigned ToSven Barth  
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionopen 
Platformx64OSWindows 
Product Version3.3.1 
Summary0038207: Recent type helper fixes introduce bug with "with" syntax
DescriptionIf you compile the attached program an run it, you will get a range check error / crash. I narrowed the error down as far as I could, but there might still be a more simple test case.

This seems to be related to 0038122 .
Additional InformationTested with Lazarus default debug and release build modes.
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget-
Attached Files

Relationships

child of 0038122 feedbackSven Barth Type Helper only modifies stack copy instead of self 

Activities

Julian Puhl

2020-12-12 09:11

reporter  

HelperBug.pas (1,585 bytes)   
program HelperBug;

{$modeswitch advancedrecords}
{$modeswitch typehelpers}

type

  TTestInner = record
    A: Integer;
    B: array of Integer;
    procedure SetBWithoutHelper(Value: Integer); inline;
  end;

  TTest = record
    A: Integer;
    B: array of Integer;
    TestInner: TTestInner;
  end;

  TTestHelper = record helper for TTest
    procedure SetBWithHelper(Value: Integer); inline;
  end;

  TTestInnerHelper = record helper for TTestInner
    procedure SetBWithHelper(Value: Integer); inline; //inline is needed for error
  end;

  procedure TTestInner.SetBWithoutHelper(Value: Integer);
  begin
    B[0] := Value;
  end;

  procedure TTestInnerHelper.SetBWithHelper(Value: Integer);
  begin
    B[0] := Value;
  end;

  procedure TTestHelper.SetBWithHelper(Value: Integer);
  begin
    B[0] := Value;
  end;

var
  Test: TTest;
begin

  Test.B := nil; //Otherwise compiler warns, despite setlength initializes everything to 0 according to documentation

  //Setting lengths
  setlength(Test.B, 1);
  setlength(Test.TestInner.B, 1); //Note: Curiously compiler does NOT warn here about no initialization

  //First tests all fine
  Test.B[0] := 1;
  Test.SetBWithHelper(1);
  with Test do
    SetBWithHelper(1);

  //Still all fine here
  Test.TestInner.B[0] := 1;
  Test.TestInner.SetBWithHelper(1);
  Test.TestInner.SetBWithoutHelper(1);
  with Test.TestInner do
    SetBWithoutHelper(1);

  //Causes range check error or crashes without checks
  with Test.TestInner do
    SetBWithHelper(1);
end.
HelperBug.pas (1,585 bytes)   

Julian Puhl

2021-01-01 16:12

reporter   ~0127997

Any news on this? Also the mentioned probably related bug report 0038122 has been reopened, so maybe this bug report could be at least marked as related.

With the current revision 47932 this error still happens.

Sven Barth

2021-03-24 22:05

manager   ~0129865

It seems to be fixed already. At least I can not reproduce it with 3.3.1 on x86_64-win64. If you still can reproduce it, then please provide the command line parameters for the compiler.

Julian Puhl

2021-03-27 13:53

reporter   ~0129922

Yes, I still am getting the error. FPC svn revision is 49056.

I attached the Lazarus project (Lazarus svn build) . Does this help you?
BugTypeHelper.zip (1,640 bytes)

Erik Rößiger

2021-04-05 00:54

reporter   ~0130096

I just tested the latest attached project on Linux 64bit on Fedora 32, and as Win32 and Win64 executables on Windows 8.1.
The Linux 64bit and the Win32 targetted executables work flawless. The Win64 targetted executable crashes still. Using the most recent FPC SVN Trunk revision (49119).

jamie philbrook

2021-04-05 02:18

reporter   ~0130099

its the INLINE that is causing the problem if you are using 3.2.x and up..

Due to that, I have a pile of code that works fine in 3.0.4 and down but no longer in 3.2.x , but for me that will never get fixed because I was told is undocumented coding I was doing.. However, in this case I believe the same reason is generating the errors here..

 The compiler forgets to define the refence to the object using an INLINE..

 My case was I was using it to morph a function into a procedure so I could have a REFERENCE return type, this works perfectly in 3.0.4 and down and also in Delphi..

P.s. your code here seems to work in Delphi too, I am sure it will also work in 3.0.4..

Don't throw your 3.0.4 away..

Sven Barth

2021-04-05 12:59

manager   ~0130105

@jamie: you don't get it, do you? With what you're trying to do, what multiple people have told you, you're relying on an implementation detail of Delphi's code generator. I've shown you an example that fails in Delphi as well and your code could as-is very well fail on the LLVM based Delphi compilers, too, as that does much more aggressive optimizations.

The bug here however is indeed a bug, because it surfaced due to a change of mine.

Issue History

Date Modified Username Field Change
2020-12-12 09:11 Julian Puhl New Issue
2020-12-12 09:11 Julian Puhl File Added: HelperBug.pas
2021-01-01 16:12 Julian Puhl Note Added: 0127997
2021-01-01 17:04 Sven Barth Relationship added child of 0038122
2021-03-24 22:05 Sven Barth Assigned To => Sven Barth
2021-03-24 22:05 Sven Barth Status new => feedback
2021-03-24 22:05 Sven Barth FPCTarget => -
2021-03-24 22:05 Sven Barth Note Added: 0129865
2021-03-27 13:53 Julian Puhl Note Added: 0129922
2021-03-27 13:53 Julian Puhl File Added: BugTypeHelper.zip
2021-03-27 13:53 Julian Puhl Status feedback => assigned
2021-04-05 00:54 Erik Rößiger Note Added: 0130096
2021-04-05 02:18 jamie philbrook Note Added: 0130099
2021-04-05 12:59 Sven Barth Note Added: 0130105