]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR modula2/112946 ICE assignment of string to enumeration or set
authorGaius Mulley <gaiusmod2@gmail.com>
Fri, 15 Dec 2023 15:26:48 +0000 (15:26 +0000)
committerGaius Mulley <gaiusmod2@gmail.com>
Fri, 15 Dec 2023 15:26:48 +0000 (15:26 +0000)
This patch introduces type checking during FoldBecomes and also
adds set/string/enum checking to the type checker.  FoldBecomes
has been re-written, tidied up and re-factored.

gcc/m2/ChangeLog:

PR modula2/112946
* gm2-compiler/M2Check.mod (checkConstMeta): New procedure
function.
(checkConstEquivalence): New procedure function.
(doCheckPair): Add call to checkConstEquivalence.
* gm2-compiler/M2GenGCC.mod (ResolveConstantExpressions): Call
FoldBecomes with reduced parameters.
(FoldBecomes): Re-write.
(TryDeclareConst): New procedure.
(RemoveQuads): New procedure.
(DeclaredOperandsBecomes): New procedure function.
(TypeCheckBecomes): New procedure function.
(PerformFoldBecomes): New procedure.
* gm2-compiler/M2Range.mod (FoldAssignment): Call
AssignmentTypeCompatible to check des expr compatibility.
* gm2-compiler/M2SymInit.mod (CheckReadBeforeInitQuad): Remove
parameter lst.
(FilterCheckReadBeforeInitQuad): Remove parameter lst.
(CheckReadBeforeInitFirstBasicBlock): Remove parameter lst.
Call FilterCheckReadBeforeInitQuad without lst.

gcc/testsuite/ChangeLog:

PR modula2/112946
* gm2/iso/fail/badassignment.mod: New test.
* gm2/iso/fail/badexpression.mod: New test.
* gm2/iso/fail/badexpression2.mod: New test.

Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
gcc/m2/gm2-compiler/M2Check.mod
gcc/m2/gm2-compiler/M2GenGCC.mod
gcc/m2/gm2-compiler/M2Range.mod
gcc/m2/gm2-compiler/M2SymInit.mod
gcc/testsuite/gm2/iso/fail/badassignment.mod [new file with mode: 0644]
gcc/testsuite/gm2/iso/fail/badexpression.mod [new file with mode: 0644]
gcc/testsuite/gm2/iso/fail/badexpression2.mod [new file with mode: 0644]

index 9ef100e65409d0aca9bb7622bf23afc864f9d887..41ed5ad523893dc218400c0e35866987556b3e9c 100644 (file)
@@ -39,7 +39,7 @@ FROM M2Error IMPORT Error, InternalError, NewError, ErrorString, ChainError ;
 FROM M2MetaError IMPORT MetaErrorStringT2, MetaErrorStringT3, MetaErrorStringT4, MetaString2, MetaString3, MetaString4 ;
 FROM StrLib IMPORT StrEqual ;
 FROM M2Debug IMPORT Assert ;
-FROM SymbolTable IMPORT NulSym, IsRecord, IsSet, GetDType, GetSType, IsType, SkipType, IsProcedure, NoOfParam, IsVarParam, GetNth, GetNthParam, IsProcType, IsVar, IsEnumeration, IsArray, GetDeclaredMod, IsSubrange, GetArraySubscript, IsConst, IsReallyPointer, IsPointer, IsParameter, ModeOfAddr, GetMode, GetType, IsUnbounded, IsComposite, IsConstructor, IsParameter ;
+FROM SymbolTable IMPORT NulSym, IsRecord, IsSet, GetDType, GetSType, IsType, SkipType, IsProcedure, NoOfParam, IsVarParam, GetNth, GetNthParam, IsProcType, IsVar, IsEnumeration, IsArray, GetDeclaredMod, IsSubrange, GetArraySubscript, IsConst, IsReallyPointer, IsPointer, IsParameter, ModeOfAddr, GetMode, GetType, IsUnbounded, IsComposite, IsConstructor, IsParameter, IsConstString ;
 FROM M2GCCDeclare IMPORT GetTypeMin, GetTypeMax ;
 FROM M2System IMPORT Address ;
 FROM M2ALU IMPORT Equ, PushIntegerTree ;
@@ -503,7 +503,7 @@ END isLValue ;
 
 
 (*
-   checkVarEquivalence - this test must be done first as it checks the symbol mode.
+   checkVarEquivalence - this test must be done early as it checks the symbol mode.
                          An LValue is treated as a pointer during assignment and the
                          LValue is attached to a variable.  This function skips the variable
                          and checks the types - after it has considered a possible LValue.
@@ -547,6 +547,63 @@ BEGIN
 END checkVarEquivalence ;
 
 
+(*
+   checkConstMeta -
+*)
+
+PROCEDURE checkConstMeta  (result: status;
+                           left, right: CARDINAL) : status ;
+VAR
+   typeRight: CARDINAL ;
+BEGIN
+   Assert (IsConst (left)) ;
+   IF isFalse (result)
+   THEN
+      RETURN result
+   ELSIF IsConstString (left)
+   THEN
+      typeRight := GetDType (right) ;
+      IF typeRight = NulSym
+      THEN
+         RETURN result
+      ELSIF IsSet (typeRight) OR IsEnumeration (typeRight)
+      THEN
+         RETURN false
+      END
+   END ;
+   RETURN result
+END checkConstMeta ;
+
+
+(*
+   checkConstEquivalence - this check can be done first as it checks symbols which
+                           may have no type.  Ie constant strings.  These constants
+                           will likely have their type set during quadruple folding.
+                           But we can check the meta type for obvious mismatches
+                           early on.  For example adding a string to an enum or set.
+*)
+
+PROCEDURE checkConstEquivalence (result: status;
+                                 left, right: CARDINAL) : status ;
+BEGIN
+   IF isFalse (result)
+   THEN
+      RETURN result
+   ELSIF (left = NulSym) OR (right = NulSym)
+   THEN
+      (* No option but to return true.  *)
+      RETURN true
+   ELSIF IsConst (left)
+   THEN
+      RETURN checkConstMeta (result, left, right)
+   ELSIF IsConst (right)
+   THEN
+      RETURN checkConstMeta (result, right, left)
+   END ;
+   RETURN result
+END checkConstEquivalence ;
+
+
 (*
    checkSubrangeTypeEquivalence -
 *)
@@ -658,28 +715,32 @@ BEGIN
    THEN
       RETURN return (true, tinfo, left, right)
    ELSE
-      result := checkVarEquivalence (unknown, tinfo, left, right) ;
+      result := checkConstEquivalence (unknown, left, right) ;
       IF NOT isKnown (result)
       THEN
-         result := checkSystemEquivalence (unknown, left, right) ;
+         result := checkVarEquivalence (unknown, tinfo, left, right) ;
          IF NOT isKnown (result)
          THEN
-            result := checkSubrangeTypeEquivalence (unknown, tinfo, left, right) ;
+            result := checkSystemEquivalence (unknown, left, right) ;
             IF NOT isKnown (result)
             THEN
-               result := checkBaseTypeEquivalence (unknown, tinfo, left, right) ;
+               result := checkSubrangeTypeEquivalence (unknown, tinfo, left, right) ;
                IF NOT isKnown (result)
                THEN
-                  result := checkTypeEquivalence (unknown, left, right) ;
+                  result := checkBaseTypeEquivalence (unknown, tinfo, left, right) ;
                   IF NOT isKnown (result)
                   THEN
-                     result := checkArrayTypeEquivalence (result, tinfo, left, right) ;
+                     result := checkTypeEquivalence (unknown, left, right) ;
                      IF NOT isKnown (result)
                      THEN
-                        result := checkGenericTypeEquivalence (result, left, right) ;
+                        result := checkArrayTypeEquivalence (result, tinfo, left, right) ;
                         IF NOT isKnown (result)
                         THEN
-                           result := checkTypeKindEquivalence (result, tinfo, left, right)
+                           result := checkGenericTypeEquivalence (result, left, right) ;
+                           IF NOT isKnown (result)
+                           THEN
+                              result := checkTypeKindEquivalence (result, tinfo, left, right)
+                           END
                         END
                      END
                   END
@@ -949,7 +1010,7 @@ BEGIN
    THEN
       RETURN true
    ELSE
-      (* long cascade of all type kinds.  *)
+      (* Long cascade of all type kinds.  *)
       IF IsSet (left) AND IsSet (right)
       THEN
          RETURN checkSetEquivalent (result, tinfo, left, right)
index acbfe0c179d86dd4a180a7fe99ac9135bb5d1369..a4824bbe40ba1edd8f794edbf00b39533d63d082 100644 (file)
@@ -597,7 +597,7 @@ BEGIN
          LogicalOrOp        : FoldSetOr (tokenno, p, quad, op1, op2, op3) |
          LogicalAndOp       : FoldSetAnd (tokenno, p, quad, op1, op2, op3) |
          LogicalXorOp       : FoldSymmetricDifference (tokenno, p, quad, op1, op2, op3) |
-         BecomesOp          : FoldBecomes (tokenno, p, quad, op1, op3) |
+         BecomesOp          : FoldBecomes (p, quad) |
          ArithAddOp         : FoldArithAdd (op1pos, p, quad, op1, op2, op3) |
          AddOp              : FoldAdd (op1pos, p, quad, op1, op2, op3) |
          SubOp              : FoldSub (op1pos, p, quad, op1, op2, op3) |
@@ -2653,6 +2653,7 @@ BEGIN
    END
 END CheckStop ;
 
+
 (*
 ------------------------------------------------------------------------------
    := Operator
@@ -2660,96 +2661,205 @@ END CheckStop ;
    Sym1<I> := Sym3<I>           := produces a constant
 *)
 
-PROCEDURE FoldBecomes (tokenno: CARDINAL; p: WalkAction; quad: CARDINAL; op1, op3: CARDINAL) ;
+PROCEDURE FoldBecomes (p: WalkAction; quad: CARDINAL) ;
 VAR
-   location: location_t ;
+   op            : QuadOperator ;
+   des, op2, expr: CARDINAL ;
 BEGIN
-   TryDeclareConstant(tokenno, op3) ;  (* checks to see whether it is a constant literal and declares it *)
-   TryDeclareConstructor(tokenno, op3) ;
-   location := TokenToLocation(tokenno) ;
-   IF IsConst (op1) AND IsConstant (op3)
+   IF DeclaredOperandsBecomes (p, quad)
    THEN
-      (* constant folding taking place, but have we resolved op3 yet? *)
-      IF GccKnowsAbout (op3)
+      IF TypeCheckBecomes (p, quad)
       THEN
-         (* now we can tell gcc about the relationship between, op1 and op3 *)
-         (* RemoveSSAPlaceholder (quad, op1) ;  *)
-         IF GccKnowsAbout (op1)
+         PerformFoldBecomes (p, quad)
+      ELSE
+         GetQuad (quad, op, des, op2, expr) ;
+         RemoveQuad (p, des, quad)
+      END
+   END
+END FoldBecomes ;
+
+
+(*
+   TryDeclareConst -
+*)
+
+PROCEDURE TryDeclareConst (tokenno: CARDINAL; sym: CARDINAL) ;
+BEGIN
+   (* Check whether expr is a constant literal and if so declare it.  *)
+   TryDeclareConstant (tokenno, sym) ;
+   (* Check whether expr is a const constructor and if so declare it.  *)
+   TryDeclareConstructor (tokenno, sym)
+END TryDeclareConst ;
+
+
+(*
+   RemoveQuad - remove quad and ensure p (des) is called.
+*)
+
+PROCEDURE RemoveQuad (p: WalkAction; des: CARDINAL; quad: CARDINAL) ;
+BEGIN
+   p (des) ;
+   NoChange := FALSE ;
+   SubQuad (quad)
+END RemoveQuad ;
+
+
+(*
+   DeclaredOperandsBecomes -
+*)
+
+PROCEDURE DeclaredOperandsBecomes (p: WalkAction; quad: CARDINAL) : BOOLEAN ;
+VAR
+   des, op2, expr     : CARDINAL ;
+   overflowChecking   : BOOLEAN ;
+   despos, op2pos,
+   exprpos, becomespos: CARDINAL ;
+   op                 : QuadOperator ;
+BEGIN
+   GetQuadOtok (quad, becomespos, op,
+                des, op2, expr, overflowChecking,
+                despos, op2pos, exprpos) ;
+   Assert (op2pos = UnknownTokenNo) ;
+   TryDeclareConst (exprpos, expr) ;
+   IF IsConst (des) AND IsConstant (expr)
+   THEN
+      (* Constant folding taking place, but have we resolved op3 yet?  *)
+      IF GccKnowsAbout (expr)
+      THEN
+         (* Now we can tell gcc about the relationship between des and expr.  *)
+         (* RemoveSSAPlaceholder (quad, des) ;  *)
+         IF GccKnowsAbout (des)
          THEN
-            MetaErrorT1 (tokenno, 'constant {%1Ead} should not be reassigned', op1)
+            MetaErrorT1 (despos, 'constant {%1Ead} should not be reassigned', des) ;
+            RemoveQuad (p, des, quad) ;
+            RETURN FALSE
          ELSE
-            IF IsConstString(op3)
-            THEN
-               PutConstString(tokenno, op1, GetString(op3)) ;
-            ELSIF GetType(op1)=NulSym
-            THEN
-               Assert(GetType(op3)#NulSym) ;
-               PutConst(op1, GetType(op3))
-            END ;
-            IF GetType(op3)=NulSym
+            RETURN TRUE
+         END
+      END
+   END ;
+   RETURN FALSE
+END DeclaredOperandsBecomes ;
+
+
+(*
+   TypeCheckBecomes - returns TRUE if the type check succeeds.
+*)
+
+PROCEDURE TypeCheckBecomes (p: WalkAction; quad: CARDINAL) : BOOLEAN ;
+VAR
+   des, op2, expr     : CARDINAL ;
+   overflowChecking   : BOOLEAN ;
+   despos, op2pos,
+   exprpos, becomespos: CARDINAL ;
+   op                 : QuadOperator ;
+BEGIN
+   GetQuadOtok (quad, becomespos, op,
+                des, op2, expr, overflowChecking,
+                despos, op2pos, exprpos) ;
+   Assert (op2pos = UnknownTokenNo) ;
+   IF StrictTypeChecking AND
+      (NOT AssignmentTypeCompatible (despos, "", des, expr))
+   THEN
+      MetaErrorT2 (MakeVirtualTok (becomespos, despos, exprpos),
+                   'assignment check caught mismatch between {%1Ead} and {%2ad}',
+                   des, expr) ;
+      RemoveQuad (p, des, quad) ;
+      RETURN FALSE
+   END ;
+   RETURN TRUE
+END TypeCheckBecomes ;
+
+
+(*
+   PerformFoldBecomes -
+*)
+
+PROCEDURE PerformFoldBecomes (p: WalkAction; quad: CARDINAL) ;
+VAR
+   des, op2, expr     : CARDINAL ;
+   overflowChecking   : BOOLEAN ;
+   despos, op2pos,
+   exprpos, becomespos,
+   virtpos            : CARDINAL ;
+   op                 : QuadOperator ;
+   desloc, exprloc    : location_t ;
+BEGIN
+   GetQuadOtok (quad, becomespos, op,
+                des, op2, expr, overflowChecking,
+                despos, op2pos, exprpos) ;
+   Assert (op2pos = UnknownTokenNo) ;
+   IF IsConstString (expr)
+   THEN
+      PutConstString (exprpos, des, GetString (expr))
+   ELSIF GetType (des) = NulSym
+   THEN
+      Assert (GetType (expr) # NulSym) ;
+      PutConst (des, GetType (expr))
+   END ;
+   IF GetType (expr) = NulSym
+   THEN
+      CheckOrResetOverflow (exprpos, Mod2Gcc (expr), MustCheckOverflow (quad)) ;
+      AddModGcc (des, Mod2Gcc (expr))
+   ELSE
+      IF NOT GccKnowsAbout (GetType (des))
+      THEN
+         RETURN
+      END ;
+      IF IsProcedure (expr)
+      THEN
+         AddModGcc (des,
+                    BuildConvert (TokenToLocation (exprpos),
+                                  Mod2Gcc (GetType (des)),
+                                  BuildAddr (TokenToLocation (exprpos),
+                                             Mod2Gcc (expr), FALSE), TRUE))
+      ELSIF IsValueSolved (expr)
+      THEN
+         PushValue (expr) ;
+         IF IsValueTypeReal ()
+         THEN
+            CheckOrResetOverflow (exprpos, PopRealTree (), MustCheckOverflow (quad)) ;
+            PushValue (expr) ;
+            AddModGcc (des, PopRealTree ())
+         ELSIF IsValueTypeSet ()
+         THEN
+            PopValue (des) ;
+            PutConstSet (des)
+         ELSIF IsValueTypeConstructor () OR IsValueTypeArray () OR IsValueTypeRecord ()
+         THEN
+            PopValue (des) ;
+            PutConstructor (des)
+         ELSIF IsValueTypeComplex ()
+         THEN
+            CheckOrResetOverflow (exprpos, PopComplexTree (), MustCheckOverflow (quad)) ;
+            PushValue (expr) ;
+            PopValue (des)
+         ELSE
+            CheckOrResetOverflow (exprpos, PopIntegerTree (), MustCheckOverflow (quad)) ;
+            IF GetType (des) = NulSym
             THEN
-               CheckOrResetOverflow(tokenno, Mod2Gcc(op3), MustCheckOverflow(quad)) ;
-               AddModGcc(op1, Mod2Gcc(op3))
+               PushValue (expr) ;
+               AddModGcc (des, PopIntegerTree ())
             ELSE
-               IF NOT GccKnowsAbout(GetType(op1))
-               THEN
-                  RETURN
-               END ;
-               IF IsProcedure(op3)
-               THEN
-                  AddModGcc(op1,
-                            BuildConvert(location,
-                                         Mod2Gcc(GetType(op1)), BuildAddr(location, Mod2Gcc(op3), FALSE), TRUE))
-               ELSIF IsValueSolved(op3)
-               THEN
-                  PushValue(op3) ;
-                  IF IsValueTypeReal()
-                  THEN
-                     CheckOrResetOverflow(tokenno, PopRealTree(), MustCheckOverflow(quad)) ;
-                     PushValue(op3) ;
-                     AddModGcc(op1, PopRealTree())
-                  ELSIF IsValueTypeSet()
-                  THEN
-                     PopValue(op1) ;
-                     PutConstSet(op1)
-                  ELSIF IsValueTypeConstructor() OR IsValueTypeArray() OR IsValueTypeRecord()
-                  THEN
-                     PopValue(op1) ;
-                     PutConstructor(op1)
-                  ELSIF IsValueTypeComplex()
-                  THEN
-                     CheckOrResetOverflow(tokenno, PopComplexTree(), MustCheckOverflow(quad)) ;
-                     PushValue(op3) ;
-                     PopValue(op1)
-                  ELSE
-                     CheckOrResetOverflow(tokenno, PopIntegerTree(), MustCheckOverflow(quad)) ;
-                     IF GetType(op1)=NulSym
-                     THEN
-                        PushValue(op3) ;
-                        AddModGcc(op1, PopIntegerTree())
-                     ELSE
-                        PushValue(op3) ;
-                        AddModGcc(op1, BuildConvert(location, Mod2Gcc(GetType(op1)), PopIntegerTree(), FALSE))
-                     END
-                  END
-               ELSE
-                  CheckOrResetOverflow(tokenno, Mod2Gcc(op3), MustCheckOverflow(quad)) ;
-                  AddModGcc(op1,
-                            DeclareKnownConstant(location,
-                                                 Mod2Gcc(GetType(op3)),
-                                                 Mod2Gcc(op3)))
-               END
-            END ;
-            p (op1) ;
-            NoChange := FALSE ;
-            SubQuad(quad) ;
-            Assert (RememberConstant(Mod2Gcc (op1)) = Mod2Gcc (op1))
+               virtpos := MakeVirtualTok (becomespos, despos, exprpos) ;
+               PushValue (expr) ;
+               AddModGcc (des, BuildConvert (TokenToLocation (virtpos),
+                                             Mod2Gcc (GetType (des)), PopIntegerTree (), FALSE))
+            END
          END
       ELSE
-         (* not to worry, we must wait until op3 is known *)
+         virtpos := MakeVirtualTok (becomespos, despos, exprpos) ;
+         CheckOrResetOverflow (exprpos, Mod2Gcc (des), MustCheckOverflow (quad)) ;
+         AddModGcc (des,
+                    DeclareKnownConstant (TokenToLocation (virtpos),
+                                          Mod2Gcc (GetType (expr)),
+                                          Mod2Gcc (expr)))
       END
-   END
-END FoldBecomes ;
+   END ;
+   RemoveQuad (p, des, quad) ;
+   Assert (RememberConstant(Mod2Gcc (des)) = Mod2Gcc (des))
+END PerformFoldBecomes ;
+
 
 VAR
    tryBlock: Tree ;    (* this must be placed into gccgm2 and it must follow the
index 543c2784d3d32e562695fc0d88312761f560ad6c..90ad1577ff8a40c84fb668d8172b9ce64fca2bc9 100644 (file)
@@ -82,7 +82,7 @@ FROM M2GenGCC IMPORT GetHighFromUnbounded, StringToChar, LValueToGenericPtr, ZCo
 FROM M2System IMPORT Address, Word, Loc, Byte, IsWordN, IsRealN, IsComplexN ;
 FROM FormatStrings IMPORT Sprintf0, Sprintf1, Sprintf2 ;
 
-FROM M2Check IMPORT ParameterTypeCompatible, ExpressionTypeCompatible ;
+FROM M2Check IMPORT ParameterTypeCompatible, ExpressionTypeCompatible, AssignmentTypeCompatible ;
 
 FROM M2Base IMPORT Nil, IsRealType, GetBaseTypeMinMax,
                    Cardinal, Integer, ZType, IsComplexType,
@@ -1141,18 +1141,23 @@ BEGIN
       TryDeclareConstant (tokenNo, expr) ;
       IF desLowestType # NulSym
       THEN
-         IF GccKnowsAbout (expr) AND IsConst (expr) AND
-            GetMinMax (tokenno, desLowestType, min, max)
+         IF AssignmentTypeCompatible (tokenno, "", des, expr)
          THEN
-            IF OutOfRange (tokenno, min, expr, max, desLowestType)
+            IF GccKnowsAbout (expr) AND IsConst (expr) AND
+               GetMinMax (tokenno, desLowestType, min, max)
             THEN
-               MetaErrorT2 (tokenNo,
-                            'attempting to assign a value {%2Wa} to a designator {%1a} which will exceed the range of type {%1tad}',
-                            des, expr) ;
-               PutQuad (q, ErrorOp, NulSym, NulSym, r)
-            ELSE
-               SubQuad (q)
+               IF OutOfRange (tokenno, min, expr, max, desLowestType)
+               THEN
+                  MetaErrorT2 (tokenNo,
+                               'attempting to assign a value {%2Wa} to a designator {%1a} which will exceed the range of type {%1tad}',
+                               des, expr) ;
+                  PutQuad (q, ErrorOp, NulSym, NulSym, r)
+               ELSE
+                  SubQuad (q)
+               END
             END
+         ELSE
+            SubQuad (q)
          END
       END
    END
index 47026a87555abe9a37cf0d9218a44a553b283a64..f16993544e195d59076fc3bc43ae40ba1ec35aa3 100644 (file)
@@ -1244,7 +1244,7 @@ END stop ;
 *)
 
 PROCEDURE CheckReadBeforeInitQuad (procSym: CARDINAL; quad: CARDINAL;
-                                   warning: BOOLEAN; lst: List; i: CARDINAL) : BOOLEAN ;
+                                   warning: BOOLEAN; i: CARDINAL) : BOOLEAN ;
 VAR
    op                          : QuadOperator ;
    op1, op2, op3               : CARDINAL ;
@@ -1382,7 +1382,7 @@ END CheckReadBeforeInitQuad ;
 
 PROCEDURE FilterCheckReadBeforeInitQuad (procSym: CARDINAL; start: CARDINAL;
                                          warning: BOOLEAN;
-                                         lst: List; i: CARDINAL) : BOOLEAN ;
+                                         i: CARDINAL) : BOOLEAN ;
 VAR
    Op           : QuadOperator ;
    Op1, Op2, Op3: CARDINAL ;
@@ -1390,7 +1390,7 @@ BEGIN
    GetQuad (start, Op, Op1, Op2, Op3) ;
    IF (Op # RangeCheckOp) AND (Op # StatementNoteOp)
    THEN
-      RETURN CheckReadBeforeInitQuad (procSym, start, warning, lst, i)
+      RETURN CheckReadBeforeInitQuad (procSym, start, warning, i)
    END ;
    RETURN FALSE
 END FilterCheckReadBeforeInitQuad ;
@@ -1403,10 +1403,10 @@ END FilterCheckReadBeforeInitQuad ;
 PROCEDURE CheckReadBeforeInitFirstBasicBlock (procSym: CARDINAL;
                                               start, end: CARDINAL;
                                               warning: BOOLEAN;
-                                              lst: List; i: CARDINAL) ;
+                                              i: CARDINAL) ;
 BEGIN
    LOOP
-      IF FilterCheckReadBeforeInitQuad (procSym, start, warning, lst, i)
+      IF FilterCheckReadBeforeInitQuad (procSym, start, warning, i)
       THEN
       END ;
       IF start = end
@@ -1630,7 +1630,7 @@ BEGIN
       bbPtr := Indexing.GetIndice (bbArray, bbi) ;
       CheckReadBeforeInitFirstBasicBlock (procSym,
                                           bbPtr^.start, bbPtr^.end,
-                                          warning, lst, i) ;
+                                          warning, i) ;
       IF bbPtr^.endCond
       THEN
          (* Check to see if we are moving into an conditional block in which case
diff --git a/gcc/testsuite/gm2/iso/fail/badassignment.mod b/gcc/testsuite/gm2/iso/fail/badassignment.mod
new file mode 100644 (file)
index 0000000..9dc0d92
--- /dev/null
@@ -0,0 +1,14 @@
+MODULE badassignment ;
+
+TYPE
+   enums = (red, blue, green) ;
+   set = SET OF enums ;
+VAR
+   setvar : set;
+   enumvar: enums;
+BEGIN
+   enumvar := 'a';
+   enumvar := 'ab';
+   setvar := 'a';
+   setvar := 'ab';
+END badassignment.
\ No newline at end of file
diff --git a/gcc/testsuite/gm2/iso/fail/badexpression.mod b/gcc/testsuite/gm2/iso/fail/badexpression.mod
new file mode 100644 (file)
index 0000000..967d405
--- /dev/null
@@ -0,0 +1,14 @@
+MODULE badexpression ;
+
+TYPE
+   enums = (red, blue, green) ;
+   set = SET OF enums ;
+VAR
+   setvar : set;
+   enumvar: enums;
+BEGIN
+   enumvar := 'a';
+   enumvar := 'ab';
+   setvar := set {} ;
+   setvar := setvar + "hello"
+END badexpression.
diff --git a/gcc/testsuite/gm2/iso/fail/badexpression2.mod b/gcc/testsuite/gm2/iso/fail/badexpression2.mod
new file mode 100644 (file)
index 0000000..7514895
--- /dev/null
@@ -0,0 +1,13 @@
+MODULE badexpression2 ;
+
+TYPE
+   enums = (red, blue, green) ;
+   set = SET OF enums ;
+VAR
+   setvar : set;
+   enumvar: enums;
+BEGIN
+   enumvar := 'ab';
+   setvar := set {} ;
+   setvar := setvar + "hello"
+END badexpression2.