Watch, Follow, &
Connect with Us
Public Report
Report From: Delphi-BCB/Compiler/Delphi/Execution    [ Add a report in this area ]  
Report #:  67364   Status: Closed
Internal Error: C4310 (Class Helpers)
Project:  Delphi Build #:  11.0.2902.10471
Version:    11.2 Submitted By:   Alex Alexeev
Report Type:  Basic functionality failure Date Reported:  10/1/2008 12:16:30 AM
Severity:    Commonly encountered problem Last Updated: 3/20/2012 2:24:39 AM
Platform:    All platforms Internal Tracking #:   265610
Resolution: Fixed (Resolution Comments) Resolved in Build: : Delphi XE
Duplicate of:  None
Voting and Rating
Overall Rating: No Ratings Yet
0.00 out of 5
Total Votes: None
Description
When I try to compile this simple project I get "[DCC Error] Unit1.pas(1): F2084 Internal Error: C4310".
I suspect the reason is class helpers.
There are 3 simple units in project and two class helpers:

type
  TStreamPersistentSave = class helper for TStream
  public
    function  ReadPersistent(const AInstance: TPersistent; const AReaderClass: TPersistentReaderClass = nil): TPersistent; overload;
    procedure WritePersistent(const AInstance: TPersistent; const AWriterClass: TPersistentWriterClass = nil); overload;
    function  ReadPersistent(const AInstance: TPersistent; const AReader: TPersistentReader): TPersistent; overload;
    procedure WritePersistent(const AInstance: TPersistent; const AWriter: TPersistentWriter); overload;
  end;

type
  TPersistentStreamSave = class helper for TPersistent
    procedure LoadFromStream(const AStream: TStream; const AReaderClass: TPersistentReaderClass = nil); overload;
    procedure LoadFromFile(const AFileName: String; const AReaderClass: TPersistentReaderClass = nil); overload;
    procedure SaveToStream(const AStream: TStream; const AWriterClass: TPersistentWriterClass = nil); overload;
    procedure SaveToFile(const AFileName: String; const AWriterClass: TPersistentWriterClass = nil); overload;
    procedure LoadFromStream(const AStream: TStream; const AReader: TPersistentReader); overload;
    procedure LoadFromFile(const AFileName: String; const AReader: TPersistentReader); overload;
    procedure SaveToStream(const AStream: TStream; const AWriter: TPersistentWriter); overload;
    procedure SaveToFile(const AFileName: String; const AWriter: TPersistentWriter); overload;
  end;

Please see steps to reproduce. The problem class helper seems to be TPersistentStreamSave = class helper for TPersistent.
Steps to Reproduce:
1. Open the attached demo project.
2. Compile it.
3. Compilation will be successfull.

4. In unit Unit1 uncomment declaration of the class TTest: type TTest = class(TPersistent);
5. Try to compile project again.
6. Compilation will fail with "[DCC Error] Unit1.pas(1): F2084 Internal Error: C4310".

7. Comment back the declaration of TTest.
8. Try to recompile.
9. Compilation will fail with "[DCC Error] UnitDefaultPersFiler.pas(351): F2084 Internal Error: O620" (Note: unit UnitDefaultPersFiler.pas does not contain any class helpers).

10. In order to restore functionality you must restart Delphi.

11. Delete or comment unit UnitPersistentHelper from uses clause (Note: unit UnitPersistentHelper.pas contains only one declaration - class helper for TPersistent).
12. Uncomment the declaration of TTest class.
13. Compile the project.
14. Compilation will be successfull.
Workarounds
None
Attachment
DemoTest.zip
Comments

Alex Alexeev at 10/1/2008 12:21:19 AM -
Looks like this report is duplicate of #51322.
And, hey, I spotted the TPersistent in #51322 too! :)

I posted this report for better description of the problem (since I can not add attachment with comment to existing report).

Alex Alexeev at 10/1/2008 12:52:10 AM -
Just checked this issue in D2009 12.0.3170.16989.

The bug still exists.

But instead of C4310 I got "[DCC Fatal Error] Unit1.pas(1): F2084 Internal Error: C4539"

Balazs Farkas at 10/15/2008 11:52:20 AM -
I have created a much simpler test case, and I have found a workaround.
Test case:
-------------------
unit1.pas:
-------------------
implementation
uses
  unit2;
type
  TTest = class(TPersistent);
-------------------
unit2.pas:
-------------------
interface
uses Classes;
type
  TTestHelper = class helper for TPersistent
    procedure TestMethod(const A: Integer; B: Integer); // internal error C4310
    // procedure TestMethod(const A: Integer; B: Integer); stdcall; // OK
    // procedure TestMethod(const A: Integer); // OK
  end;
implementation
procedure TTestHelper.TestMethod(const A: Integer; B: Integer);
begin
end;
-------------------
It seems that the internal error C4310 occurs only when you use the default
register calling convetion and two or more parameters in class helper methods.
Workaround is simple: set calling convention to stdcall.

Alex Alexeev at 11/30/2010 12:32:53 PM -
This issue seems to be fixed in Delphi XE SP1. I don't know for Delphi 2010 and Delphi XE without SP.

Tomohiro Takahashi at 11/30/2010 4:46:28 PM -
Thanks for the confirmation. I will check the internal status.

Server Response from: ETNACODE01