public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-7653] modula2: Variable analysis understands DISPOSE and NIL
@ 2023-07-30 11:35 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2023-07-30 11:35 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:97e97b76f0b76842bc0f0ee90ca54c5d16e5baf7

commit r13-7653-g97e97b76f0b76842bc0f0ee90ca54c5d16e5baf7
Author: Gaius Mulley <gaiusmod2@gmail.com>
Date:   Sun Jul 30 12:34:38 2023 +0100

    modula2: Variable analysis understands DISPOSE and NIL
    
    This patch allows the uninitialized variable analysis to detect pointer
    through NIL and incorrectly reusing a pointer after a call to DISPOSE.
    
    gcc/m2/ChangeLog:
    
            * gm2-compiler/M2Quads.mod (BuildRealFuncProcCall): Set the trash
            parameter value to NIL if DEALLOCATE is detected.
            * gm2-compiler/M2SymInit.mod (CheckDeferredRecordAccess): Pass
            tok to SetVarInitialized.  Pass tok to GetVarComponentInitialized.
            (ComponentFindVar): Add tok parameter.  Check aliased pointer
            against Nil and generate warning if necessary.
            (deRefComponent): Add tok and sym parameters and pass them to
            getContent.
            (SetVarComponentInitialized): Add tok parameter.  Pass tok to
            ComponentFindVar.  Pass tok and sym to deRefComponent.
            (GetVarComponentInitialized): Add tok parameter.  Pass tok to
            ComponentFindVar.  Pass tok to deRefComponent.
            (SetVarInitialized): Add tok parameter.  Pass tok to
            SetVarComponentInitialized.
            (doGetVarInitialized): Add tok parameter.  Pass tok to
            GetVarComponentInitialized.
            (CheckXIndr): Pass lhs and lhstok to getContent.
            (CheckIndrX): Pass rhs and rhstok to getContent.
            (CheckBecomes): Pass destok to ComponentFindVar.  Pass des and
            destok to deRefComponent.
            (CheckAddr): Pass contenttok to GetVarInitialized.  Pass ptrtok
            to SetVarInitialized.
            (CheckReadBeforeInitQuad): Pass op1tok to SetVarInitialized for
            op1 cases and op3tok for op3 cases.
            (trashParam): Get operand tokens.  Pass op3tok to
            SetVarInitialized.  Pass op3 and op3tok to getContent.
            Alias ptr to NIL if procedure is DEALLOCATE.  Pass op3tok to
            SetVarInitialized.
            (IsDeallocate): New procedure function.
            (DetectTrash): Use IsDeallocate.
            (SetupLAlias): Allow exp to be Nil.
            (getContent): Generate warning message if ptr is Nil.
    
    gcc/testsuite/ChangeLog:
    
            * gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod: New test.
            * gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod: New test.
            * gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod: New test.
    
    (cherry picked from commit e029635cb72e6db72f1826b6b43fa4b299b2145f)
    
    Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>

Diff:
---
 gcc/m2/gm2-compiler/M2Quads.mod                    |  12 +-
 gcc/m2/gm2-compiler/M2SymInit.mod                  | 145 +++++++++++++--------
 .../procedures/fail/testdispose.mod                |  24 ++++
 .../procedures/fail/testdispose2.mod               |  24 ++++
 .../procedures/fail/testnil.mod                    |  17 +++
 5 files changed, 163 insertions(+), 59 deletions(-)

diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index db5513d6787..3e4863b3baf 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -5269,9 +5269,15 @@ BEGIN
          THEN
             GenQuadO (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE)
          ELSE
-            trash := MakeTemporary (paramtok, RightValue) ;
-            PutVar (trash, ParamType) ;
-            PutVarHeap (trash, TRUE) ;
+            IF AllocateProc
+            THEN
+               trash := MakeTemporary (paramtok, RightValue) ;
+               PutVar (trash, ParamType) ;
+               PutVarHeap (trash, TRUE)
+            ELSE
+               Assert (DeallocateProc) ;
+               trash := Nil
+            END ;
             GenQuadOTrash (paramtok, ParamOp, i, Proc, OperandT (pi), TRUE, trash)
          END
       ELSE
diff --git a/gcc/m2/gm2-compiler/M2SymInit.mod b/gcc/m2/gm2-compiler/M2SymInit.mod
index f617c40d1d0..b7978e55ef2 100644
--- a/gcc/m2/gm2-compiler/M2SymInit.mod
+++ b/gcc/m2/gm2-compiler/M2SymInit.mod
@@ -26,6 +26,7 @@ FROM M2Debug IMPORT Assert ;
 FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ;
 FROM libc IMPORT printf ;
 FROM NameKey IMPORT Name, NulName, KeyToCharStar, MakeKey ;
+FROM M2Base IMPORT Nil ;
 
 FROM M2Options IMPORT UninitVariableChecking, UninitVariableConditionalChecking,
                       CompilerDebugging ;
@@ -693,11 +694,11 @@ BEGIN
          (* SetVarInitialized (sym, TRUE) *)
       ELSIF IsUnbounded (GetSType (sym))
       THEN
-         SetVarInitialized (sym, TRUE)
+         SetVarInitialized (sym, TRUE, tok)
       ELSIF IsComponent (sym)
       THEN
          Trace ("checkReadInit IsComponent (%d) is true)", sym) ;
-         IF (NOT GetVarComponentInitialized (sym)) AND IsUniqueWarning (tok)
+         IF (NOT GetVarComponentInitialized (sym, tok)) AND IsUniqueWarning (tok)
          THEN
             GenerateNoteFlow (lst, i, warning) ;
             IssueWarning (tok,
@@ -766,7 +767,9 @@ END SetVarUninitialized ;
    ComponentFindVar -
 *)
 
-PROCEDURE ComponentFindVar (sym: CARDINAL; VAR lvalue: BOOLEAN) : CARDINAL ;
+PROCEDURE ComponentFindVar (sym: CARDINAL;
+                            VAR lvalue: BOOLEAN;
+                            tok: CARDINAL) : CARDINAL ;
 VAR
    nsym,
    i   : CARDINAL ;
@@ -776,11 +779,17 @@ BEGIN
       nsym := GetNth (sym, i) ;
       lvalue := GetMode (nsym) = LeftValue ;
       nsym := getLAlias (nsym) ;
-      IF (nsym # NulSym) AND IsVar (nsym)
+      IF nsym = Nil
+      THEN
+         MetaErrorT1 (tok,
+                      "attempting to dereference {%1Wad} which will be a {%kNIL} pointer",
+                      sym) ;
+         RETURN NulSym
+      ELSIF (nsym # NulSym) AND IsVar (nsym)
       THEN
          IF (nsym # sym) AND IsComponent (nsym)
          THEN
-            RETURN ComponentFindVar (nsym, lvalue)
+            RETURN ComponentFindVar (nsym, lvalue, tok)
          ELSE
             RETURN nsym
          END
@@ -846,11 +855,12 @@ END ComponentBuildFieldList ;
    deRefComponent -
 *)
 
-PROCEDURE deRefComponent (component: CARDINAL; lvalue: BOOLEAN) : CARDINAL ;
+PROCEDURE deRefComponent (component: CARDINAL; lvalue: BOOLEAN;
+                          sym: CARDINAL; tok: CARDINAL) : CARDINAL ;
 BEGIN
    IF lvalue
    THEN
-      RETURN getContent (component)
+      RETURN getContent (component, sym, tok)
    ELSE
       RETURN component
    END
@@ -861,7 +871,7 @@ END deRefComponent ;
    SetVarComponentInitialized -
 *)
 
-PROCEDURE SetVarComponentInitialized (sym: CARDINAL) ;
+PROCEDURE SetVarComponentInitialized (sym: CARDINAL; tok: CARDINAL) ;
 VAR
    lvalue: BOOLEAN ;
    i, n,
@@ -869,8 +879,8 @@ VAR
    vsym  : CARDINAL ;
    lst   : List ;
 BEGIN
-   vsym := ComponentFindVar (sym, lvalue) ;
-   vsym := deRefComponent (vsym, lvalue) ;
+   vsym := ComponentFindVar (sym, lvalue, tok) ;
+   vsym := deRefComponent (vsym, lvalue, sym, tok) ;
    IF vsym # NulSym
    THEN
       IF Debugging
@@ -911,7 +921,7 @@ END SetVarComponentInitialized ;
    GetVarComponentInitialized -
 *)
 
-PROCEDURE GetVarComponentInitialized (sym: CARDINAL) : BOOLEAN ;
+PROCEDURE GetVarComponentInitialized (sym: CARDINAL; tok: CARDINAL) : BOOLEAN ;
 VAR
    lvalue,
    init     : BOOLEAN ;
@@ -919,13 +929,13 @@ VAR
    vsym     : CARDINAL ;
    lst      : List ;
 BEGIN
-   component := ComponentFindVar (sym, lvalue) ;
+   component := ComponentFindVar (sym, lvalue, tok) ;
    IF IsItemInList (ignoreList, component) OR IsExempt (component)
    THEN
       RETURN TRUE
    ELSE
       init := FALSE ;
-      vsym := deRefComponent (component, lvalue) ;
+      vsym := deRefComponent (component, lvalue, sym, tok) ;
       IF vsym # NulSym
       THEN
          IF IsExempt (vsym)
@@ -963,7 +973,8 @@ END Trace ;
                        then set the left and right initialization state.
 *)
 
-PROCEDURE SetVarInitialized (sym: CARDINAL; canDereference: BOOLEAN) ;
+PROCEDURE SetVarInitialized (sym: CARDINAL; canDereference: BOOLEAN;
+                             tok: CARDINAL) ;
 BEGIN
    IF IsVar (sym)
    THEN
@@ -971,7 +982,7 @@ BEGIN
       IF IsComponent (sym)
       THEN
          Trace ("SetVarInitialized sym %d is a component and calling SetVarComponentInitialized", sym);
-         SetVarComponentInitialized (sym)
+         SetVarComponentInitialized (sym, tok)
       ELSIF (GetMode (sym) = LeftValue) AND canDereference
       THEN
          Trace ("SetVarInitialized sym %d is LeftValue and canDeference and calling PutVarInitialized LeftValue and RightValue", sym);
@@ -993,7 +1004,7 @@ END SetVarInitialized ;
    doGetVarInitialized -
 *)
 
-PROCEDURE doGetVarInitialized (sym: CARDINAL) : BOOLEAN ;
+PROCEDURE doGetVarInitialized (sym: CARDINAL; tok: CARDINAL) : BOOLEAN ;
 BEGIN
    IF IsVar (sym)
    THEN
@@ -1002,7 +1013,7 @@ BEGIN
          RETURN TRUE
       ELSIF IsComponent (sym)
       THEN
-         RETURN GetVarComponentInitialized (sym)
+         RETURN GetVarComponentInitialized (sym, tok)
       END ;
       RETURN VarCheckReadInit (sym, GetMode (sym))
    END ;
@@ -1014,11 +1025,11 @@ END doGetVarInitialized ;
    GetVarInitialized -
 *)
 
-PROCEDURE GetVarInitialized (sym: CARDINAL) : BOOLEAN ;
+PROCEDURE GetVarInitialized (sym: CARDINAL; tok: CARDINAL) : BOOLEAN ;
 VAR
    init: BOOLEAN ;
 BEGIN
-   init := doGetVarInitialized (sym) ;
+   init := doGetVarInitialized (sym, tok) ;
    IF Debugging
    THEN
       IF init
@@ -1061,7 +1072,7 @@ PROCEDURE CheckBinary (procSym,
 BEGIN
    CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) ;
    CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ;
-   SetVarInitialized (op1, FALSE)
+   SetVarInitialized (op1, FALSE, op1tok)
 END CheckBinary ;
 
 
@@ -1075,7 +1086,7 @@ PROCEDURE CheckUnary (procSym,
                       lst: List; i: CARDINAL) ;
 BEGIN
    CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ;
-   SetVarInitialized (lhs, FALSE)
+   SetVarInitialized (lhs, FALSE, lhstok)
 END CheckUnary ;
 
 
@@ -1093,13 +1104,13 @@ BEGIN
    CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, bblst, i) ;
    CheckDeferredRecordAccess (procSym, lhstok, lhs, FALSE, warning, bblst, i) ;
    (* Now see if we know what lhs is pointing to and set fields if necessary.  *)
-   vsym := getContent (getLAlias (lhs)) ;
+   vsym := getContent (getLAlias (lhs), lhs, lhstok) ;
    IF (vsym # NulSym) AND (vsym # lhs) AND (GetSType (vsym) = type)
    THEN
       IF IsRecord (type)
       THEN
          (* Set all fields of vsym as initialized.  *)
-         SetVarInitialized (vsym, FALSE)
+         SetVarInitialized (vsym, FALSE, lhstok)
       ELSE
          (* Set only the field assigned in vsym as initialized.  *)
          lst := ComponentCreateFieldList (rhs) ;
@@ -1123,7 +1134,7 @@ VAR
    content: CARDINAL ;
 BEGIN
    CheckDeferredRecordAccess (procSym, rhstok, rhs, FALSE, warning, lst, i) ;
-   content := getContent (getLAlias (rhs)) ;
+   content := getContent (getLAlias (rhs), rhs, rhstok) ;
    IF content = NulSym
    THEN
       IncludeItemIntoList (ignoreList, lhs)
@@ -1131,7 +1142,7 @@ BEGIN
       CheckDeferredRecordAccess (procSym, rhstok, content, TRUE, warning, lst, i) ;
       (* SetVarInitialized (lhs, IsVarAParam (rhs))  -- was --  *)
       (* SetVarInitialized (lhs, FALSE) -- was -- *)
-      SetVarInitialized (lhs, VarCheckReadInit (content, RightValue))
+      SetVarInitialized (lhs, VarCheckReadInit (content, RightValue), lhstok)
    END
 END CheckIndrX ;
 
@@ -1159,12 +1170,12 @@ VAR
 BEGIN
    CheckDeferredRecordAccess (procSym, exprtok, expr, FALSE, warning, bblst, i) ;
    SetupLAlias (des, expr) ;
-   SetVarInitialized (des, FALSE) ;
+   SetVarInitialized (des, FALSE, destok) ;
    (* Now see if we know what lhs is pointing to and set fields if necessary.  *)
    IF IsComponent (des)
    THEN
-      vsym := ComponentFindVar (des, lvalue) ;
-      vsym := deRefComponent (vsym, lvalue) ;
+      vsym := ComponentFindVar (des, lvalue, destok) ;
+      vsym := deRefComponent (vsym, lvalue, des, destok) ;
       IF vsym # NulSym
       THEN
          (* Set only the field assigned in vsym as initialized.  *)
@@ -1196,7 +1207,7 @@ END CheckComparison ;
 
 PROCEDURE CheckAddr (procSym, ptrtok, ptr, contenttok, content: CARDINAL) ;
 BEGIN
-   SetVarInitialized (ptr, GetVarInitialized (content)) ;
+   SetVarInitialized (ptr, GetVarInitialized (content, contenttok), ptrtok) ;
    SetupIndr (ptr, content)
 END CheckAddr ;
 
@@ -1281,19 +1292,19 @@ BEGIN
    FunctValueOp,
    StandardFunctionOp,
    HighOp,
-   SizeOp            : SetVarInitialized (op1, FALSE) |
+   SizeOp            : SetVarInitialized (op1, FALSE, op1tok) |
    AddrOp            : CheckAddr (procSym, op1tok, op1, op3tok, op3) |
-   ReturnValueOp     : SetVarInitialized (op1, FALSE) |
+   ReturnValueOp     : SetVarInitialized (op1, FALSE, op1tok) |
    NewLocalVarOp     : |
    ParamOp           : CheckDeferredRecordAccess (procSym, op2tok, op2, FALSE, warning, lst, i) ;
                        CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ;
                        IF (op1 > 0) AND (op1 <= NoOfParam (op2)) AND
                           IsVarParam (op2, op1)
                        THEN
-                          SetVarInitialized (op3, TRUE)
+                          SetVarInitialized (op3, TRUE, op3tok)
                        END |
    ArrayOp           : CheckDeferredRecordAccess (procSym, op3tok, op3, FALSE, warning, lst, i) ;
-                       SetVarInitialized (op1, TRUE) |
+                       SetVarInitialized (op1, TRUE, op1tok) |
    RecordFieldOp     : CheckRecordField (procSym, op1tok, op1, op2tok, op2) |
    LogicalShiftOp,
    LogicalRotateOp,
@@ -1318,7 +1329,7 @@ BEGIN
                                     op1tok, op1, op2tok, op2, op3tok, op3, warning, lst, i) |
    XIndrOp           : CheckXIndr (procSym, op1tok, op1, op2, op3tok, op3, warning, lst, i) |
    IndrXOp           : CheckIndrX (procSym, op1tok, op1, op2, op3tok, op3, warning, lst, i) |
-   SaveExceptionOp   : SetVarInitialized (op1, FALSE) |
+   SaveExceptionOp   : SetVarInitialized (op1, FALSE, op1tok) |
    RestoreExceptionOp: CheckDeferredRecordAccess (procSym, op1tok, op1, FALSE, warning, lst, i) |
 
    SubrangeLowOp,
@@ -1516,13 +1527,16 @@ END DumpBBSequence ;
 
 PROCEDURE trashParam (trashQuad: CARDINAL) ;
 VAR
-   op           : QuadOperator ;
-   op1, op2, op3: CARDINAL ;
-   heapSym, ptr : CARDINAL ;
+   op                          : QuadOperator ;
+   op1, op2, op3               : CARDINAL ;
+   op1tok, op2tok, op3tok, qtok: CARDINAL ;
+   overflowChecking            : BOOLEAN ;
+   heapSym, ptr                : CARDINAL ;
 BEGIN
    IF trashQuad # 0
    THEN
-      GetQuad (trashQuad, op, op1, op2, op3) ;
+      GetQuadOtok (trashQuad, qtok, op, op1, op2, op3, overflowChecking,
+                   op1tok, op2tok, op3tok) ;
       heapSym := GetQuadTrash (trashQuad) ;
       IF Debugging
       THEN
@@ -1530,21 +1544,20 @@ BEGIN
       END ;
       IF heapSym # NulSym
       THEN
-         SetVarInitialized (op3, FALSE) ;
-         ptr := getContent (getLAlias (op3)) ;
+         SetVarInitialized (op3, FALSE, op3tok) ;
+         ptr := getContent (getLAlias (op3), op3, op3tok) ;
          IF ptr # NulSym
          THEN
-            SetupIndr (ptr, heapSym) ;
-            SetVarInitialized (ptr, FALSE)
+            IF IsDeallocate (op2)
+            THEN
+               (* SetupLAlias (ptr, heapSym) *)
+               (* SetupIndr (ptr, Nil) *)
+               SetupLAlias (ptr, Nil)
+            ELSE
+               SetupIndr (ptr, heapSym)
+            END ;
+            SetVarInitialized (ptr, FALSE, op3tok)
          END
-(*
-         vsym := getLAlias (op3) ;
-         VarInitState (vsym) ;
-         VarInitState (heapSym) ;
-         PutVarInitialized (vsym, GetMode (vsym)) ;
-         PutVarInitialized (heapSym, LeftValue) ;
-         SetupLAlias (vsym, heapSym)
-*)
       END
    END ;
    DumpAliases
@@ -1788,6 +1801,16 @@ BEGIN
 END IsAllocate ;
 
 
+(*
+   IsDeallocate - return TRUE is sym is DEALLOCATE.
+*)
+
+PROCEDURE IsDeallocate (sym: CARDINAL) : BOOLEAN ;
+BEGIN
+   RETURN IsProcedure (sym) AND (GetSymName (sym) = MakeKey('DEALLOCATE'))
+END IsDeallocate ;
+
+
 (*
    DetectTrash -
 *)
@@ -1803,7 +1826,7 @@ BEGIN
       i := bbPtr^.start ;
       LOOP
          GetQuad (i, op, op1, op2, op3) ;
-         IF (op = ParamOp) AND (op1 = 1) AND IsAllocate (op2)
+         IF (op = ParamOp) AND (op1 = 1) AND (IsAllocate (op2) OR IsDeallocate (op2))
          THEN
             bbPtr^.trashQuad := i
          END ;
@@ -2078,8 +2101,9 @@ END getLAlias ;
 
 PROCEDURE SetupLAlias (des, exp: CARDINAL) ;
 BEGIN
-   IF IsVar (exp) AND
-      ((GetMode (des) = LeftValue) OR IsReallyPointer (GetSType (des)))
+   IF (exp = Nil) OR
+      (IsVar (exp) AND
+       ((GetMode (des) = LeftValue) OR IsReallyPointer (GetSType (des))))
    THEN
       addAlias (LArray, des, exp) ;
       DumpAliases
@@ -2098,12 +2122,21 @@ END SetupIndr ;
 
 
 (*
-   getContent -
+   getContent - attempts to return the content pointed to by ptr.
+                sym is the original symbol and ptr will be the equivalent lvalue.
 *)
 
-PROCEDURE getContent (ptr: CARDINAL) : CARDINAL ;
+PROCEDURE getContent (ptr: CARDINAL; sym: CARDINAL; tok: CARDINAL) : CARDINAL ;
 BEGIN
-   RETURN doGetAlias (IndirectArray, ptr)
+   IF ptr = Nil
+   THEN
+      MetaErrorT1 (tok,
+                   "attempting to dereference {%1Wad} which will be a {%kNIL} pointer",
+                   sym) ;
+      RETURN NulSym
+   ELSE
+      RETURN doGetAlias (IndirectArray, ptr)
+   END
 END getContent ;
 
 
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod
new file mode 100644
index 00000000000..366de7d9559
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose.mod
@@ -0,0 +1,24 @@
+MODULE testdispose ;
+
+FROM Storage IMPORT DEALLOCATE ;
+
+TYPE
+   PtrToVec = POINTER TO RECORD
+                            x, y: INTEGER ;
+                         END ;
+
+
+PROCEDURE test ;
+VAR
+   ptr: PtrToVec ;
+BEGIN
+   DISPOSE (ptr) ;
+   IF ptr^.x = 1
+   THEN
+   END
+END test ;
+
+
+BEGIN
+   test
+END testdispose.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod
new file mode 100644
index 00000000000..e4e555cf0ff
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testdispose2.mod
@@ -0,0 +1,24 @@
+MODULE testdispose2 ;
+
+FROM Storage IMPORT DEALLOCATE ;
+
+TYPE
+   PtrToVec = POINTER TO RECORD
+                            x, y: INTEGER ;
+                         END ;
+
+
+PROCEDURE test (ptr: PtrToVec) ;
+BEGIN
+   DISPOSE (ptr) ;
+   IF ptr^.x = 1
+   THEN
+   END
+END test ;
+
+
+VAR
+   p: PtrToVec ;
+BEGIN
+   test (p)
+END testdispose2.
diff --git a/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod
new file mode 100644
index 00000000000..26d1d2b620b
--- /dev/null
+++ b/gcc/testsuite/gm2/switches/uninit-variable-checking/procedures/fail/testnil.mod
@@ -0,0 +1,17 @@
+MODULE testnil ;
+
+
+PROCEDURE test ;
+VAR
+   p: POINTER TO CARDINAL ;
+BEGIN
+   p := NIL ;
+   IF p^ = 1
+   THEN
+   END
+END test ;
+
+
+BEGIN
+   test
+END testnil.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-30 11:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-30 11:35 [gcc r13-7653] modula2: Variable analysis understands DISPOSE and NIL Gaius Mulley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).