fix: ARRAY type of itself caused crash;
better implementation of ranges in CASE labels
This commit is contained in:
parent
a771c9aa30
commit
8e6fe7258c
2 changed files with 80 additions and 72 deletions
|
@ -52,7 +52,7 @@ struct switch_hdr {
|
||||||
struct case_entry {
|
struct case_entry {
|
||||||
struct case_entry *ce_next; /* next in list */
|
struct case_entry *ce_next; /* next in list */
|
||||||
label ce_label; /* generated label */
|
label ce_label; /* generated label */
|
||||||
arith ce_value; /* value of case label */
|
arith ce_low, ce_up; /* lower and upper bound of range */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* STATICALLOCDEF "case_entry" 20 */
|
/* STATICALLOCDEF "case_entry" 20 */
|
||||||
|
@ -147,14 +147,20 @@ CaseCode(nd, exitlabel, end_reached)
|
||||||
if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) {
|
if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) {
|
||||||
/* CSA
|
/* CSA
|
||||||
*/
|
*/
|
||||||
|
int gen = 1;
|
||||||
|
|
||||||
ce = sh->sh_entries;
|
ce = sh->sh_entries;
|
||||||
C_rom_cst((arith) 0);
|
C_rom_cst((arith) 0);
|
||||||
C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd);
|
C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd);
|
||||||
for (val = sh->sh_lowerbd; val <= sh->sh_upperbd; val++) {
|
for (val = sh->sh_lowerbd; val <= sh->sh_upperbd; val++) {
|
||||||
assert(ce);
|
assert(ce);
|
||||||
if (val == ce->ce_value) {
|
if (gen || val == ce->ce_low) {
|
||||||
|
gen = 1;
|
||||||
C_rom_ilb(ce->ce_label);
|
C_rom_ilb(ce->ce_label);
|
||||||
ce = ce->ce_next;
|
if (val == ce->ce_up) {
|
||||||
|
gen = 0;
|
||||||
|
ce = ce->ce_next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (sh->sh_default) C_rom_ilb(sh->sh_default);
|
else if (sh->sh_default) C_rom_ilb(sh->sh_default);
|
||||||
else C_rom_ucon("0", pointer_size);
|
else C_rom_ucon("0", pointer_size);
|
||||||
|
@ -171,8 +177,11 @@ CaseCode(nd, exitlabel, end_reached)
|
||||||
for (ce = sh->sh_entries; ce; ce = ce->ce_next) {
|
for (ce = sh->sh_entries; ce; ce = ce->ce_next) {
|
||||||
/* generate the entries: value + prog.label
|
/* generate the entries: value + prog.label
|
||||||
*/
|
*/
|
||||||
C_rom_cst(ce->ce_value);
|
val = ce->ce_low;
|
||||||
C_rom_ilb(ce->ce_label);
|
do {
|
||||||
|
C_rom_cst(val);
|
||||||
|
C_rom_ilb(ce->ce_label);
|
||||||
|
} while (val++ != ce->ce_up);
|
||||||
}
|
}
|
||||||
c_lae_dlb(CaseDescrLab); /* perform the switch */
|
c_lae_dlb(CaseDescrLab); /* perform the switch */
|
||||||
C_csb(word_size);
|
C_csb(word_size);
|
||||||
|
@ -238,15 +247,7 @@ AddCases(sh, node, lbl)
|
||||||
assert(node->nd_left->nd_class == Value);
|
assert(node->nd_left->nd_class == Value);
|
||||||
assert(node->nd_right->nd_class == Value);
|
assert(node->nd_right->nd_class == Value);
|
||||||
|
|
||||||
node->nd_type = node->nd_left->nd_type;
|
AddOneCase(sh, node->nd_left, node->nd_right, lbl);
|
||||||
node->nd_INT = node->nd_left->nd_INT;
|
|
||||||
for (;;) {
|
|
||||||
AddOneCase(sh, node, lbl);
|
|
||||||
if (node->nd_INT == node->nd_right->nd_INT) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
node->nd_INT++;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,12 +258,12 @@ AddCases(sh, node, lbl)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(node->nd_class == Value);
|
assert(node->nd_class == Value);
|
||||||
AddOneCase(sh, node, lbl);
|
AddOneCase(sh, node, node, lbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddOneCase(sh, node, lbl)
|
AddOneCase(sh, lnode, rnode, lbl)
|
||||||
register struct switch_hdr *sh;
|
register struct switch_hdr *sh;
|
||||||
t_node *node;
|
t_node *lnode, *rnode;
|
||||||
label lbl;
|
label lbl;
|
||||||
{
|
{
|
||||||
register struct case_entry *ce = new_case_entry();
|
register struct case_entry *ce = new_case_entry();
|
||||||
|
@ -270,29 +271,30 @@ AddOneCase(sh, node, lbl)
|
||||||
int fund = sh->sh_type->tp_fund;
|
int fund = sh->sh_type->tp_fund;
|
||||||
|
|
||||||
ce->ce_label = lbl;
|
ce->ce_label = lbl;
|
||||||
ce->ce_value = node->nd_INT;
|
ce->ce_low = lnode->nd_INT;
|
||||||
if (! ChkCompat(&node, sh->sh_type, "case")) {
|
ce->ce_up = rnode->nd_INT;
|
||||||
|
if (! ChkCompat(&lnode, sh->sh_type, "case") ||
|
||||||
|
! ChkCompat(&rnode, sh->sh_type, "case")) {
|
||||||
}
|
}
|
||||||
if (sh->sh_entries == 0) {
|
if (sh->sh_entries == 0) {
|
||||||
/* first case entry
|
/* first case entry
|
||||||
*/
|
*/
|
||||||
ce->ce_next = (struct case_entry *) 0;
|
|
||||||
sh->sh_entries = ce;
|
sh->sh_entries = ce;
|
||||||
sh->sh_lowerbd = sh->sh_upperbd = ce->ce_value;
|
sh->sh_lowerbd = ce->ce_low;
|
||||||
sh->sh_nrofentries = 1;
|
sh->sh_upperbd = ce->ce_up;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* second etc. case entry
|
/* second etc. case entry
|
||||||
find the proper place to put ce into the list
|
find the proper place to put ce into the list
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (chk_bounds(ce->ce_value, sh->sh_lowerbd, fund)) {
|
if (chk_bounds(ce->ce_low, sh->sh_lowerbd, fund)) {
|
||||||
sh->sh_lowerbd = ce->ce_value;
|
sh->sh_lowerbd = ce->ce_low;
|
||||||
}
|
}
|
||||||
else if (! chk_bounds(ce->ce_value, sh->sh_upperbd, fund)) {
|
if (! chk_bounds(ce->ce_up, sh->sh_upperbd, fund)) {
|
||||||
sh->sh_upperbd = ce->ce_value;
|
sh->sh_upperbd = ce->ce_up;
|
||||||
}
|
}
|
||||||
while (c1 && !chk_bounds(ce->ce_value, c1->ce_value, fund)) {
|
while (c1 &&! chk_bounds(ce->ce_up, c1->ce_low, fund)) {
|
||||||
c2 = c1;
|
c2 = c1;
|
||||||
c1 = c1->ce_next;
|
c1 = c1->ce_next;
|
||||||
}
|
}
|
||||||
|
@ -306,11 +308,14 @@ AddOneCase(sh, node, lbl)
|
||||||
The case c1 == 0 && c2 == 0 cannot occur, since
|
The case c1 == 0 && c2 == 0 cannot occur, since
|
||||||
the list is guaranteed not to be empty.
|
the list is guaranteed not to be empty.
|
||||||
*/
|
*/
|
||||||
if (c1) {
|
if (c2) {
|
||||||
if (c1->ce_value == ce->ce_value) {
|
if ( chk_bounds(ce->ce_low, c2->ce_up, fund)) {
|
||||||
node_error(node, "multiple case entry for value %ld", ce->ce_value);
|
node_error(rnode, "multiple case entry for value %ld", (long)(ce->ce_low));
|
||||||
free_case_entry(ce);
|
free_case_entry(ce);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (c1) {
|
||||||
if (c2) {
|
if (c2) {
|
||||||
ce->ce_next = c2->ce_next;
|
ce->ce_next = c2->ce_next;
|
||||||
c2->ce_next = ce;
|
c2->ce_next = ce;
|
||||||
|
@ -323,9 +328,8 @@ node_error(node, "multiple case entry for value %ld", ce->ce_value);
|
||||||
else {
|
else {
|
||||||
assert(c2);
|
assert(c2);
|
||||||
|
|
||||||
ce->ce_next = (struct case_entry *) 0;
|
|
||||||
c2->ce_next = ce;
|
c2->ce_next = ce;
|
||||||
}
|
}
|
||||||
(sh->sh_nrofentries)++;
|
|
||||||
}
|
}
|
||||||
|
sh->sh_nrofentries += ce->ce_up - ce->ce_low + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,16 +150,17 @@ FPSection(t_param **ppr; arith *parmaddr;)
|
||||||
{ EnterParamList(ppr, FPList, tp, VARp, parmaddr); }
|
{ EnterParamList(ppr, FPList, tp, VARp, parmaddr); }
|
||||||
;
|
;
|
||||||
|
|
||||||
FormalType(t_type **ptp;) :
|
FormalType(t_type **ptp;)
|
||||||
ARRAY OF qualtype(ptp)
|
/* index type of conformant array is "CARDINAL".
|
||||||
{ /* index type of conformant array is "CARDINAL".
|
Recognize a conformant array by size 0.
|
||||||
Recognize a conformant array by size 0.
|
*/
|
||||||
*/
|
{ register t_type *tp;
|
||||||
register t_type *tp = construct_type(T_ARRAY, card_type);
|
} :
|
||||||
|
ARRAY OF
|
||||||
tp->arr_elem = *ptp;
|
{ tp = construct_type(T_ARRAY, card_type); }
|
||||||
|
qualtype(&(tp->arr_elem))
|
||||||
|
{ ArrayElSize(tp);
|
||||||
*ptp = tp;
|
*ptp = tp;
|
||||||
ArrayElSize(tp);
|
|
||||||
}
|
}
|
||||||
|
|
|
|
||||||
qualtype(ptp)
|
qualtype(ptp)
|
||||||
|
@ -206,7 +207,7 @@ SimpleType(register t_type **ptp;) :
|
||||||
]
|
]
|
||||||
|
|
|
|
||||||
enumeration(ptp)
|
enumeration(ptp)
|
||||||
| { *ptp = 0; }
|
| { *ptp = 0; /* no qualification */ }
|
||||||
SubrangeType(ptp)
|
SubrangeType(ptp)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -252,10 +253,10 @@ SubrangeType(t_type **ptp;)
|
||||||
ArrayType(t_type **ptp;)
|
ArrayType(t_type **ptp;)
|
||||||
{
|
{
|
||||||
t_type *tp;
|
t_type *tp;
|
||||||
register t_type *tp2;
|
register t_type *tp1, *tp2;
|
||||||
} :
|
} :
|
||||||
ARRAY SimpleType(&tp)
|
ARRAY SimpleType(&tp)
|
||||||
{ *ptp = tp2 = construct_type(T_ARRAY, tp); }
|
{ tp1 = tp2 = construct_type(T_ARRAY, tp); }
|
||||||
[
|
[
|
||||||
',' SimpleType(&tp)
|
',' SimpleType(&tp)
|
||||||
{ tp2->arr_elem = construct_type(T_ARRAY, tp);
|
{ tp2->arr_elem = construct_type(T_ARRAY, tp);
|
||||||
|
@ -263,7 +264,8 @@ ArrayType(t_type **ptp;)
|
||||||
}
|
}
|
||||||
]* OF type(&tp)
|
]* OF type(&tp)
|
||||||
{ tp2->arr_elem = tp;
|
{ tp2->arr_elem = tp;
|
||||||
ArraySizes(*ptp);
|
ArraySizes(tp1);
|
||||||
|
*ptp = tp1;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -437,23 +439,28 @@ CaseLabels(t_type **ptp; register t_node **pnd;)
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
SetType(t_type **ptp;) :
|
SetType(t_type **ptp;)
|
||||||
SET OF SimpleType(ptp)
|
{ t_type *tp;
|
||||||
{ *ptp = set_type(*ptp); }
|
} :
|
||||||
|
SET OF SimpleType(&tp)
|
||||||
|
{ *ptp = set_type(tp); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/* In a pointer type definition, the type pointed at does not
|
/* In a pointer type definition, the type pointed at does not
|
||||||
have to be declared yet, so be careful about identifying
|
have to be declared yet, so be careful about identifying
|
||||||
type-identifiers
|
type-identifiers.
|
||||||
*/
|
*/
|
||||||
PointerType(register t_type **ptp;) :
|
PointerType(register t_type **ptp;)
|
||||||
{ *ptp = construct_type(T_POINTER, NULLTYPE); }
|
{ register t_type *tp;
|
||||||
|
} :
|
||||||
|
{ tp = construct_type(T_POINTER, NULLTYPE); }
|
||||||
POINTER TO
|
POINTER TO
|
||||||
[ %if (type_or_forward(ptp))
|
[ %if (type_or_forward(tp))
|
||||||
type(&((*ptp)->tp_next))
|
type(&(tp->tp_next))
|
||||||
|
|
|
|
||||||
IDENT
|
IDENT
|
||||||
]
|
]
|
||||||
|
{ *ptp = tp; }
|
||||||
;
|
;
|
||||||
|
|
||||||
qualtype(t_type **ptp;)
|
qualtype(t_type **ptp;)
|
||||||
|
@ -464,46 +471,43 @@ qualtype(t_type **ptp;)
|
||||||
{ *ptp = qualified_type(nd); }
|
{ *ptp = qualified_type(nd); }
|
||||||
;
|
;
|
||||||
|
|
||||||
ProcedureType(t_type **ptp;) :
|
ProcedureType(t_type **ptp;)
|
||||||
PROCEDURE
|
|
||||||
[
|
|
||||||
FormalTypeList(ptp)
|
|
||||||
|
|
|
||||||
{ *ptp = proc_type((t_type *) 0,
|
|
||||||
(t_param *) 0,
|
|
||||||
(arith) 0);
|
|
||||||
}
|
|
||||||
]
|
|
||||||
;
|
|
||||||
|
|
||||||
FormalTypeList(t_type **ptp;)
|
|
||||||
{
|
{
|
||||||
t_param *pr = 0;
|
t_param *pr = 0;
|
||||||
arith parmaddr = 0;
|
arith parmaddr = 0;
|
||||||
|
t_type *tp = 0;
|
||||||
} :
|
} :
|
||||||
|
PROCEDURE
|
||||||
|
[
|
||||||
|
FormalTypeList(&pr, &parmaddr, &tp)
|
||||||
|
|
|
||||||
|
]
|
||||||
|
{ *ptp = proc_type(tp, pr, parmaddr); }
|
||||||
|
;
|
||||||
|
|
||||||
|
FormalTypeList(t_param **ppr; arith *pparmaddr; t_type **ptp;) :
|
||||||
'('
|
'('
|
||||||
[
|
[
|
||||||
VarFormalType(&pr, &parmaddr)
|
VarFormalType(ppr, pparmaddr)
|
||||||
[
|
[
|
||||||
',' VarFormalType(&pr, &parmaddr)
|
',' VarFormalType(ppr, pparmaddr)
|
||||||
]*
|
]*
|
||||||
|
|
|
|
||||||
]
|
]
|
||||||
')'
|
')'
|
||||||
[ ':' qualtype(ptp)
|
[ ':' qualtype(ptp)
|
||||||
| { *ptp = 0; }
|
|
|
||||||
]
|
]
|
||||||
{ *ptp = proc_type(*ptp, pr, parmaddr); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
VarFormalType(t_param **ppr; arith *parmaddr;)
|
VarFormalType(t_param **ppr; arith *pparmaddr;)
|
||||||
{
|
{
|
||||||
t_type *tp;
|
t_type *tp;
|
||||||
int isvar;
|
int isvar;
|
||||||
} :
|
} :
|
||||||
var(&isvar)
|
var(&isvar)
|
||||||
FormalType(&tp)
|
FormalType(&tp)
|
||||||
{ EnterParamList(ppr,NULLNODE,tp,isvar,parmaddr); }
|
{ EnterParamList(ppr,NULLNODE,tp,isvar,pparmaddr); }
|
||||||
;
|
;
|
||||||
|
|
||||||
var(int *VARp;) :
|
var(int *VARp;) :
|
||||||
|
|
Loading…
Add table
Reference in a new issue