Переглянути джерело

compiler: don't allow parameterless constructors

git-svn-id: trunk@23436 -
paul 12 роки тому
батько
коміт
1b8369dd99

+ 2 - 0
.gitattributes

@@ -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

+ 2 - 2
compiler/msg/errore.msg

@@ -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
-% 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"
 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.

+ 2 - 2
compiler/msgidx.inc

@@ -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,

Різницю між файлами не показано, бо вона завелика
+ 215 - 214
compiler/msgtxt.inc


+ 9 - 1
compiler/pdecobj.pas

@@ -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);
 
 

+ 5 - 1
compiler/ptype.pas

@@ -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;

+ 8 - 8
tests/test/terecs15.pp

@@ -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 Create; overload;
+    constructor CreateAndTest(dummy: byte);
+    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 := TRec.Create;
+  R.CreateAndTest(0);
+  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.
 
 

+ 5 - 5
tests/test/terecs16.pp

@@ -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 - 0
tests/test/terecs17.pp

@@ -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 - 0
tests/test/terecs18.pp

@@ -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.

Деякі файли не було показано, через те що забагато файлів було змінено