diff --git a/fco2/GenerateC.hs b/fco2/GenerateC.hs index 990ebbc..b5b12e5 100644 --- a/fco2/GenerateC.hs +++ b/fco2/GenerateC.hs @@ -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, "]"] diff --git a/fco2/fco_support.h b/fco2/fco_support.h index 85ce3d9..c78e78c 100644 --- a/fco2/fco_support.h +++ b/fco2/fco_support.h @@ -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. */ diff --git a/fco2/testcases/checkindex.occ b/fco2/testcases/checkindex.occ new file mode 100644 index 0000000..916ca68 --- /dev/null +++ b/fco2/testcases/checkindex.occ @@ -0,0 +1,4 @@ +PROC P (CHAN OF BYTE in, out, err) + [10]INT as: + as[15] := 0 +: diff --git a/fco2/testcases/checksize.occ b/fco2/testcases/checksize.occ new file mode 100644 index 0000000..2b8362a --- /dev/null +++ b/fco2/testcases/checksize.occ @@ -0,0 +1,5 @@ +PROC P (CHAN OF BYTE in, out, err) + [10]INT as: + []INT bs IS [as FROM 5 FOR 6]: + SKIP +: