aboutsummaryrefslogtreecommitdiff
path: root/gcc/m2
diff options
context:
space:
mode:
authorGaius Mulley <gaiusmod2@gmail.com>2023-05-12 00:15:28 +0100
committerGaius Mulley <gaiusmod2@gmail.com>2023-05-12 00:15:28 +0100
commitc787f593e62869ae0b230949b4791f4f3a26e50e (patch)
tree55bb404358049d4fcc0fea6c5a72ab8bdf671a12 /gcc/m2
parent02777f20be4f40160f1b4ed34fa59ba75245b5b7 (diff)
downloadgcc-c787f593e62869ae0b230949b4791f4f3a26e50e.zip
gcc-c787f593e62869ae0b230949b4791f4f3a26e50e.tar.gz
gcc-c787f593e62869ae0b230949b4791f4f3a26e50e.tar.bz2
PR modula2/109810 ICE fix when an array is assigned by a larger string
This patch fixes an ICE when an array variable is assigned with a string which exceeds the array size. It improves the accuracy of the virtual token used to indicate the error message. gcc/m2/ChangeLog: PR modula2/109810 * gm2-compiler/M2ALU.mod (ConvertConstToType): Use PrepareCopyString in place of DoCopyString. * gm2-compiler/M2GenGCC.def (DoCopyString): Rename to ... (PrepareCopyString): ... this. * gm2-compiler/M2GenGCC.mod (CodeStatement): Call CodeReturnValue with a single parameter. Call CodeXIndr with a single parameter. (CodeReturnValue): Remove parameters and replace with a single quadno. Reimplement using PrepareCopyString. Issue error if the string exceeds designator space. (DoCopyString): Reimplement and rename to ... (PrepareCopyString): ... this. (CodeXIndr): Remove parameters and replace with a single quadno. Reimplement using PrepareCopyString. Issue error if the string exceeds designator space. (CodeBecomes): Remove parameters and replace with a single quadno. Reimplement using PrepareCopyString. Issue error if the string exceeds designator space. * gm2-compiler/M2Quads.def (BuildReturn): Rename parameter to tokreturn. * gm2-compiler/M2Quads.mod (BuildReturn): Rename parameter to tokreturn. Rename tokno to tokcombined. gcc/testsuite/ChangeLog: PR modula2/109810 * gm2/pim/fail/highice.mod: New test. Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
Diffstat (limited to 'gcc/m2')
-rw-r--r--gcc/m2/gm2-compiler/M2ALU.mod11
-rw-r--r--gcc/m2/gm2-compiler/M2GenGCC.def21
-rw-r--r--gcc/m2/gm2-compiler/M2GenGCC.mod208
-rw-r--r--gcc/m2/gm2-compiler/M2Quads.def2
-rw-r--r--gcc/m2/gm2-compiler/M2Quads.mod73
5 files changed, 176 insertions, 139 deletions
diff --git a/gcc/m2/gm2-compiler/M2ALU.mod b/gcc/m2/gm2-compiler/M2ALU.mod
index ef3b934..5cad874 100644
--- a/gcc/m2/gm2-compiler/M2ALU.mod
+++ b/gcc/m2/gm2-compiler/M2ALU.mod
@@ -40,7 +40,7 @@ FROM M2Debug IMPORT Assert ;
FROM Storage IMPORT ALLOCATE ;
FROM StringConvert IMPORT ostoi, bstoi, stoi, hstoi ;
FROM M2GCCDeclare IMPORT GetTypeMin, GetTypeMax, CompletelyResolved, DeclareConstant ;
-FROM M2GenGCC IMPORT DoCopyString, StringToChar ;
+FROM M2GenGCC IMPORT PrepareCopyString, StringToChar ;
FROM M2Bitset IMPORT Bitset ;
FROM SymbolConversion IMPORT Mod2Gcc, GccKnowsAbout ;
FROM M2Printf IMPORT printf0, printf2 ;
@@ -4528,8 +4528,13 @@ BEGIN
IF IsConstString(init) AND IsArray(SkipType(GetType(field))) AND
(SkipTypeAndSubrange(GetType(GetType(field)))=Char)
THEN
- DoCopyString(tokenno, nBytes, initT, GetType(field), init) ;
- RETURN( initT )
+ IF NOT PrepareCopyString (tokenno, nBytes, initT, init, GetType (field))
+ THEN
+ MetaErrorT2 (tokenno,
+ 'string constant {%1Ea} is too large to be assigned to the {%2d} {%2a}',
+ init, field)
+ END ;
+ RETURN initT
ELSE
RETURN( ConvertConstantAndCheck(TokenToLocation(tokenno), Mod2Gcc(GetType(field)), Mod2Gcc(init)) )
END
diff --git a/gcc/m2/gm2-compiler/M2GenGCC.def b/gcc/m2/gm2-compiler/M2GenGCC.def
index e29649d..646e09e 100644
--- a/gcc/m2/gm2-compiler/M2GenGCC.def
+++ b/gcc/m2/gm2-compiler/M2GenGCC.def
@@ -37,7 +37,7 @@ FROM m2linemap IMPORT location_t ;
EXPORT QUALIFIED ConvertQuadsToTree, ResolveConstantExpressions,
GetHighFromUnbounded, StringToChar,
LValueToGenericPtr, ZConstToTypedConst,
- DoCopyString ;
+ PrepareCopyString ;
(*
@@ -91,13 +91,22 @@ PROCEDURE ZConstToTypedConst (t: Tree; op1, op2: CARDINAL) : Tree ;
(*
- DoCopyString - returns trees:
- t number of bytes to be copied (including the nul)
- op3t the string with the extra nul character
- providing it fits.
+ PrepareCopyString - returns two trees:
+ length number of bytes to be copied (including the nul if room)
+ srcTreeType the new string type (with the extra nul character).
+
+ Pre condition: destStrType the dest type string.
+ src is the original string (without a nul)
+ to be copied.
+ Post condition: TRUE or FALSE is returned.
+ if true length and srcTreeType will be assigned
+ else length is set to the maximum length to be
+ copied and srcTree is set to the max length
+ which fits in dest.
*)
-PROCEDURE DoCopyString (tokenno: CARDINAL; VAR length, op3t: Tree; op1t, op3: CARDINAL) ;
+PROCEDURE PrepareCopyString (tokenno: CARDINAL; VAR length, srcTree: Tree;
+ src, destStrType: CARDINAL) : BOOLEAN ;
END M2GenGCC.
diff --git a/gcc/m2/gm2-compiler/M2GenGCC.mod b/gcc/m2/gm2-compiler/M2GenGCC.mod
index 15fb929..9e975ba 100644
--- a/gcc/m2/gm2-compiler/M2GenGCC.mod
+++ b/gcc/m2/gm2-compiler/M2GenGCC.mod
@@ -80,7 +80,10 @@ FROM SymbolTable IMPORT PushSize, PopSize, PushValue, PopValue,
NulSym ;
FROM M2Batch IMPORT MakeDefinitionSource ;
-FROM M2LexBuf IMPORT FindFileNameFromToken, TokenToLineNo, TokenToLocation, MakeVirtualTok ;
+
+FROM M2LexBuf IMPORT FindFileNameFromToken, TokenToLineNo, TokenToLocation,
+ MakeVirtualTok, UnknownTokenNo ;
+
FROM M2Code IMPORT CodeBlock ;
FROM M2Debug IMPORT Assert ;
FROM M2Error IMPORT InternalError, WriteFormat0, WriteFormat1, WriteFormat2, WarnStringAt ;
@@ -167,6 +170,7 @@ FROM m2expr IMPORT GetIntegerZero, GetIntegerOne,
CompareTrees,
StringLength,
AreConstantsEqual,
+ GetCstInteger,
BuildForeachWordInSetDoIfExpr,
BuildIfConstInVar,
BuildIfVarInVar,
@@ -467,7 +471,7 @@ BEGIN
KillLocalVarOp : CodeKillLocalVar (op3) |
ProcedureScopeOp : CodeProcedureScope (op3) |
ReturnOp : (* Not used as return is achieved by KillLocalVar. *) |
- ReturnValueOp : CodeReturnValue (op1, op3) |
+ ReturnValueOp : CodeReturnValue (q) |
TryOp : CodeTry |
ThrowOp : CodeThrow (op3) |
CatchBeginOp : CodeCatchBegin |
@@ -507,7 +511,7 @@ BEGIN
IfInOp : CodeIfIn (q, op1, op2, op3) |
IfNotInOp : CodeIfNotIn (q, op1, op2, op3) |
IndrXOp : CodeIndrX (q, op1, op2, op3) |
- XIndrOp : CodeXIndr (q, op1, op2, op3) |
+ XIndrOp : CodeXIndr (q) |
CallOp : CodeCall (CurrentQuadToken, op3) |
ParamOp : CodeParam (q, op1, op2, op3) |
FunctValueOp : CodeFunctValue (location, op1) |
@@ -1832,68 +1836,39 @@ END CodeProcedureScope ;
allocated by the function call.
*)
-PROCEDURE CodeReturnValue (res, Procedure: CARDINAL) ;
+PROCEDURE CodeReturnValue (quad: CARDINAL) ;
VAR
- value, length, op3t : Tree ;
- location: location_t ;
+ op : QuadOperator ;
+ expr, none, procedure : CARDINAL ;
+ combinedpos,
+ returnpos, exprpos, nonepos, procpos: CARDINAL ;
+ value, length : Tree ;
+ location : location_t ;
BEGIN
- location := TokenToLocation (CurrentQuadToken) ;
- TryDeclareConstant (CurrentQuadToken, res) ; (* checks to see whether it is a constant and declares it *)
- TryDeclareConstructor (CurrentQuadToken, res) ;
- IF IsConstString (res) AND (SkipTypeAndSubrange (GetType (Procedure)) # Char)
+ GetQuadOtok (quad, returnpos, op, expr, none, procedure,
+ exprpos, nonepos, procpos) ;
+ combinedpos := MakeVirtualTok (returnpos, returnpos, exprpos) ;
+ location := TokenToLocation (combinedpos) ;
+ TryDeclareConstant (exprpos, expr) ; (* checks to see whether it is a constant and declares it *)
+ TryDeclareConstructor (exprpos, expr) ;
+ IF IsConstString (expr) AND (SkipTypeAndSubrange (GetType (procedure)) # Char)
THEN
- DoCopyString (CurrentQuadToken, length, op3t, GetType (Procedure), res) ;
+ IF NOT PrepareCopyString (returnpos, length, value, expr, GetType (procedure))
+ THEN
+ MetaErrorT3 (MakeVirtualTok (returnpos, returnpos, exprpos),
+ 'string constant {%1Ea} is too large to be returned from procedure {%2a} via the {%3d} {%3a}',
+ expr, procedure, GetType (procedure))
+ END ;
value := BuildArrayStringConstructor (location,
- Mod2Gcc (GetType (Procedure)), op3t, length)
+ Mod2Gcc (GetType (procedure)),
+ value, length)
ELSE
- value := Mod2Gcc (res)
+ value := Mod2Gcc (expr)
END ;
- BuildReturnValueCode (location, Mod2Gcc (Procedure), value)
+ BuildReturnValueCode (location, Mod2Gcc (procedure), value)
END CodeReturnValue ;
-(* *******************************
-(*
- GenerateCleanup - generates a try/catch/clobber tree containing the call to ptree
-*)
-
-PROCEDURE GenerateCleanup (location: location_t; procedure: CARDINAL; p, call: Tree) : Tree ;
-VAR
- i, n: CARDINAL ;
- t : Tree ;
-BEGIN
- t := push_statement_list (begin_statement_list ()) ;
- i := 1 ;
- n := NoOfParam (procedure) ;
- WHILE i<=n DO
- IF IsParameterVar (GetNthParam (procedure, i))
- THEN
- AddStatement (location, BuildCleanUp (GetParamTree (call, i-1)))
- END ;
- INC(i)
- END ;
- RETURN BuildTryFinally (location, p, pop_statement_list ())
-END GenerateCleanup ;
-
-
-(*
- CheckCleanup - checks whether a cleanup is required for a procedure with
- VAR parameters. The final tree is returned.
-*)
-
-PROCEDURE CheckCleanup (location: location_t; procedure: CARDINAL; tree, call: Tree) : Tree ;
-BEGIN
- IF HasVarParameters(procedure)
- THEN
- RETURN tree ;
- (* RETURN GenerateCleanup(location, procedure, tree, call) *)
- ELSE
- RETURN tree
- END
-END CheckCleanup ;
-************************************** *)
-
-
(*
CodeCall - determines whether the procedure call is a direct call
or an indirect procedure call.
@@ -1920,7 +1895,6 @@ BEGIN
THEN
location := TokenToLocation (tokenno) ;
AddStatement (location, tree)
- (* was AddStatement(location, CheckCleanup(location, procedure, tree, tree)) *)
ELSE
(* leave tree alone - as it will be picked up when processing FunctValue *)
END
@@ -2882,57 +2856,67 @@ END FoldConstBecomes ;
(*
- DoCopyString - returns trees:
- length number of bytes to be copied (including the nul)
- op1t the new string _type_ (with the extra nul character).
- op3t the actual string with the extra nul character.
+ PrepareCopyString - returns two trees:
+ length number of bytes to be copied (including the nul if room)
+ srcTreeType the new string type (with the extra nul character).
+
+ Pre condition: destStrType the dest type string.
+ src is the original string (without a nul)
+ to be copied.
+ Post condition: TRUE or FALSE is returned.
+ if true length and srcTreeType will be assigned
+ else length is set to the maximum length to be
+ copied and srcTree is set to the max length
+ which fits in dest.
*)
-PROCEDURE DoCopyString (tokenno: CARDINAL; VAR length, op3t: Tree; op1t, op3: CARDINAL) ;
+PROCEDURE PrepareCopyString (tokenno: CARDINAL; VAR length, srcTree: Tree;
+ src, destStrType: CARDINAL) : BOOLEAN ;
VAR
- location: location_t ;
+ location : location_t ;
+ intLength: INTEGER ;
BEGIN
- location := TokenToLocation(tokenno) ;
- Assert(IsArray(SkipType(op1t))) ;
- (* handle string assignments:
+ location := TokenToLocation (tokenno) ;
+ Assert (IsArray (SkipType (destStrType))) ;
+ (* Handle string assignments:
VAR
str: ARRAY [0..10] OF CHAR ;
ch : CHAR ;
str := 'abcde' but not ch := 'a'
*)
- IF GetType (op3) = Char
+ IF GetType (src) = Char
THEN
(*
- * create string from char and add nul to the end, nul is
+ * Create string from char and add nul to the end, nul is
* added by BuildStringConstant
*)
- op3t := BuildStringConstant (KeyToCharStar (GetString (op3)), 1)
+ srcTree := BuildStringConstant (KeyToCharStar (GetString (src)), 1)
ELSE
- op3t := Mod2Gcc (op3)
+ srcTree := Mod2Gcc (src)
END ;
- op3t := ConvertString (Mod2Gcc (op1t), op3t) ;
-
- PushIntegerTree(FindSize(tokenno, op3)) ;
- PushIntegerTree(FindSize(tokenno, op1t)) ;
- IF Less(tokenno)
- THEN
- (* there is room for the extra <nul> character *)
- length := BuildAdd(location, FindSize(tokenno, op3), GetIntegerOne(location), FALSE)
+ srcTree := ConvertString (Mod2Gcc (destStrType), srcTree) ;
+ PushIntegerTree (FindSize (tokenno, src)) ;
+ PushIntegerTree (FindSize (tokenno, destStrType)) ;
+ IF Less (tokenno)
+ THEN
+ (* There is room for the extra <nul> character. *)
+ length := BuildAdd (location, FindSize (tokenno, src),
+ GetIntegerOne (location), FALSE)
ELSE
- PushIntegerTree(FindSize(tokenno, op3)) ;
- PushIntegerTree(FindSize(tokenno, op1t)) ;
+ length := FindSize (tokenno, destStrType) ;
+ PushIntegerTree (FindSize (tokenno, src)) ;
+ PushIntegerTree (length) ;
+ (* Greater or Equal so return max characters in the array. *)
IF Gre (tokenno)
THEN
- WarnStringAt (InitString('string constant is too large to be assigned to the array'),
- tokenno) ;
- length := FindSize (tokenno, op1t)
- ELSE
- (* equal so return max characters in the array *)
- length := FindSize (tokenno, op1t)
+ intLength := GetCstInteger (length) ;
+ srcTree := BuildStringConstant (KeyToCharStar (GetString (src)), intLength) ;
+ RETURN FALSE
END
- END
-END DoCopyString ;
+ END ;
+ RETURN TRUE
+END PrepareCopyString ;
(*
@@ -3104,7 +3088,8 @@ VAR
location : location_t ;
BEGIN
GetQuadOtok (quad, becomespos, op, op1, op2, op3, op1pos, op2pos, op3pos) ;
- DeclareConstant (CurrentQuadToken, op3) ; (* checks to see whether it is a constant and declares it *)
+ Assert (op2pos = UnknownTokenNo) ;
+ DeclareConstant (CurrentQuadToken, op3) ; (* Check to see whether op3 is a constant and declare it. *)
DeclareConstructor (CurrentQuadToken, quad, op3) ;
location := TokenToLocation (CurrentQuadToken) ;
@@ -3121,7 +3106,12 @@ BEGIN
ELSIF IsConstString (op3) AND (SkipTypeAndSubrange (GetType (op1)) # Char)
THEN
checkDeclare (op1) ;
- DoCopyString (CurrentQuadToken, length, op3t, SkipType (GetType (op1)), op3) ;
+ IF NOT PrepareCopyString (becomespos, length, op3t, op3, SkipType (GetType (op1)))
+ THEN
+ MetaErrorT2 (MakeVirtualTok (becomespos, op1pos, op3pos),
+ 'string constant {%1Ea} is too large to be assigned to the array {%2ad}',
+ op3, op1)
+ END ;
AddStatement (location,
MaybeDebugBuiltinMemcpy (location, CurrentQuadToken,
BuildAddr (location, Mod2Gcc (op1), FALSE),
@@ -7177,17 +7167,28 @@ END CodeIndrX ;
(op2 is the type of the data being indirectly copied)
*)
-PROCEDURE CodeXIndr (quad: CARDINAL; op1, type, op3: CARDINAL) ;
+PROCEDURE CodeXIndr (quad: CARDINAL) ;
VAR
+ op : QuadOperator ;
+ tokenno,
+ op1,
+ type,
+ op3,
+ op1pos,
+ op3pos,
+ typepos,
+ xindrpos: CARDINAL ;
length,
newstr : Tree ;
location: location_t ;
BEGIN
- location := TokenToLocation(CurrentQuadToken) ;
+ GetQuadOtok (quad, xindrpos, op, op1, type, op3, op1pos, typepos, op3pos) ;
+ tokenno := MakeVirtualTok (xindrpos, op1pos, op3pos) ;
+ location := TokenToLocation (tokenno) ;
type := SkipType (type) ;
- DeclareConstant(CurrentQuadToken, op3) ;
- DeclareConstructor(CurrentQuadToken, quad, op3) ;
+ DeclareConstant (op3pos, op3) ;
+ DeclareConstructor (op3pos, quad, op3) ;
(*
Follow the Quadruple rule:
@@ -7195,8 +7196,8 @@ BEGIN
*)
IF IsProcType(SkipType(type))
THEN
- BuildAssignmentStatement (location, BuildIndirect(location, Mod2Gcc(op1), GetPointerType()), Mod2Gcc(op3))
- ELSIF IsConstString(op3) AND (GetStringLength(op3)=0) AND (GetMode(op1)=LeftValue)
+ BuildAssignmentStatement (location, BuildIndirect (location, Mod2Gcc (op1), GetPointerType ()), Mod2Gcc (op3))
+ ELSIF IsConstString (op3) AND (GetStringLength (op3) = 0) AND (GetMode (op1) = LeftValue)
THEN
(*
no need to check for type errors,
@@ -7205,13 +7206,18 @@ BEGIN
contents.
*)
BuildAssignmentStatement (location,
- BuildIndirect(location, LValueToGenericPtr(location, op1), Mod2Gcc(Char)),
- StringToChar(Mod2Gcc(op3), Char, op3))
- ELSIF IsConstString(op3) AND (SkipTypeAndSubrange(GetType(op1))#Char)
+ BuildIndirect (location, LValueToGenericPtr (location, op1), Mod2Gcc (Char)),
+ StringToChar (Mod2Gcc (op3), Char, op3))
+ ELSIF IsConstString (op3) AND (SkipTypeAndSubrange (GetType (op1)) # Char)
THEN
- DoCopyString (CurrentQuadToken, length, newstr, type, op3) ;
+ IF NOT PrepareCopyString (tokenno, length, newstr, op3, type)
+ THEN
+ MetaErrorT2 (MakeVirtualTok (xindrpos, op1pos, op3pos),
+ 'string constant {%1Ea} is too large to be assigned to the array {%2ad}',
+ op3, op1)
+ END ;
AddStatement (location,
- MaybeDebugBuiltinMemcpy (location, CurrentQuadToken,
+ MaybeDebugBuiltinMemcpy (location, tokenno,
Mod2Gcc (op1),
BuildAddr (location, newstr, FALSE),
length))
diff --git a/gcc/m2/gm2-compiler/M2Quads.def b/gcc/m2/gm2-compiler/M2Quads.def
index 84c01e2..582daeb 100644
--- a/gcc/m2/gm2-compiler/M2Quads.def
+++ b/gcc/m2/gm2-compiler/M2Quads.def
@@ -1705,7 +1705,7 @@ PROCEDURE BuildProcedureEnd ;
|------------|
*)
-PROCEDURE BuildReturn (tokno: CARDINAL) ;
+PROCEDURE BuildReturn (tokreturn: CARDINAL) ;
(*
diff --git a/gcc/m2/gm2-compiler/M2Quads.mod b/gcc/m2/gm2-compiler/M2Quads.mod
index 57f272f..65e3c49 100644
--- a/gcc/m2/gm2-compiler/M2Quads.mod
+++ b/gcc/m2/gm2-compiler/M2Quads.mod
@@ -260,7 +260,7 @@ IMPORT M2Error ;
CONST
DebugStackOn = TRUE ;
DebugVarients = FALSE ;
- BreakAtQuad = 4423 ;
+ BreakAtQuad = 133 ;
DebugTokPos = FALSE ;
TYPE
@@ -301,8 +301,8 @@ TYPE
RecordSym : CARDINAL ;
RecordType : CARDINAL ;
RecordRef : CARDINAL ;
- rw : CARDINAL ; (* The record variable. *)
- RecordTokPos: CARDINAL ; (* Token of the record. *)
+ rw : CARDINAL ; (* The record variable. *)
+ RecordTokPos: CARDINAL ; (* Token of the record. *)
END ;
ForLoopInfo = POINTER TO RECORD
@@ -333,8 +333,9 @@ VAR
WhileStack,
ForStack,
ExitStack,
- ReturnStack : StackOfWord ; (* Return quadruple of the procedure. *)
- PriorityStack : StackOfWord ; (* Temporary variable holding old priority. *)
+ ReturnStack : StackOfWord ; (* Return quadruple of the procedure. *)
+ PriorityStack : StackOfWord ; (* Temporary variable holding old *)
+ (* priority. *)
SuppressWith : BOOLEAN ;
QuadArray : Index ;
NextQuad : CARDINAL ; (* Next quadruple number to be created. *)
@@ -3195,7 +3196,7 @@ BEGIN
IF IsConstString(Exp) AND IsConst(Des)
THEN
GenQuadOtok (tokno, BecomesOp, Des, NulSym, Exp, TRUE,
- tokno, destok, exptok) ;
+ destok, UnknownTokenNo, exptok) ;
PutConstString (tokno, Des, GetString (Exp))
ELSE
IF GetMode(Des)=RightValue
@@ -3206,7 +3207,7 @@ BEGIN
doIndrX (tokno, Des, Exp)
ELSE
GenQuadOtok (tokno, BecomesOp, Des, NulSym, Exp, TRUE,
- tokno, destok, exptok)
+ destok, UnknownTokenNo, exptok)
END
ELSIF GetMode(Des)=LeftValue
THEN
@@ -3227,7 +3228,7 @@ BEGIN
END
ELSE
GenQuadOtok (tokno, BecomesOp, Des, NulSym, Exp, TRUE,
- tokno, destok, exptok)
+ destok, UnknownTokenNo, exptok)
END
END
END MoveWithMode ;
@@ -3542,6 +3543,17 @@ BEGIN
MarkAsWrite (w) ;
CheckCompatibleWithBecomes (Des, Exp, destok, exptok) ;
combinedtok := MakeVirtualTok (becomesTokNo, destok, exptok) ;
+ IF DebugTokPos
+ THEN
+ MetaErrorT1 (becomesTokNo, 'becomestok {%1Oad}', Des) ;
+ MetaErrorT1 (destok, 'destok {%1Oad}', Des) ;
+ MetaErrorT1 (exptok, 'exptok {%1Oad}', Exp)
+ END ;
+ combinedtok := MakeVirtualTok (becomesTokNo, destok, exptok) ;
+ IF DebugTokPos
+ THEN
+ MetaErrorT1 (combinedtok, 'combined {%1Oad}', Des)
+ END ;
IF (GetSType (Des) # NulSym) AND (NOT IsSet (GetDType (Des)))
THEN
(* Tell code generator to test runtime values of assignment so ensure we
@@ -3552,7 +3564,7 @@ BEGIN
THEN
CheckBecomesMeta (Des, Exp, combinedtok, destok, exptok)
END ;
- (* Traditional Assignment. *)
+ (* Simple assignment. *)
MoveWithMode (becomesTokNo, Des, Exp, Array, destok, exptok, checkOverflow) ;
IF checkTypes
THEN
@@ -10925,7 +10937,7 @@ END CheckReturnType ;
(*
BuildReturn - Builds the Return part of the procedure.
- tokno is the location of the RETURN keyword.
+ tokreturn is the location of the RETURN keyword.
The Stack is expected to contain:
@@ -10938,48 +10950,53 @@ END CheckReturnType ;
|------------|
*)
-PROCEDURE BuildReturn (tokno: CARDINAL) ;
+PROCEDURE BuildReturn (tokreturn: CARDINAL) ;
VAR
+ tokcombined,
+ tokexpr : CARDINAL ;
e2, t2,
e1, t1,
t, f,
- Des : CARDINAL ;
+ Des : CARDINAL ;
BEGIN
IF IsBoolean (1)
THEN
- PopBool(t, f) ;
+ PopBooltok (t, f, tokexpr) ;
(* Des will be a boolean type *)
- Des := MakeTemporary (tokno, RightValue) ;
+ Des := MakeTemporary (tokexpr, RightValue) ;
PutVar (Des, Boolean) ;
- PushTF (Des, Boolean) ;
- PushBool (t, f) ;
- BuildAssignmentWithoutBounds (tokno, FALSE, TRUE) ;
- PushTF (Des, Boolean)
+ PushTFtok (Des, Boolean, tokexpr) ;
+ PushBooltok (t, f, tokexpr) ;
+ BuildAssignmentWithoutBounds (tokreturn, FALSE, TRUE) ;
+ PushTFtok (Des, Boolean, tokexpr)
END ;
- PopTF (e1, t1) ;
+ PopTFtok (e1, t1, tokexpr) ;
+ 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 (tokno, CurrentProc, e1, t1) ;
+ CheckReturnType (tokcombined, CurrentProc, e1, t1) ;
(* dereference LeftValue if necessary *)
IF GetMode (e1) = LeftValue
THEN
t2 := GetSType (CurrentProc) ;
- e2 := MakeTemporary (tokno, RightValue) ;
+ e2 := MakeTemporary (tokexpr, RightValue) ;
PutVar(e2, t2) ;
- CheckPointerThroughNil (tokno, e1) ;
- doIndrX (tokno, e2, e1) ;
+ CheckPointerThroughNil (tokexpr, e1) ;
+ doIndrX (tokexpr, e2, e1) ;
(* here we check the data contents to ensure no overflow. *)
- BuildRange (InitReturnRangeCheck (tokno, CurrentProc, e2)) ;
- GenQuadO (tokno, ReturnValueOp, e2, NulSym, CurrentProc, FALSE)
+ BuildRange (InitReturnRangeCheck (tokcombined, CurrentProc, e2)) ;
+ GenQuadOtok (tokcombined, ReturnValueOp, e2, NulSym, CurrentProc, FALSE,
+ tokcombined, UnknownTokenNo, GetDeclaredMod (CurrentProc))
ELSE
(* here we check the data contents to ensure no overflow. *)
- BuildRange (InitReturnRangeCheck (tokno, CurrentProc, e1)) ;
- GenQuadO (tokno, ReturnValueOp, e1, NulSym, CurrentProc, FALSE)
+ BuildRange (InitReturnRangeCheck (tokcombined, CurrentProc, e1)) ;
+ GenQuadOtok (tokcombined, ReturnValueOp, e1, NulSym, CurrentProc, FALSE,
+ tokcombined, UnknownTokenNo, GetDeclaredMod (CurrentProc))
END
END ;
- GenQuadO (tokno, GotoOp, NulSym, NulSym, PopWord(ReturnStack), FALSE) ;
+ GenQuadO (tokcombined, GotoOp, NulSym, NulSym, PopWord (ReturnStack), FALSE) ;
PushWord (ReturnStack, NextQuad-1)
END BuildReturn ;