[gcc r17-3523] cobol: Allow larger REDEFINES for -dialect ibm.
"James K. Lowden via Gcc-cvs" <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:4918feee536ef3ef5431f87f0b314f6b03378981 commit r17-3523-g4918feee536ef3ef5431f87f0b314f6b03378981 Author: James K. Lowden <[email protected]> Date: Thu Aug 20 17:58:09 2026 -0400 cobol: Allow larger REDEFINES for -dialect ibm. ISO prohibits B REDEFINES A if B is larger than A, unless A is 01 level and not external. IBM and others do not impose the 01 restriction. Also simplify and correct how -preprocess parses its argument. gcc/cobol/ChangeLog: * cbldiag.h (enum cbl_diag_id_t): Define IsoRedefinesGrow. * cobol1.cc (cobol_langhook_handle_option): Handle Wredefines-grow. * lang-specs.h: Same. * lang.opt: Same. * lexio.cc (preprocess_filter_add): Use xstrdup, not std::vector. * messages.cc: Quell Wredefines-grow with -dialect ibm. * parse_ante.h (valid_redefine): Conditional message. Diff: --- gcc/cobol/cbldiag.h | 1 + gcc/cobol/cobol1.cc | 4 ++++ gcc/cobol/lang-specs.h | 1 + gcc/cobol/lang.opt | 5 +++++ gcc/cobol/lexio.cc | 9 ++++----- gcc/cobol/messages.cc | 6 ++++-- gcc/cobol/parse_ante.h | 18 +++++++++--------- 7 files changed, 28 insertions(+), 16 deletions(-) diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h index 5f88e15563a6..c05bfde7f39f 100644 --- a/gcc/cobol/cbldiag.h +++ b/gcc/cobol/cbldiag.h @@ -189,6 +189,7 @@ enum cbl_diag_id_t : uint64_t { IbmVolatileW, // dialect warning for ignored syntax IsoAssignFile, + IsoRedefinesGrow, IsoResume, MfAssignExternal, diff --git a/gcc/cobol/cobol1.cc b/gcc/cobol/cobol1.cc index eedaf600440a..79c6d507247e 100644 --- a/gcc/cobol/cobol1.cc +++ b/gcc/cobol/cobol1.cc @@ -645,6 +645,10 @@ cobol_langhook_handle_option (size_t scode, cobol_warning(MfRedefinesFirst, redefines_first, warning_as_error); return true; + case OPT_Wredefines_grow: + cobol_warning(IsoRedefinesGrow, redefines_grow, warning_as_error); + return true; + case OPT_Wreturning_number: cobol_warning(MfReturningNum, returning_number, warning_as_error); return true; diff --git a/gcc/cobol/lang-specs.h b/gcc/cobol/lang-specs.h index 272ef480b6ae..701a1d1a07a8 100644 --- a/gcc/cobol/lang-specs.h +++ b/gcc/cobol/lang-specs.h @@ -91,6 +91,7 @@ "%{Wprocedure-pointer} %{Wno-procedure-pointer} " "%{Wreplace-error} %{Wno-replace-error} " "%{Wredefines-first} %{Wno-redefines-first} " + "%{Wredefines-grow} %{Wno-redefines-grow} " "%{Wreturning-number} %{Wno-returning-number} " "%{Wsegment-error} %{Wno-segment-error} " "%{Wsegment-negative} %{Wno-segment-negative} " diff --git a/gcc/cobol/lang.opt b/gcc/cobol/lang.opt index 9e2f989b2626..8b0a575d1183 100644 --- a/gcc/cobol/lang.opt +++ b/gcc/cobol/lang.opt @@ -274,6 +274,11 @@ Wsegment Cobol Warning Var(cobol_segment, 1) Init(1) Warn if SECTION segments are used. +; IsoRedefinesGrow, "-Wredefines-grow" +Wredefines-grow +Cobol Warning Var(redefines_grow, 1) Init(1) +Warn if REDEFINES data item is larger than the redefined. + ; IsoResume Wcobol-resume Cobol Warning Var(cobol_resume, 1) Init(1) diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc index d4cb4a258f3c..f31f707ad02a 100644 --- a/gcc/cobol/lexio.cc +++ b/gcc/cobol/lexio.cc @@ -1443,12 +1443,11 @@ preprocess_filter_add( const char input[] ) { size_t pos = filter.find(","); if( pos != filter.npos ) { - std::vector<char> others( filter.size() - pos, '\0' ); - std::copy( filter.begin() + pos + 1, filter.end(), others.begin() ); + std::string args( filter.begin() + pos + 1, filter.end() ); filter.resize(pos); - char *optstr = others.data(); - for( char *opt = optstr + 1; (opt = strtok(opt, ",")); opt = NULL ) { - options.push_back(opt); + + for( char *arg = xstrdup(args.c_str()); (arg = strtok(arg, ",")); arg = NULL ) { + options.push_back(arg); } } diff --git a/gcc/cobol/messages.cc b/gcc/cobol/messages.cc index e55ab194dd79..eff05f98e442 100644 --- a/gcc/cobol/messages.cc +++ b/gcc/cobol/messages.cc @@ -137,10 +137,12 @@ std::set<cbl_diag_t> cbl_diagnostics { { IbmVolatileE, "-Wcobol-volatile", diagnostics::kind::error, dialect_ibm_e }, { IbmVolatileW, "-Wcobol-volatile", diagnostics::kind::warning, dialect_ibm_e }, - // RESUME not supported by IBM - { IsoResume, "-Wcobol-resume", diagnostics::kind::error, dialect_ibm_e }, // IBM, MF, and GNU all support ASSIGN TO filename, so we keep mum. { IsoAssignFile, "-Wassign-file", diagnostics::kind::ignored, dialect_ibm_mf_gnu }, + // ISO says for B REDEFINES A, Length(B) <= Length(A), others disagree + { IsoRedefinesGrow, "-Wredefines-grow", diagnostics::kind::error, dialect_ibm_mf_gnu }, + // RESUME not supported by IBM + { IsoResume, "-Wcobol-resume", diagnostics::kind::error, dialect_ibm_e }, { MfAnyLength, "-Wany-length", diagnostics::kind::error, dialect_mf_gnu }, { MfAssignExternal, "-Wassign-external", diagnostics::kind::error, dialect_mf_gnu }, diff --git a/gcc/cobol/parse_ante.h b/gcc/cobol/parse_ante.h index 243f43bbf1e7..2dff569a2b57 100644 --- a/gcc/cobol/parse_ante.h +++ b/gcc/cobol/parse_ante.h @@ -3145,8 +3145,6 @@ valid_redefine( const cbl_loc_t& loc, orig->level_str(), orig->name); return false; } - // We don't know about the redefining group until it's completely defined. - /* * 8) The storage area required for the subject of the entry * shall not be larger than the storage area required for the @@ -3159,13 +3157,15 @@ valid_redefine( const cbl_loc_t& loc, if( orig->level > 1 || orig->has_attr(external_e) ) { dbgmsg( "size error orig: %s", field_str(orig) ); dbgmsg( "size error redef: %s", field_str(field) ); - error_msg(loc, "%s (%s size %u) larger than REDEFINES %s (%s size %u)", - field->name, - 3 + cbl_field_type_str(field->type), - field->size()/field->codeset.stride(), - orig->name, - 3 + cbl_field_type_str(orig->type), - orig->size()/field->codeset.stride() ); + if( ! dialect_ok(loc, IsoRedefinesGrow, "REDEFINES larger") ) { + error_msg(loc, "%qs (%s size %u) larger than REDEFINES %qs (%s size %u)", + field->name, + 3 + cbl_field_type_str(field->type), + field->size()/field->codeset.stride(), + orig->name, + 3 + cbl_field_type_str(orig->type), + orig->size()/field->codeset.stride() ); + } } } }