Skip to content

-O2 -O3 -O4 The compiled program will trigger abnormal access

This problem is extremely strange. As long as the -O2 -O3 -O4 optimized compilation option is not turned on, or the TStrItems defined by the generic type are not used, everything works fine.

Once the optimization option is turned on, and TStrItems are defined using generics, an exception will appear. I guess the optimization compile generated the wrong optimization code.

I tested windows x86_64, linux aarch64 and all had the same problem

Here is the code that can reproduce the problem

program Project1;

{$MODE DELPHI}{$H+}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils,
  Classes,
  Generics.Collections;

type
  TStrItems = TList<string>; // If this definition is used, an exception will be triggered when the program executes
  //TStrItems = TStringList; // If this definition is used, there will be no exceptions

  { TTestList }

  TTestList = class
  private
    FStrs: TStrItems;

    function GetStrs(out AStrs: TStrItems): Boolean;
    function GetItem(I: Integer): string;
  public
    constructor Create;

    property Items[I: Integer]: string read GetItem;
  end;

{ TTestList }

function TTestList.GetStrs(out AStrs: TStrItems): Boolean;
begin
  AStrs := FStrs;
  Result := (AStrs <> nil);
end;

function TTestList.GetItem(I: Integer): string;
var
  LStrs: TStrItems;
begin
  // Logically, the GetStrs function must return false, and LStrs must be nil.
  // If the - O2, - O3, or - O4 compilation options are not added, the generated program will not have any problems
  // Otherwise, the generated program executing here will trigger an exception for illegal access
  if GetStrs(LStrs) and (I >= 0) and (I < LStrs.Count) then
    Result := LStrs[I]
  else
    Result := '';
end;

constructor TTestList.Create;
begin
  FStrs := nil;
end;

var
  LTestList: TTestList;
  LTestStr: string;

begin
  Writeln('111');
  LTestList := TTestList.Create;
  try
    Writeln('222');
    LTestStr := LTestList.Items[0];
  finally
    FreeAndNil(LTestList);
  end;

  Writeln('DONE');
end.

Project1.zip

Edited by Yong Zeng
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information