compiler: don't allow parameterless constructors

git-svn-id: trunk@23436 -
This commit is contained in:
paul 2013-01-18 01:24:04 +00:00
parent 83af4e93f7
commit 1b8369dd99
10 changed files with 374 additions and 300 deletions

2
.gitattributes vendored
View File

@ -10810,6 +10810,8 @@ tests/test/terecs13d.pp svneol=native#text/pascal
tests/test/terecs14.pp svneol=native#text/pascal
tests/test/terecs15.pp svneol=native#text/pascal
tests/test/terecs16.pp svneol=native#text/pascal
tests/test/terecs17.pp svneol=native#text/pascal
tests/test/terecs18.pp svneol=native#text/pascal
tests/test/terecs2.pp svneol=native#text/pascal
tests/test/terecs3.pp svneol=native#text/pascal
tests/test/terecs4.pp svneol=native#text/pascal

View File

@ -1385,8 +1385,8 @@ parser_e_no_destructor_in_records=03300_E_Destructors aren't allowed in records
parser_e_class_methods_only_static_in_records=03301_E_Class methods must be static in records
% Class methods declarations aren't allowed in records without static modifier.
% Records have no inheritance and therefore non static class methods have no sence for them.
parser_e_no_constructor_in_records=03302_E_Constructors aren't allowed in records or record helpers
% Constructor declarations aren't allowed in records or record helpers.
parser_e_no_parameterless_constructor_in_records=03302_E_Parameterless constructors aren't allowed in records or record helpers
% Constructor declarations with no arguments aren't allowed in records or record helpers.
parser_e_at_least_one_argument_must_be_of_type=03303_E_Either the result or at least one parameter must be of type "$1"
% It is required that either the result of the routine or at least one of its parameters be of the specified type.
% For example class operators either take an instance of the structured type in which they are defined, or they return one.

View File

@ -397,7 +397,7 @@ const
parser_e_no_record_published=03299;
parser_e_no_destructor_in_records=03300;
parser_e_class_methods_only_static_in_records=03301;
parser_e_no_constructor_in_records=03302;
parser_e_no_parameterless_constructor_in_records=03302;
parser_e_at_least_one_argument_must_be_of_type=03303;
parser_e_cant_use_type_parameters_here=03304;
parser_e_externals_no_section=03305;
@ -967,7 +967,7 @@ const
option_info=11024;
option_help_pages=11025;
MsgTxtSize = 68401;
MsgTxtSize = 68415;
MsgIdxMax : array[1..20] of longint=(
26,93,332,120,87,56,126,26,202,63,

File diff suppressed because it is too large Load Diff

View File

@ -912,7 +912,15 @@ implementation
if is_classdef then
result:=class_constructor_head(current_structdef)
else
result:=constructor_head;
begin
result:=constructor_head;
if is_objectpascal_helper(astruct) and
is_record(tobjectdef(astruct).extendeddef) and
(result.maxparacount=0) then
{ as long as parameterless constructors aren't allowed in records they
aren't allowed in helpers either }
MessagePos(result.procsym.fileinfo,parser_e_no_parameterless_constructor_in_records);
end;
chkcpp(result);

View File

@ -718,7 +718,11 @@ implementation
if is_classdef then
pd:=class_constructor_head(current_structdef)
else
pd:=constructor_head;
begin
pd:=constructor_head;
if pd.maxparacount = 0 then
MessagePos(pd.procsym.fileinfo,parser_e_no_parameterless_constructor_in_records);
end;
parse_only:=oldparse_only;
fields_allowed:=false;

View File

@ -12,15 +12,15 @@ type
Y: Integer;
public
// delphi does not allow constructors without arguments
constructor CreateAndTest;
constructor Create; overload;
constructor CreateAndTest(dummy: byte);
constructor Create(dummy: boolean); overload;
constructor Create(AX, AY: Integer); overload;
constructor Create(AY: Integer); overload;
end;
{ TRec }
constructor TRec.CreateAndTest;
constructor TRec.CreateAndTest(dummy: byte);
begin
X := 1;
if X <> 1 then
@ -30,7 +30,7 @@ begin
halt(2);
end;
constructor TRec.Create;
constructor TRec.Create(dummy: boolean);
begin
X := 10;
Y := 20;
@ -44,7 +44,7 @@ end;
constructor TRec.Create(AY: Integer);
begin
Create;
Create(false);
Y := AY;
end;
@ -59,8 +59,8 @@ end;
var
R: TRec;
begin
R.CreateAndTest;
R := TRec.Create;
R.CreateAndTest(0);
R := TRec.Create(false);
if R.X <> 10 then
halt(3);
if R.Y <> 20 then
@ -68,6 +68,6 @@ begin
TestRec(TRec.Create(1, 2), 1, 2, 5, 6);
TestRec(TRec.Create(2), 10, 2, 7, 8);
// delphi has an internal error here
TestRec(R.Create, 10, 20, 9, 10);
TestRec(R.Create(false), 10, 20, 9, 10);
end.

View File

@ -4,18 +4,18 @@ program terecs16;
type
TRec = record
l: longint;
constructor Create;
constructor Create(a: longint);
end;
var
r: TRec;
constructor TRec.Create;
constructor TRec.Create(a: longint);
begin
l := 0;
l := a;
r.l := 4;
if l <> 0 then
if l <> a then
halt(1);
l := 5;
if r.l <> 4 then
@ -24,7 +24,7 @@ var
end;
begin
r := TRec.Create;
r := TRec.Create(10);
if r.l <> 5 then
halt(3);
end.

27
tests/test/terecs17.pp Normal file
View File

@ -0,0 +1,27 @@
{ %FAIL }
{ %NORUN }
program terecs17;
{$mode delphi}
type
{ TRec }
TRec = record
X: Integer;
constructor Create;
end;
{ TRec }
constructor TRec.Create;
begin
end;
var
R: TRec;
begin
R := TRec.Create;
end.

32
tests/test/terecs18.pp Normal file
View File

@ -0,0 +1,32 @@
{ %FAIL }
{ %NORUN }
program terecs18;
{$mode delphi}
type
{ TRec }
TRec = record
X: Integer;
end;
{ TRecHelper }
TRecHelper = record helper for TRec
constructor Create;
end;
{ TRecHelper }
constructor TRecHelper.Create;
begin
end;
var
R: TRec;
begin
R := TRec.Create;
end.