Add array bounds checking
This commit is contained in:
parent
432c89e625
commit
408b8614e2
|
@ -328,10 +328,18 @@ genArraySubscript v es
|
|||
-- smart C compiler should be able to work it out...
|
||||
genPlainSub :: A.Variable -> [A.Expression] -> [Int] -> [CGen ()]
|
||||
genPlainSub _ [] _ = []
|
||||
genPlainSub v (e:es) (_:subs)
|
||||
genPlainSub v (e:es) (sub:subs)
|
||||
= gen : genPlainSub v es subs
|
||||
where
|
||||
gen = sequence_ $ intersperse (tell [" * "]) $ genExpression e : genChunks
|
||||
gen = sequence_ $ intersperse (tell [" * "]) $ genSub : genChunks
|
||||
genSub
|
||||
= do tell ["occam_check_index ("]
|
||||
genExpression e
|
||||
tell [", "]
|
||||
genVariable v
|
||||
tell ["_sizes[", show sub, "], "]
|
||||
genMeta (metaOfExpression e)
|
||||
tell [")"]
|
||||
genChunks = [genVariable v >> tell ["_sizes[", show i, "]"] | i <- subs]
|
||||
--}}}
|
||||
|
||||
|
@ -544,7 +552,15 @@ genSlice :: A.Variable -> A.Variable -> A.Expression -> A.Expression -> [A.Dimen
|
|||
genSlice v (A.Variable _ on) start count ds
|
||||
= (tell ["&"] >> genVariable v,
|
||||
genArraySize False
|
||||
(do genExpression count
|
||||
(do tell ["occam_check_slice ("]
|
||||
genExpression start
|
||||
tell [", "]
|
||||
genExpression count
|
||||
tell [", "]
|
||||
genName on
|
||||
tell ["_sizes[0], "]
|
||||
genMeta (metaOfExpression count)
|
||||
tell [")"]
|
||||
sequence_ [do tell [", "]
|
||||
genName on
|
||||
tell ["_sizes[", show i, "]"]
|
||||
|
|
|
@ -35,9 +35,24 @@
|
|||
#warning No PACKED implementation for this compiler
|
||||
#endif
|
||||
|
||||
static void occam_stop (const char *pos, const char *message) {
|
||||
EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: %s\n", pos, message);
|
||||
SetErr ();
|
||||
#define occam_stop(pos, format, args...) \
|
||||
do { \
|
||||
EXTERNAL_CALLN (fprintf, stderr, "Program stopped at %s: " format "\n", pos, ##args); \
|
||||
SetErr (); \
|
||||
} while (0)
|
||||
|
||||
static int occam_check_slice (int start, int count, int limit, const char *pos) {
|
||||
int end = start + count;
|
||||
if (end < 0 || end > limit) {
|
||||
occam_stop (pos, "invalid array slice from %d to %d (end should be 0 <= i <= %d)", start, end, limit);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
static int occam_check_index (int i, int limit, const char *pos) {
|
||||
if (i < 0 || i >= limit) {
|
||||
occam_stop (pos, "invalid array index %d (should be 0 <= i < %d)", i, limit);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/* FIXME All of these need to check for overflow and report errors appropriately. */
|
||||
|
|
4
fco2/testcases/checkindex.occ
Normal file
4
fco2/testcases/checkindex.occ
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROC P (CHAN OF BYTE in, out, err)
|
||||
[10]INT as:
|
||||
as[15] := 0
|
||||
:
|
5
fco2/testcases/checksize.occ
Normal file
5
fco2/testcases/checksize.occ
Normal file
|
@ -0,0 +1,5 @@
|
|||
PROC P (CHAN OF BYTE in, out, err)
|
||||
[10]INT as:
|
||||
[]INT bs IS [as FROM 5 FOR 6]:
|
||||
SKIP
|
||||
:
|
Loading…
Reference in New Issue
Block a user