diff --git a/gcc/cobol/symbols.cc b/gcc/cobol/symbols.cc index d19c8faaaa6ca90a735c38e5cc492905ea5e75ff..43383171ae4b0a62045a6fdf74fa812f67d72063 100644 --- a/gcc/cobol/symbols.cc +++ b/gcc/cobol/symbols.cc @@ -1162,6 +1162,38 @@ symbols_dump( size_t first, bool header ) { return ninvalid; } +static bool +grow_redefined_group( cbl_field_t *redefined, const cbl_field_t *field ) { + assert(redefined); + assert(field); + assert(redefined == symbol_redefines(field)); + + + /* + * 8) The storage area required for the subject of the entry + * shall not be larger than the storage area required for the + * data item referenced by data-name-2, unless the data item + * referenced by data- name-2 has been specified with level + * number 1 and without the EXTERNAL clause. + */ + + if( 1 < redefined->level ) { + if( field_memsize(redefined) < field_memsize(field) ) { + yyerrorv("error: line %d: %s (size %u) larger than REDEFINES %s (size %u)", + field->line, + field->name, field_memsize(field), + redefined->name, field_memsize(redefined)); + return false; + } + } + + redefined->data.memsize = std::max(field_memsize(redefined), + field_memsize(field)); + + return true; +} + + /* * Input is a symbol-table element, always a field. * For elementary fields, return the input. @@ -1257,6 +1289,7 @@ static struct symbol_elem_t * e--; // set e to last symbol processed (not next one, because ++e) } +#if 0 cbl_field_t *redefined = symbol_redefines(field); /* @@ -1292,7 +1325,7 @@ static struct symbol_elem_t * continue; } } - +#endif members.push_back(field); } @@ -1310,8 +1343,13 @@ static struct symbol_elem_t * for( auto field : members ) { cbl_field_t *redefined = symbol_redefines(field); if( redefined ) { - assert( group == redefined ); + if( group != redefined ) { + grow_redefined_group(redefined, field); + } max_memsize = std::max(max_memsize, field_memsize(field)); + + field->data.memsize = 0; + if( redefined->data.memsize == redefined->data.capacity ) { redefined->data.memsize = 0; }