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.