https://gcc.gnu.org/g:0f93b290938d2a78adb7183104a86ce05ccd21de
commit r16-2676-g0f93b290938d2a78adb7183104a86ce05ccd21de Author: Robert Dubner <rdub...@symas.com> Date: Wed Jul 30 09:54:13 2025 -0400 cobol: Eliminate various errors. [PR120244] The following coding errors were located by running extended tests through valgrind. These changes repair the errors. gcc/cobol/ChangeLog: PR cobol/120244 * genapi.cc (get_level_88_domain): Increase array size for final byte. (psa_FldLiteralA): Use correct length in build_string_literal call. * scan.l: Use a loop instead of std:transform to avoid EOF overrun. * scan_ante.h (binary_integer_usage): Use a variable-length buffer. Diff: --- gcc/cobol/genapi.cc | 12 ++++++++++-- gcc/cobol/scan.l | 21 +++++++++++---------- gcc/cobol/scan_ante.h | 5 ++++- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/gcc/cobol/genapi.cc b/gcc/cobol/genapi.cc index 666802ea137e..20341643182e 100644 --- a/gcc/cobol/genapi.cc +++ b/gcc/cobol/genapi.cc @@ -531,6 +531,14 @@ get_level_88_domain(size_t parent_capacity, cbl_field_t *var, size_t &returned_s free(stream); domain += 1; } + + if( returned_size >= retval_capacity) + { + retval_capacity *= 2; + retval = static_cast<char *>(xrealloc(retval, retval_capacity)); + } + + gcc_assert(returned_size < retval_capacity); retval[returned_size++] = '\0'; return retval; } @@ -16765,9 +16773,9 @@ psa_FldLiteralA(struct cbl_field_t *field ) vs_file_static); actually_create_the_static_field( field, - build_string_literal(field->data.capacity+1, + build_string_literal(field->data.capacity, buffer), - field->data.capacity+1, + field->data.capacity, field->data.initial, NULL_TREE, field->var_decl_node); diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l index 2da38d82a2e7..ba4c044e15e3 100644 --- a/gcc/cobol/scan.l +++ b/gcc/cobol/scan.l @@ -1673,16 +1673,17 @@ B-SHIFT-RC p += 2; while( ISSPACE(*p) ) p++; cbl_name_t name2; - std::transform( p, p + sizeof(name2), name2, - []( char ch ) { - switch(ch) { - case '-': - case '_': return ch; - default: - if( ISALNUM(ch) ) return ch; - } - return '\0'; - } ); + const char *pend = p + sizeof(name2); + char *pout = name2; + while( p < pend ) { + char ch = *p++; + if( ISALNUM(ch) || ch == '-' || ch == '_' ) { + *pout++ = ch; + } else { + *pout++ = '\0'; + break; + } + } symbol_elem_t *e = symbol_file(PROGRAM, name2); /* * For NAME IN FILENAME, we want the parser to handle it. diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h index 19ceb2b4a08b..c00826d652fd 100644 --- a/gcc/cobol/scan_ante.h +++ b/gcc/cobol/scan_ante.h @@ -609,7 +609,9 @@ static const std::map <std::string, bint_t > binary_integers { static int binary_integer_usage( const char name[]) { - cbl_name_t uname = {}; + // uname can't be cbl_name_t, because at this point name[] might have more + // than sizeof(cbl_name_t) characters. The length check comes later. + char *uname = xstrdup(name); std::transform(name, name + strlen(name), uname, ftoupper); dbgmsg("%s:%d: checking %s in %zu keyword_aliases", @@ -628,6 +630,7 @@ binary_integer_usage( const char name[]) { yylval.computational.signable = p->second.signable; dbgmsg("%s:%d: %s has type %d", __func__, __LINE__, uname, p->second.type ); + free(uname); return p->second.token; }