f26259caac
In ego, the CS phase may convert a LAR/SAR to AAR LOI/STI so it can optimize multiple occurrences of AAR of the same array element. This conversion should not happen if it would LOI/STI a large or unknown size. cs_profit.c okay_lines() checked the size of each occurrence of AAR except the first. If the first AAR was the implicit AAR in a LAR/SAR, then the conversion happened without checking the size. For unknown size, this made a bad LOI -1 or STI -1. Fix by checking the size earlier: if a LAR/SAR has a bad size, then don't enter it as an AAR. This Modula-2 code showed the bug. Given M.def: DEFINITION MODULE M; TYPE S = SET OF [0..95]; PROCEDURE F(a: ARRAY OF S; i, j: INTEGER); END M. and M.mod: (*$R-*) IMPLEMENTATION MODULE M; FROM SYSTEM IMPORT ADDRESS, ADR; PROCEDURE G(s: S; p, q: ADDRESS; t: S); BEGIN s := s; p := p; q := q; t := t; END G; PROCEDURE F(a: ARRAY OF S; i, j: INTEGER); BEGIN G(a[i + j], ADR(a[i + j]), ADR(a[i + j]), a[i + j]) END F; END M. then the bug caused an error: $ ack -mlinuxppc -O3 -c.e M.mod /tmp/Ack_b357d.g, line 57: Argument range error The bug had put LOI -1 in the code, then em_decode got an error because -1 is out of range for LOI. Procedure F has 4 occurrences of `a[i + j]`. The size of `a[i + j]` is 96 bits, or 12 bytes, but the EM code hides the size in an array descriptor, so the size is unknown to CS. The pragma `(*$R-*)` disables a range check on `i + j` so CS can work. EM uses AAR for the 2 `ADR(a[i + j])` and LAR for the other 2 `a[i + j]`. EM pushes the arguments to G in reverse order, so the last `a[i + j]` in Modula-2 is the first LAR in EM. CS found 4 occurrences of AAR. The first AAR was an implicit AAR in LAR. Because of the bug, CS converted this LAR 4 to AAR 4 LOI -1. |
||
---|---|---|
.. | ||
cs.c | ||
cs.h | ||
cs_alloc.c | ||
cs_alloc.h | ||
cs_aux.c | ||
cs_aux.h | ||
cs_avail.c | ||
cs_avail.h | ||
cs_debug.c | ||
cs_debug.h | ||
cs_elim.c | ||
cs_elim.h | ||
cs_entity.c | ||
cs_entity.h | ||
cs_getent.c | ||
cs_getent.h | ||
cs_kill.c | ||
cs_kill.h | ||
cs_partit.c | ||
cs_partit.h | ||
cs_profit.c | ||
cs_profit.h | ||
cs_stack.c | ||
cs_stack.h | ||
cs_vnm.c | ||
cs_vnm.h |