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/terecs14.pp svneol=native#text/pascal
tests/test/terecs15.pp svneol=native#text/pascal tests/test/terecs15.pp svneol=native#text/pascal
tests/test/terecs16.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/terecs2.pp svneol=native#text/pascal
tests/test/terecs3.pp svneol=native#text/pascal tests/test/terecs3.pp svneol=native#text/pascal
tests/test/terecs4.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 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. % 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. % 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 parser_e_no_parameterless_constructor_in_records=03302_E_Parameterless constructors aren't allowed in records or record helpers
% Constructor declarations 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" 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. % 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. % 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_record_published=03299;
parser_e_no_destructor_in_records=03300; parser_e_no_destructor_in_records=03300;
parser_e_class_methods_only_static_in_records=03301; 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_at_least_one_argument_must_be_of_type=03303;
parser_e_cant_use_type_parameters_here=03304; parser_e_cant_use_type_parameters_here=03304;
parser_e_externals_no_section=03305; parser_e_externals_no_section=03305;
@ -967,7 +967,7 @@ const
option_info=11024; option_info=11024;
option_help_pages=11025; option_help_pages=11025;
MsgTxtSize = 68401; MsgTxtSize = 68415;
MsgIdxMax : array[1..20] of longint=( MsgIdxMax : array[1..20] of longint=(
26,93,332,120,87,56,126,26,202,63, 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 if is_classdef then
result:=class_constructor_head(current_structdef) result:=class_constructor_head(current_structdef)
else 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); chkcpp(result);

View File

@ -718,7 +718,11 @@ implementation
if is_classdef then if is_classdef then
pd:=class_constructor_head(current_structdef) pd:=class_constructor_head(current_structdef)
else 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; parse_only:=oldparse_only;
fields_allowed:=false; fields_allowed:=false;

View File

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

View File

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