diff options
author | Gaius Mulley <gaiusmod2@gmail.com> | 2025-06-06 10:46:48 +0100 |
---|---|---|
committer | Gaius Mulley <gaiusmod2@gmail.com> | 2025-06-06 10:46:48 +0100 |
commit | 16ab791531ec16fd4596a25efbe6b42e6c16171f (patch) | |
tree | 52ffe4f5db37ad5bf83b07e0de19a55b43f0e4b0 /gcc | |
parent | 61b014f614be523174f6a9df6e1fbac11de11abd (diff) | |
download | gcc-master.zip gcc-master.tar.gz gcc-master.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/m2/gm2-compiler/M2Quads.mod | 60 | ||||
-rw-r--r-- | gcc/testsuite/gm2/iso/fail/badreturn.mod | 5 | ||||
-rw-r--r-- | gcc/testsuite/gm2/iso/fail/badreturn2.mod | 12 | ||||
-rw-r--r-- | gcc/testsuite/gm2/iso/pass/modulereturn.mod | 5 | ||||
-rw-r--r-- | 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 3c29fdd..b5455d0 100644 --- a/gcc/m2/gm2-compiler/M2Quads.mod +++ b/gcc/m2/gm2-compiler/M2Quads.mod @@ -11299,6 +11299,35 @@ 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. The Stack is expected to contain: @@ -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 0000000..5417961 --- /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 0000000..a4b9008 --- /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 0000000..b39947d --- /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 0000000..934cfae --- /dev/null +++ b/gcc/testsuite/gm2/iso/pass/modulereturn2.mod @@ -0,0 +1,10 @@ +MODULE modulereturn2 ; + + +BEGIN + RETURN +EXCEPT + RETURN +FINALLY + RETURN +END modulereturn2. |