Skip to content

Commit fba2f08

Browse files
author
Gaius Mulley
committed
PR modula2/120673: Mutually dependent types crash the compiler
This patch fixes an ICE which will occur if cyclic dependent types are used when declaring a variable. This patch detects the cyclic dependency and issues an error message for each outstanding component. gcc/m2/ChangeLog: PR modula2/120673 * gm2-compiler/M2GCCDeclare.mod (ErrorDepList): New global variable set containing every errant dependency symbol. (mystop): Remove. (EmitCircularDependancyError): Replace with ... (EmitCircularDependencyError): ... this. (AssertAllTypesDeclared): Rewrite. (DoVariableDeclaration): Ditto. (TypeDependentsDeclared): New procedure function. (PrepareGCCVarDeclaration): Ditto. (DeclareVariable): Remove assert. (DeclareLocalVariable): Ditto. (Constructor): Initialize ErrorDepList. * gm2-compiler/M2MetaError.mod (doErrorScopeProc): Rewrite and ensure that a symbol with a module scope does not lookup from a definition module. * gm2-compiler/P2SymBuild.mod (BuildType): Rewrite so that a synonym type is created using the token refering to the name on the lhs. gcc/testsuite/ChangeLog: PR modula2/120673 * gm2/pim/fail/badmodvar.mod: New test. * gm2/pim/fail/cyclictypes.mod: New test. * gm2/pim/fail/cyclictypes2.mod: New test. * gm2/pim/fail/cyclictypes4.mod: New test. Signed-off-by: Gaius Mulley <[email protected]>
1 parent 260252e commit fba2f08

File tree

7 files changed

+140
-64
lines changed

7 files changed

+140
-64
lines changed

gcc/m2/gm2-compiler/M2GCCDeclare.mod

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ TYPE
251251
VAR
252252
FreeGroup,
253253
GlobalGroup : Group ; (* The global group of all sets. *)
254+
ErrorDepList, (* The set of symbols with dependency errors. *)
254255
VisitedList,
255256
ChainedList : Set ;
256257
HaveInitDefaultTypes: BOOLEAN ; (* Have we initialized them yet? *)
@@ -261,9 +262,6 @@ VAR
261262
enumDeps : BOOLEAN ;
262263

263264

264-
PROCEDURE mystop ; BEGIN END mystop ;
265-
266-
267265
(* *************************************************** *)
268266
(*
269267
PrintNum -
@@ -1315,14 +1313,26 @@ END CanBeDeclaredPartiallyViaPartialDependants ;
13151313

13161314

13171315
(*
1318-
EmitCircularDependancyError - issue a dependancy error.
1316+
EmitCircularDependencyError - issue a dependency error.
13191317
*)
13201318

1321-
PROCEDURE EmitCircularDependancyError (sym: CARDINAL) ;
1319+
PROCEDURE EmitCircularDependencyError (sym: CARDINAL) ;
13221320
BEGIN
1323-
MetaError1('circular dependancy error found when trying to resolve {%1Uad}',
1324-
sym)
1325-
END EmitCircularDependancyError ;
1321+
(* Ensure we only issue one dependency message per symbol for this
1322+
error classification. *)
1323+
IF NOT IsElementInSet (ErrorDepList, sym)
1324+
THEN
1325+
IncludeElementIntoSet (ErrorDepList, sym) ;
1326+
IF IsVar (sym) OR IsParameter (sym)
1327+
THEN
1328+
MetaError1 ('circular dependency error found when trying to resolve {%1Had}',
1329+
sym)
1330+
ELSE
1331+
MetaError1 ('circular dependency error found when trying to resolve {%1Dad}',
1332+
sym)
1333+
END
1334+
END
1335+
END EmitCircularDependencyError ;
13261336

13271337

13281338
TYPE
@@ -1529,17 +1539,17 @@ BEGIN
15291539
IF ForeachTryDeclare (todolist,
15301540
circulartodo,
15311541
NotAllDependantsFullyDeclared,
1532-
EmitCircularDependancyError)
1542+
EmitCircularDependencyError)
15331543
THEN
15341544
ELSIF ForeachTryDeclare (partiallydeclared,
15351545
circularpartial,
15361546
NotAllDependantsPartiallyDeclared,
1537-
EmitCircularDependancyError)
1547+
EmitCircularDependencyError)
15381548
THEN
15391549
ELSIF ForeachTryDeclare (niltypedarrays,
15401550
circularniltyped,
15411551
NotAllDependantsPartiallyDeclared,
1542-
EmitCircularDependancyError)
1552+
EmitCircularDependencyError)
15431553
THEN
15441554
END
15451555
END ;
@@ -2855,13 +2865,8 @@ BEGIN
28552865
n := 1 ;
28562866
Var := GetNth(scope, n) ;
28572867
WHILE Var#NulSym DO
2858-
IF NOT AllDependantsFullyDeclared(GetSType(Var))
2859-
THEN
2860-
mystop
2861-
END ;
2862-
IF NOT AllDependantsFullyDeclared(GetSType(Var))
2868+
IF NOT TypeDependentsDeclared (Var, TRUE)
28632869
THEN
2864-
EmitCircularDependancyError(GetSType(Var)) ;
28652870
failed := TRUE
28662871
END ;
28672872
INC(n) ;
@@ -3411,15 +3416,55 @@ PROCEDURE DoVariableDeclaration (var: CARDINAL; name: ADDRESS;
34113416
isImported, isExported,
34123417
isTemporary, isGlobal: BOOLEAN;
34133418
scope: tree) ;
3419+
BEGIN
3420+
IF NOT (IsComponent (var) OR IsVarHeap (var))
3421+
THEN
3422+
IF TypeDependentsDeclared (var, TRUE)
3423+
THEN
3424+
PrepareGCCVarDeclaration (var, name, isImported, isExported,
3425+
isTemporary, isGlobal, scope)
3426+
END
3427+
END
3428+
END DoVariableDeclaration ;
3429+
3430+
3431+
(*
3432+
TypeDependentsDeclared - return TRUE if all type dependents of variable
3433+
have been declared.
3434+
*)
3435+
3436+
PROCEDURE TypeDependentsDeclared (variable: CARDINAL; errorMessage: BOOLEAN) : BOOLEAN ;
3437+
VAR
3438+
type: CARDINAL ;
3439+
BEGIN
3440+
type := GetSType (variable) ;
3441+
IF AllDependantsFullyDeclared (type)
3442+
THEN
3443+
RETURN TRUE
3444+
ELSE
3445+
IF errorMessage
3446+
THEN
3447+
EmitCircularDependencyError (variable) ;
3448+
ForeachElementInSetDo (GlobalGroup^.ToDoList, EmitCircularDependencyError)
3449+
END
3450+
END ;
3451+
RETURN FALSE
3452+
END TypeDependentsDeclared ;
3453+
3454+
3455+
(*
3456+
PrepareGCCVarDeclaration -
3457+
*)
3458+
3459+
PROCEDURE PrepareGCCVarDeclaration (var: CARDINAL; name: ADDRESS;
3460+
isImported, isExported,
3461+
isTemporary, isGlobal: BOOLEAN;
3462+
scope: tree) ;
34143463
VAR
34153464
type : tree ;
34163465
varType : CARDINAL ;
34173466
location: location_t ;
34183467
BEGIN
3419-
IF IsComponent (var) OR IsVarHeap (var)
3420-
THEN
3421-
RETURN
3422-
END ;
34233468
IF GetMode (var) = LeftValue
34243469
THEN
34253470
(*
@@ -3457,7 +3502,7 @@ BEGIN
34573502
isGlobal, scope, NIL)) ;
34583503
WatchRemoveList (var, todolist) ;
34593504
WatchIncludeList (var, fullydeclared)
3460-
END DoVariableDeclaration ;
3505+
END PrepareGCCVarDeclaration ;
34613506

34623507

34633508
(*
@@ -3493,7 +3538,6 @@ BEGIN
34933538
THEN
34943539
scope := FindContext (ModSym) ;
34953540
decl := FindOuterModule (variable) ;
3496-
Assert (AllDependantsFullyDeclared (GetSType (variable))) ;
34973541
PushBinding (ModSym) ;
34983542
DoVariableDeclaration (variable,
34993543
KeyToCharStar (GetFullSymName (variable)),
@@ -3521,7 +3565,6 @@ BEGIN
35213565
THEN
35223566
scope := FindContext (mainModule) ;
35233567
decl := FindOuterModule (variable) ;
3524-
Assert (AllDependantsFullyDeclared (GetSType (variable))) ;
35253568
PushBinding (mainModule) ;
35263569
DoVariableDeclaration (variable,
35273570
KeyToCharStar (GetFullSymName (variable)),
@@ -3618,7 +3661,6 @@ END DeclareImportedVariablesWholeProgram ;
36183661

36193662
PROCEDURE DeclareLocalVariable (var: CARDINAL) ;
36203663
BEGIN
3621-
Assert (AllDependantsFullyDeclared (var)) ;
36223664
DoVariableDeclaration (var,
36233665
KeyToCharStar (GetFullSymName (var)),
36243666
FALSE, (* local variables cannot be imported *)
@@ -3662,7 +3704,6 @@ BEGIN
36623704
scope := Mod2Gcc (GetProcedureScope (sym)) ;
36633705
Var := GetNth (sym, i) ;
36643706
WHILE Var # NulSym DO
3665-
Assert (AllDependantsFullyDeclared (GetSType (Var))) ;
36663707
DoVariableDeclaration (Var,
36673708
KeyToCharStar (GetFullSymName (Var)),
36683709
FALSE, (* inner module variables cannot be imported *)
@@ -6658,6 +6699,7 @@ END InitDeclarations ;
66586699
BEGIN
66596700
FreeGroup := NIL ;
66606701
GlobalGroup := InitGroup () ;
6702+
ErrorDepList := InitSet (1) ;
66616703
ChainedList := InitSet(1) ;
66626704
WatchList := InitSet(1) ;
66636705
VisitedList := NIL ;

gcc/m2/gm2-compiler/M2MetaError.mod

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,35 +1437,22 @@ BEGIN
14371437
doError (eb, GetDeclaredDef (sym))
14381438
ELSE
14391439
M2Error.EnterErrorScope (GetErrorScope (scope)) ;
1440-
IF IsProcedure (scope)
1440+
IF IsVar (sym) OR IsParameter (sym)
14411441
THEN
1442-
IF IsVar (sym) OR IsParameter (sym)
1443-
THEN
1444-
doError (eb, GetVarParamTok (sym))
1445-
ELSE
1446-
doError (eb, GetDeclaredDef (sym))
1447-
END
1442+
doError (eb, GetVarParamTok (sym))
1443+
ELSIF IsProcedure (scope)
1444+
THEN
1445+
doError (eb, GetDeclaredDef (sym))
1446+
ELSIF IsModule (scope)
1447+
THEN
1448+
doError (eb, GetDeclaredMod (sym))
14481449
ELSE
1449-
IF IsModule (scope)
1450+
Assert (IsDefImp (scope)) ;
1451+
IF GetDeclaredDefinition (sym) = UnknownTokenNo
14501452
THEN
1451-
IF IsInnerModule (scope)
1452-
THEN
1453-
doError (eb, GetDeclaredDef (sym))
1454-
ELSE
1455-
doError (eb, GetDeclaredDef (sym))
1456-
END
1453+
doError (eb, GetDeclaredMod (sym))
14571454
ELSE
1458-
Assert (IsDefImp (scope)) ;
1459-
(* if this fails then we need to skip to the outer scope.
1460-
REPEAT
1461-
OuterModule := GetScope(OuterModule)
1462-
UNTIL GetScope(OuterModule)=NulSym ; *)
1463-
IF GetDeclaredDefinition (sym) = UnknownTokenNo
1464-
THEN
1465-
doError (eb, GetDeclaredMod (sym))
1466-
ELSE
1467-
doError (eb, GetDeclaredDef (sym))
1468-
END
1455+
doError (eb, GetDeclaredDef (sym))
14691456
END
14701457
END
14711458
END ;

gcc/m2/gm2-compiler/P2SymBuild.mod

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,7 +1225,8 @@ VAR
12251225
Sym,
12261226
Type : CARDINAL ;
12271227
name : Name ;
1228-
tokno : CARDINAL ;
1228+
nametokno,
1229+
typetokno: CARDINAL ;
12291230
BEGIN
12301231
(*
12311232
Two cases
@@ -1234,8 +1235,8 @@ BEGIN
12341235
- when type with a name that is different to Name. In which case
12351236
we create a new type.
12361237
*)
1237-
PopTtok(Type, tokno) ;
1238-
PopT(name) ;
1238+
PopTtok (Type, typetokno) ;
1239+
PopTtok (name, nametokno) ;
12391240
IF Debugging
12401241
THEN
12411242
n1 := GetSymName(GetCurrentModule()) ;
@@ -1264,19 +1265,19 @@ BEGIN
12641265

12651266
*)
12661267
(* WriteString('Blank name type') ; WriteLn ; *)
1267-
PushTFtok(Type, name, tokno) ;
1268+
PushTFtok(Type, name, typetokno) ;
12681269
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
12691270
ELSIF IsError(Type)
12701271
THEN
1271-
PushTFtok(Type, name, tokno) ;
1272+
PushTFtok(Type, name, typetokno) ;
12721273
Annotate("%1s(%1d)|%2n|%3d||error type|error type name|token no")
12731274
ELSIF GetSymName(Type)=name
12741275
THEN
12751276
isunknown := IsUnknown(Type) ;
12761277
IF isunknown OR
12771278
(NOT IsDeclaredIn(GetCurrentScope(), Type))
12781279
THEN
1279-
Sym := MakeType(tokno, name) ;
1280+
Sym := MakeType (typetokno, name) ;
12801281
IF NOT IsError(Sym)
12811282
THEN
12821283
IF Sym=Type
@@ -1295,19 +1296,23 @@ BEGIN
12951296
CheckForEnumerationInCurrentModule(Type)
12961297
END
12971298
END ;
1298-
PushTFtok(Sym, name, tokno) ;
1299+
PushTFtok(Sym, name, typetokno) ;
12991300
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
13001301
ELSE
1301-
PushTFtok(Type, name, tokno) ;
1302+
PushTFtok(Type, name, typetokno) ;
13021303
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
13031304
END
13041305
ELSE
13051306
(* example TYPE a = CARDINAL *)
1306-
Sym := MakeType(tokno, name) ;
1307-
PutType(Sym, Type) ;
1308-
CheckForExportedImplementation(Sym) ; (* May be an exported hidden type *)
1309-
PushTFtok(Sym, name, tokno) ;
1310-
Annotate("%1s(%1d)|%2n|%3d||type|type name|token no")
1307+
Sym := MakeType (nametokno, name) ;
1308+
PutType (Sym, Type) ;
1309+
CheckForExportedImplementation (Sym) ; (* May be an exported hidden type *)
1310+
PushTFtok (Sym, name, nametokno) ;
1311+
Annotate ("%1s(%1d)|%2n|%3d||type|type name|token no") ;
1312+
IF Debugging
1313+
THEN
1314+
MetaErrorT1 (nametokno, 'type pos {%1Wa}', Sym)
1315+
END
13111316
END
13121317
END BuildType ;
13131318

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
MODULE badmodvar ;
2+
3+
VAR
4+
x: y ;
5+
BEGIN
6+
7+
END badmodvar.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
MODULE cyclictypes ;
2+
3+
TYPE
4+
A = B;
5+
B = A;
6+
7+
PROCEDURE foo ;
8+
VAR
9+
bar: A ;
10+
END foo ;
11+
12+
13+
END cyclictypes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MODULE cyclictypes2 ;
2+
3+
TYPE
4+
A = B;
5+
B = A;
6+
7+
VAR
8+
bar: A ;
9+
END cyclictypes2.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
MODULE cyclictypes4 ;
2+
3+
TYPE
4+
A = B ;
5+
B = C ;
6+
C = D ;
7+
D = A ;
8+
9+
VAR
10+
v: A ;
11+
BEGIN
12+
13+
END cyclictypes4.

0 commit comments

Comments
 (0)