[gcc r16-1251] PR modula2/120542: Return statement in the main procedure crashes the compiler
Gaius Mulley
gaius@gcc.gnu.org
Fri Jun 6 09:47:23 GMT 2025
https://gcc.gnu.org/g:16ab791531ec16fd4596a25efbe6b42e6c16171f
commit r16-1251-g16ab791531ec16fd4596a25efbe6b42e6c16171f
Author: Gaius Mulley <gaiusmod2@gmail.com>
Date: Fri Jun 6 10:46:48 2025 +0100
PR modula2/120542: Return statement in the main procedure crashes the compiler
The patch checks whether a return statement is allowed. It also checks
to see that a return expression is allowed.
gcc/m2/ChangeLog:
PR modula2/120542
* gm2-compiler/M2Quads.mod (BuildReturnLower): New procedure.
(BuildReturn): Allow return without an expression from
module initialization blocks. Generate an error if an
expression is provided. Call BuildReturnLower if no error
was seen.
gcc/testsuite/ChangeLog:
PR modula2/120542
* gm2/iso/fail/badreturn.mod: New test.
* gm2/iso/fail/badreturn2.mod: New test.
* gm2/iso/pass/modulereturn.mod: New test.
* gm2/iso/pass/modulereturn2.mod: New test.
Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
Diff:
---
gcc/m2/gm2-compiler/M2Quads.mod | 60 ++++++++++++++++++----------
gcc/testsuite/gm2/iso/fail/badreturn.mod | 5 +++
gcc/testsuite/gm2/iso/fail/badreturn2.mod | 12 ++++++
gcc/testsuite/gm2/iso/pass/modulereturn.mod | 5 +++
gcc/testsuite/gm2/iso/pass/modulereturn2.mod | 10 +++++
5 files changed, 72 insertions(+), 20 deletions(-)
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index 3c29fdd3b2ba..b5455d09c66f 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -11298,6 +11298,35 @@ BEGIN
END CheckReturnType ;
+(*
+ BuildReturnLower - check the return type and value to ensure type
+ compatibility and no range overflow will occur.
+*)
+
+PROCEDURE BuildReturnLower (tokcombined, tokexpr: CARDINAL; e1, t1: CARDINAL) ;
+VAR
+ e2, t2: CARDINAL ;
+BEGIN
+ (* This will check that the type returned is compatible with
+ the formal return type of the procedure. *)
+ CheckReturnType (tokcombined, CurrentProc, e1, t1) ;
+ (* Dereference LeftValue if necessary. *)
+ IF GetMode (e1) = LeftValue
+ THEN
+ t2 := GetSType (CurrentProc) ;
+ e2 := MakeTemporary (tokexpr, RightValue) ;
+ PutVar(e2, t2) ;
+ CheckPointerThroughNil (tokexpr, e1) ;
+ doIndrX (tokexpr, e2, e1) ;
+ e1 := e2
+ END ;
+ (* Here we check the data contents to ensure no overflow. *)
+ BuildRange (InitReturnRangeCheck (tokcombined, CurrentProc, e1)) ;
+ GenQuadOtok (tokcombined, ReturnValueOp, e1, NulSym, CurrentProc, FALSE,
+ tokcombined, UnknownTokenNo, GetDeclaredMod (CurrentProc))
+END BuildReturnLower ;
+
+
(*
BuildReturn - Builds the Return part of the procedure.
tokreturn is the location of the RETURN keyword.
@@ -11317,7 +11346,6 @@ PROCEDURE BuildReturn (tokreturn: CARDINAL) ;
VAR
tokcombined,
tokexpr : CARDINAL ;
- e2, t2,
e1, t1,
t, f,
Des : CARDINAL ;
@@ -11337,26 +11365,18 @@ BEGIN
tokcombined := MakeVirtualTok (tokreturn, tokreturn, tokexpr) ;
IF e1 # NulSym
THEN
- (* this will check that the type returned is compatible with
- the formal return type of the procedure. *)
- CheckReturnType (tokcombined, CurrentProc, e1, t1) ;
- (* dereference LeftValue if necessary *)
- IF GetMode (e1) = LeftValue
- THEN
- t2 := GetSType (CurrentProc) ;
- e2 := MakeTemporary (tokexpr, RightValue) ;
- PutVar(e2, t2) ;
- CheckPointerThroughNil (tokexpr, e1) ;
- doIndrX (tokexpr, e2, e1) ;
- (* here we check the data contents to ensure no overflow. *)
- BuildRange (InitReturnRangeCheck (tokcombined, CurrentProc, e2)) ;
- GenQuadOtok (tokcombined, ReturnValueOp, e2, NulSym, CurrentProc, FALSE,
- tokcombined, UnknownTokenNo, GetDeclaredMod (CurrentProc))
+ (* Check we are in a procedure scope and that the procedure has a return type. *)
+ IF CurrentProc = NulSym
+ THEN
+ MetaErrorT0 (tokcombined,
+ '{%1E} attempting to return a value when not in a procedure scope')
+ ELSIF GetSType (CurrentProc) = NulSym
+ THEN
+ MetaErrorT1 (tokcombined,
+ 'attempting to return a value from procedure {%1Ea} which does not have a return type',
+ CurrentProc)
ELSE
- (* here we check the data contents to ensure no overflow. *)
- BuildRange (InitReturnRangeCheck (tokcombined, CurrentProc, e1)) ;
- GenQuadOtok (tokcombined, ReturnValueOp, e1, NulSym, CurrentProc, FALSE,
- tokcombined, UnknownTokenNo, GetDeclaredMod (CurrentProc))
+ BuildReturnLower (tokcombined, tokexpr, e1, t1)
END
END ;
GenQuadO (tokcombined, GotoOp, NulSym, NulSym, PopWord (ReturnStack), FALSE) ;
diff --git a/gcc/testsuite/gm2/iso/fail/badreturn.mod b/gcc/testsuite/gm2/iso/fail/badreturn.mod
new file mode 100644
index 000000000000..54179611eccd
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/fail/badreturn.mod
@@ -0,0 +1,5 @@
+MODULE badreturn ;
+
+BEGIN
+ RETURN 0
+END badreturn.
\ No newline at end of file
diff --git a/gcc/testsuite/gm2/iso/fail/badreturn2.mod b/gcc/testsuite/gm2/iso/fail/badreturn2.mod
new file mode 100644
index 000000000000..a4b90085f1f3
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/fail/badreturn2.mod
@@ -0,0 +1,12 @@
+MODULE badreturn2 ;
+
+
+PROCEDURE foo ;
+BEGIN
+ RETURN 0
+END foo ;
+
+
+BEGIN
+ foo
+END badreturn2.
diff --git a/gcc/testsuite/gm2/iso/pass/modulereturn.mod b/gcc/testsuite/gm2/iso/pass/modulereturn.mod
new file mode 100644
index 000000000000..b39947d37200
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/pass/modulereturn.mod
@@ -0,0 +1,5 @@
+MODULE modulereturn ;
+
+BEGIN
+ RETURN
+END modulereturn.
diff --git a/gcc/testsuite/gm2/iso/pass/modulereturn2.mod b/gcc/testsuite/gm2/iso/pass/modulereturn2.mod
new file mode 100644
index 000000000000..934cfae79020
--- /dev/null
+++ b/gcc/testsuite/gm2/iso/pass/modulereturn2.mod
@@ -0,0 +1,10 @@
+MODULE modulereturn2 ;
+
+
+BEGIN
+ RETURN
+EXCEPT
+ RETURN
+FINALLY
+ RETURN
+END modulereturn2.
More information about the Gcc-cvs
mailing list