Don't blow up when taking 0-length slices
This commit is contained in:
parent
8fae7c4015
commit
db8782dfcf
|
@ -363,8 +363,16 @@ CHAN OF INT c: Channel c; Channel *c;
|
|||
I suspect there's probably a nicer way of doing this, but as a translation of
|
||||
the above table this isn't too horrible...
|
||||
-}
|
||||
-- | Generate C code for a variable.
|
||||
genVariable :: A.Variable -> CGen ()
|
||||
genVariable v
|
||||
genVariable = genVariable' True
|
||||
|
||||
-- | Generate C code for a variable without doing any range checks.
|
||||
genVariableUnchecked :: A.Variable -> CGen ()
|
||||
genVariableUnchecked = genVariable' False
|
||||
|
||||
genVariable' :: Bool -> A.Variable -> CGen ()
|
||||
genVariable' checkValid v
|
||||
= do am <- abbrevModeOfVariable v
|
||||
t <- typeOfVariable v
|
||||
let isSub = case v of
|
||||
|
@ -389,7 +397,7 @@ genVariable v
|
|||
inner sv@(A.SubscriptedVariable _ (A.Subscript _ _) _)
|
||||
= do let (es, v) = collectSubs sv
|
||||
genVariable v
|
||||
genArraySubscript v es
|
||||
genArraySubscript checkValid v es
|
||||
inner (A.SubscriptedVariable _ (A.SubscriptField m n) v)
|
||||
= do genVariable v
|
||||
tell ["->"]
|
||||
|
@ -409,8 +417,8 @@ genVariable v
|
|||
(es', v') = collectSubs v
|
||||
collectSubs v = ([], v)
|
||||
|
||||
genArraySubscript :: A.Variable -> [A.Expression] -> CGen ()
|
||||
genArraySubscript v es
|
||||
genArraySubscript :: Bool -> A.Variable -> [A.Expression] -> CGen ()
|
||||
genArraySubscript checkValid v es
|
||||
= do t <- typeOfVariable v
|
||||
let numDims = case t of A.Array ds _ -> length ds
|
||||
tell ["["]
|
||||
|
@ -428,13 +436,15 @@ genArraySubscript v es
|
|||
where
|
||||
gen = sequence_ $ intersperse (tell [" * "]) $ genSub : genChunks
|
||||
genSub
|
||||
= do tell ["occam_check_index ("]
|
||||
genExpression e
|
||||
tell [", "]
|
||||
genVariable v
|
||||
tell ["_sizes[", show sub, "], "]
|
||||
genMeta (findMeta e)
|
||||
tell [")"]
|
||||
= if checkValid
|
||||
then do tell ["occam_check_index ("]
|
||||
genExpression e
|
||||
tell [", "]
|
||||
genVariable v
|
||||
tell ["_sizes[", show sub, "], "]
|
||||
genMeta (findMeta e)
|
||||
tell [")"]
|
||||
else genExpression e
|
||||
genChunks = [genVariable v >> tell ["_sizes[", show i, "]"] | i <- subs]
|
||||
--}}}
|
||||
|
||||
|
@ -668,7 +678,9 @@ genReplicatorSize rep = genExpression (sizeOfReplicator rep)
|
|||
|
||||
genSlice :: A.Variable -> A.Variable -> A.Expression -> A.Expression -> [A.Dimension] -> (CGen (), A.Name -> CGen ())
|
||||
genSlice v (A.Variable _ on) start count ds
|
||||
= (tell ["&"] >> genVariable v,
|
||||
-- We need to disable the index check here because we might be taking
|
||||
-- element 0 of a 0-length array -- which is valid.
|
||||
= (tell ["&"] >> genVariableUnchecked v,
|
||||
genArraySize False
|
||||
(do tell ["occam_check_slice ("]
|
||||
genExpression start
|
||||
|
|
|
@ -54,8 +54,10 @@
|
|||
static int occam_check_slice (int, int, int, const char *) occam_unused;
|
||||
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);
|
||||
if (count != 0 && (start < 0 || start >= limit
|
||||
|| end < 0 || end > limit
|
||||
|| count < 0)) {
|
||||
occam_stop (pos, "invalid array slice from %d to %d (should be 0 <= i <= %d)", start, end, limit);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user