https://gcc.gnu.org/g:969c30885558d092ad07c9c71dd54ea14f6096c6

commit r15-7324-g969c30885558d092ad07c9c71dd54ea14f6096c6
Author: Gaius Mulley <gaiusm...@gmail.com>
Date:   Sun Feb 2 16:02:27 2025 +0000

    PR modula2/117411 Request for documentation to include exception example
    
    This patch adds a new section to the gm2 documentation and new
    corresponding testcode to the regression testsuite.
    
    gcc/ChangeLog:
    
            PR modula2/117411
            * doc/gm2.texi (Exception handling): New section.
            (The ISO system module): Add description of COFF_T.
            (Assembler language): Tidy up last sentance.
    
    gcc/testsuite/ChangeLog:
    
            PR modula2/117411
            * gm2/iso/run/pass/except9.mod: New test.
            * gm2/iso/run/pass/lazyunique.mod: New test.
    
    Signed-off-by: Gaius Mulley <gaiusm...@gmail.com>

Diff:
---
 gcc/doc/gm2.texi                              | 162 ++++++++++++++++++++++++--
 gcc/testsuite/gm2/iso/run/pass/except9.mod    |  78 +++++++++++++
 gcc/testsuite/gm2/iso/run/pass/lazyunique.mod |  87 ++++++++++++++
 3 files changed, 318 insertions(+), 9 deletions(-)

diff --git a/gcc/doc/gm2.texi b/gcc/doc/gm2.texi
index f8ae148b99ba..8baee24f14e0 100644
--- a/gcc/doc/gm2.texi
+++ b/gcc/doc/gm2.texi
@@ -234,6 +234,7 @@ such as the AVR and the ARM).
 * Extensions::            GNU Modula-2 language extensions.
 * Type compatibility::    Data type compatibility.
 * Unbounded by reference::Explanation of a language optimization.
+* Exception handling::    Example of exception handling.
 * Building a shared library:: How to build a shared library.
 * Interface for Python::  How to produce swig interface files.
 * Producing a Python module::  How to produce a Python module.
@@ -1837,7 +1838,7 @@ are all exported from the @code{SYSTEM} module.
 @xref{The PIM system module}.
 @xref{The ISO system module}.
 
-@node Type compatibility, Unbounded by reference, Extensions, Using
+@node Type compatibility, Exception handling, Extensions, Using
 @section Type compatibility
 
 This section discuss the issues surrounding assignment, expression
@@ -1985,7 +1986,148 @@ The types @code{BYTE}, @code{LOC}, @code{WORD} and 
@code{WORD}n
 derivatives are assignment and parameter compatible with any data type
 of the same size.
 
-@node Unbounded by reference, Building a shared library, Type compatibility, 
Using
+@node Exception handling, Unbounded by reference, Type compatibility, Using
+@section Exception handling
+
+This section gives an example of exception handling and briefly
+describes its runtime behavior.  The module below is written in the
+ISO dialect of Modula-2 and can be compiled with the command line:
+
+@example
+$ gm2 -g -fiso -fsoft-check-all lazyunique.mod
+@end example
+
+The option @samp{-fsoft-check-all} generates checks for @code{NIL}
+pointer access violation.  In turn this will call the exception handler.
+
+@example
+@group
+MODULE lazyunique ;  (*!m2iso+gm2*)
+
+FROM Storage IMPORT ALLOCATE ;
+FROM libc IMPORT printf, exit ;
+
+TYPE
+   List = POINTER TO RECORD
+                        next : List ;
+                        value: INTEGER ;
+                     END ;
+
+   Array = ARRAY [0..3] OF INTEGER ;
+
+CONST
+   Unsorted = Array @{0, 2, 1, 1@} ;
+
+VAR
+   head: List ;
+@end group   
+@end example
+
+@example
+@group
+PROCEDURE Display ;
+VAR
+   p: List ;
+BEGIN
+   p := head^.next ;
+   printf ("\nunique data\n");
+   printf ("===========\n");   
+   WHILE p # NIL DO
+      printf ("%d\n", p^.value);
+      p := p^.next
+   END
+END Display ;
+@end group   
+@end example
+
+@example
+@group
+PROCEDURE Add (VAR p: List; val: INTEGER) ;
+BEGIN
+   NEW (p) ;
+   WITH p^ DO
+      value := val ;
+      next := NIL
+   END
+END Add ;
+@end group   
+@end example
+
+@example
+@group
+PROCEDURE Unique (val: INTEGER) ;
+VAR
+   p: List ;
+BEGIN
+   printf ("new value %d\n", val);
+   p := head ;
+   (* The following line may cause an exception accessing next or
+      value.  *)
+   WHILE p^.next^.value # val DO
+      p := p^.next
+   END
+EXCEPT
+   (* Now fixup.  Determine the source of the exception and retry.  *)
+   IF head = NIL
+   THEN
+      printf ("list was empty, add sentinal\n");
+      Add (head, -1) ;
+      RETRY  (* Jump back to the begin statement.  *)      
+   ELSIF p^.next = NIL
+   THEN
+      printf ("growing the list\n");
+      Add (p^.next, val) ;
+      RETRY  (* Jump back to the begin statement.  *)
+   ELSE
+      printf ("should never reach here!\n");   
+   END
+END Unique ;
+@end group   
+@end example
+
+@example
+@group
+PROCEDURE unique ;
+VAR
+   i: CARDINAL ;
+BEGIN
+   FOR i := 0 TO HIGH (Unsorted) DO
+      Unique (Unsorted[i])
+   END ;
+   Display
+END unique ;
+
+BEGIN
+   head := NIL ;
+   unique
+END lazyunique.
+@end group   
+@end example
+
+@example
+@group
+new value 0
+list was empty, add sentinal
+new value 0
+growing the list
+new value 0
+new value 2
+growing the list
+new value 2
+new value 1
+growing the list
+new value 1
+new value 1
+
+unique data
+===========
+0
+2
+1
+@end group   
+@end example
+
+@node Unbounded by reference, Building a shared library, Exception handling, 
Using
 @section Unbounded by reference
 
 This section documents a GNU Modula-2 compiler switch which implements
@@ -2589,9 +2731,8 @@ END Example ;
 Both examples generate exactly the same code.  It is worth noting that
 the specifier ``rm'' indicates that the operand can be either a
 register or memory.  Of course you must choose an instruction which
-can take either, but this allows the compiler to take make more
-efficient choices depending upon the optimization level given to the
-compiler.
+can take either, but this allows the compiler to make more
+efficient choices depending upon the optimization level.
 
 @node Alignment, Packed, Assembly language, Using
 @section Data type alignment
@@ -2916,10 +3057,13 @@ depend upon the target architecture.
 
 @include m2/SYSTEM-iso.texi
 
-The data types @code{CSIZE_T} and @code{CSSIZE_T} are also exported from
-the @code{SYSTEM} module.  The type @code{CSIZE_T} is unsigned and is
-mapped onto the target C data type @code{size_t} whereas the type
-@code{CSSIZE_T} is mapped onto the signed C data type @code{ssize_t}.
+The data types @code{CSIZE_T}, @code{CSSIZE_T} and @code{COFF_T} are
+also exported from the @code{SYSTEM} module.  The type @code{CSIZE_T}
+is unsigned and is mapped onto the target C data type @code{size_t}
+whereas the type @code{CSSIZE_T} is mapped onto the signed C data type
+@code{ssize_t}.  The default size for the signed type @code{COFF_T} is
+the same as @code{CSSIZE_T} and this can be overridden by the
+@code{-fm2-file-offset-bits=} command line option.
 
 It is anticipated that these should only be used to provide cross
 platform definition modules for C libraries.
diff --git a/gcc/testsuite/gm2/iso/run/pass/except9.mod 
b/gcc/testsuite/gm2/iso/run/pass/except9.mod
new file mode 100644
index 000000000000..e5f9482b511f
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/run/pass/except9.mod
@@ -0,0 +1,78 @@
+(* Copyright (C) 2025 Free Software Foundation, Inc. *)
+(* This file is part of GNU Modula-2.
+
+GNU Modula-2 is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with gm2; see the file COPYING.  If not, write to the Free Software
+Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *)
+
+MODULE except9 ;
+
+FROM libc IMPORT printf ;
+FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
+FROM SYSTEM IMPORT ADR, WORD ;
+
+
+PROCEDURE fly (debug: BOOLEAN) ;
+BEGIN
+   printf("fly main body\n") ;
+   IF 4 DIV ip^ = 4
+   THEN
+      printf("yes it worked\n")
+   ELSE
+      printf("no it failed\n")
+   END
+END fly ;
+
+(*
+ *   a GNU M2 version of the Modula-2 example given in the ISO standard.
+ *   This is a hand translation of the equivalent except.c file in this
+ *   directory which is written to prove that the underlying runtime system
+ *   will work with the GCC exception handling trees.
+ *)
+
+PROCEDURE tryFlying (debug: BOOLEAN) ;
+BEGIN
+   printf("tryFlying main body\n");  
+   fly (debug) ;
+EXCEPT
+   printf("inside tryFlying exception routine\n") ;
+   IF (ip#NIL) AND (ip^=0)
+   THEN
+      ip^ := 1 ;
+      RETRY
+   END
+END tryFlying ;
+
+
+PROCEDURE keepFlying (debug: BOOLEAN) ;
+BEGIN
+   printf("keepFlying main body\n") ;
+   tryFlying (debug) ;
+EXCEPT
+   printf("inside keepFlying exception routine\n") ;
+   IF ip=NIL
+   THEN
+      NEW(ip) ;
+      ip^ := 0 ;
+      RETRY
+   END
+END keepFlying ;
+
+
+VAR
+   ip: POINTER TO INTEGER ;
+BEGIN
+   ip := NIL ;
+   keepFlying (FALSE) ;
+   printf("all done\n")
+END except9.
diff --git a/gcc/testsuite/gm2/iso/run/pass/lazyunique.mod 
b/gcc/testsuite/gm2/iso/run/pass/lazyunique.mod
new file mode 100644
index 000000000000..5e4a310b0627
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/run/pass/lazyunique.mod
@@ -0,0 +1,87 @@
+MODULE lazyunique ;  (*!m2iso+gm2*)
+
+FROM Storage IMPORT ALLOCATE ;
+FROM libc IMPORT printf, exit ;
+
+TYPE
+   List = POINTER TO RECORD
+                        next : List ;
+                        value: INTEGER ;
+                     END ;
+
+   Array = ARRAY [0..3] OF INTEGER ;
+
+CONST
+   Unsorted = Array {0, 2, 1, 1} ;
+
+VAR
+   head: List ;
+
+
+PROCEDURE Display ;
+VAR
+   p: List ;
+BEGIN
+   p := head^.next ;
+   printf ("\nunique data\n");
+   printf ("===========\n");   
+   WHILE p # NIL DO
+      printf ("%d\n", p^.value);
+      p := p^.next
+   END
+END Display ;
+
+
+PROCEDURE Add (VAR p: List; val: INTEGER) ;
+BEGIN
+   NEW (p) ;
+   WITH p^ DO
+      value := val ;
+      next := NIL
+   END
+END Add ;
+
+
+PROCEDURE Unique (val: INTEGER) ;
+VAR
+   p: List ;
+BEGIN
+   printf ("new value %d\n", val);
+   p := head ;
+   (* The following line may cause an exception accessing next or value.  *)
+   WHILE p^.next^.value # val DO
+      p := p^.next
+   END
+EXCEPT
+   (* Now fixup.  Determine the source of the exception and retry.  *)
+   IF head = NIL
+   THEN
+      printf ("list was empty, add sentinal\n");
+      Add (head, -1) ;
+      RETRY  (* Jump back to the begin statement.  *)      
+   ELSIF p^.next = NIL
+   THEN
+      printf ("growing the list\n");
+      Add (p^.next, val) ;
+      RETRY  (* Jump back to the begin statement.  *)
+   ELSE
+      printf ("should never reach here!\n");   
+   END
+END Unique ;
+
+
+PROCEDURE unique ;
+VAR
+   i: CARDINAL ;
+BEGIN
+   FOR i := 0 TO HIGH (Unsorted) DO
+      Unique (Unsorted[i])
+   END ;
+   Display
+END unique ;
+
+
+BEGIN
+   head := NIL ;
+   unique
+END lazyunique.

Reply via email to