On Sat, 15 Nov 2025, Jakub Jelinek wrote: > Hi! > > I've tried to test a patch to switch -std=gnu++17 C++ default > to -std=gnu++20 (will post momentarily), but ran into various problems > during GCC bootstraps, our codebase isn't fully C++20 ready. > > The most common problems are arithmetic or bitwise operations > between enumerators of different enum types (or between enumerator > and floating point in the testsuite), ambiguous overloaded > operator == because of forgotten const qualification of const inside > of the argument and then libcody being largely stuck in C++ and incompatible > with C++20 which introduced char8_t type and uses it for u8 literals. > > The following patch fixes various issues I've run into, for libcody > this patch just makes sure code including cody.hh can be compiled > with -std=gnu++20, libcody itself I have a tweak in the other patch. > > Nothing in this patch will make the code invalid for C++14. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. > 2025-11-15 Jakub Jelinek <[email protected]> > > gcc/ > * tree-core.h (enum built_in_function): Avoid arithmetics or > bitwise operations between enumerators from different enums. > * lto-streamer.h (lto_tag_is_gimple_code_p): Likewise. > * gimple.h (gimple_omp_atomic_set_memory_order): Likewise. > * common/config/i386/i386-cpuinfo.h (M_CPU_SUBTYPE_START, > M_CPU_TYPE): Likewise. > * tree-complex.cc (expand_complex_libcall): Likewise. > * ipa-modref-tree.h (modref_access_node::operator ==): Change > argument type from modref_access_node & to > const modref_access_node &. > * ipa-modref-tree.cc (modref_access_node::operator ==): Likewise. > gcc/cobol/ > * symbols.cc (symbol_table_init): Avoid arithmetics or > bitwise operations between enumerators from different enums. > gcc/fortran/ > * parse.cc (gfc_parse_file): Avoid arithmetics or > bitwise operations between enumerators from different enums. > libcody/ > * cody.hh (MessageBuffer::Space): For C++14 or newer use > (char) u8' ' instead of Detail::S2C(u8" "). > > --- gcc/tree-core.h.jj 2025-11-08 14:44:20.509435479 +0100 > +++ gcc/tree-core.h 2025-11-15 18:58:36.302499125 +0100 > @@ -190,14 +190,12 @@ enum built_in_function { > BUILT_IN_COMPLEX_MUL_MIN, > BUILT_IN_COMPLEX_MUL_MAX > = BUILT_IN_COMPLEX_MUL_MIN > - + MAX_MODE_COMPLEX_FLOAT > - - MIN_MODE_COMPLEX_FLOAT, > + + (MAX_MODE_COMPLEX_FLOAT - MIN_MODE_COMPLEX_FLOAT), > > BUILT_IN_COMPLEX_DIV_MIN, > BUILT_IN_COMPLEX_DIV_MAX > = BUILT_IN_COMPLEX_DIV_MIN > - + MAX_MODE_COMPLEX_FLOAT > - - MIN_MODE_COMPLEX_FLOAT, > + + (MAX_MODE_COMPLEX_FLOAT - MIN_MODE_COMPLEX_FLOAT), > > /* Upper bound on non-language-specific builtins. */ > END_BUILTINS > --- gcc/lto-streamer.h.jj 2025-11-08 14:44:20.438436479 +0100 > +++ gcc/lto-streamer.h 2025-11-15 18:46:04.906102252 +0100 > @@ -990,7 +990,7 @@ lto_tag_is_gimple_code_p (enum LTO_tags > { > return (unsigned) tag >= LTO_first_gimple_tag > && (unsigned) tag > - < LTO_first_gimple_tag + LAST_AND_UNUSED_GIMPLE_CODE; > + < (unsigned) LTO_first_gimple_tag + LAST_AND_UNUSED_GIMPLE_CODE; > } > > > --- gcc/ipa-modref-tree.cc.jj 2025-01-02 20:54:32.261128094 +0100 > +++ gcc/ipa-modref-tree.cc 2025-11-15 18:51:49.975233199 +0100 > @@ -32,7 +32,7 @@ along with GCC; see the file COPYING3. > > /* Return true if both accesses are the same. */ > bool > -modref_access_node::operator == (modref_access_node &a) const > +modref_access_node::operator == (const modref_access_node &a) const > { > if (parm_index != a.parm_index) > return false; > --- gcc/ipa-modref-tree.h.jj 2025-01-02 20:54:32.261128094 +0100 > +++ gcc/ipa-modref-tree.h 2025-11-15 18:52:32.205637310 +0100 > @@ -96,7 +96,7 @@ struct GTY(()) modref_access_node > /* Dump range to debug OUT. */ > void dump (FILE *out); > /* Return true if both accesses are the same. */ > - bool operator == (modref_access_node &a) const; > + bool operator == (const modref_access_node &a) const; > /* Return true if range info is useful. */ > bool range_info_useful_p () const; > /* Return tree corresponding to parameter of the range in STMT. */ > --- gcc/gimple.h.jj 2025-11-08 14:44:20.433436549 +0100 > +++ gcc/gimple.h 2025-11-15 18:45:05.152945394 +0100 > @@ -2559,7 +2559,7 @@ gimple_omp_atomic_set_memory_order (gimp > if (gimple_code (g) != GIMPLE_OMP_ATOMIC_LOAD) > GIMPLE_CHECK (g, GIMPLE_OMP_ATOMIC_STORE); > g->subcode = ((g->subcode & ~GF_OMP_ATOMIC_MEMORY_ORDER) > - | (mo & GF_OMP_ATOMIC_MEMORY_ORDER)); > + | (int (mo) & GF_OMP_ATOMIC_MEMORY_ORDER)); > } > > > --- gcc/common/config/i386/i386-cpuinfo.h.jj 2025-10-29 22:25:56.153324579 > +0100 > +++ gcc/common/config/i386/i386-cpuinfo.h 2025-11-15 19:09:01.164678625 > +0100 > @@ -285,7 +285,7 @@ enum processor_features > > #define M_CPU_TYPE_START (BUILTIN_VENDOR_MAX) > #define M_CPU_SUBTYPE_START \ > - (M_CPU_TYPE_START + BUILTIN_CPU_TYPE_MAX) > + (M_CPU_TYPE_START + int (BUILTIN_CPU_TYPE_MAX)) > #define M_VENDOR(a) (a) > -#define M_CPU_TYPE(a) (M_CPU_TYPE_START + a) > +#define M_CPU_TYPE(a) (M_CPU_TYPE_START + int (a)) > #define M_CPU_SUBTYPE(a) (M_CPU_SUBTYPE_START + a) > --- gcc/tree-complex.cc.jj 2025-05-21 21:11:52.937553026 +0200 > +++ gcc/tree-complex.cc 2025-11-15 18:57:11.481696445 +0100 > @@ -1042,10 +1042,10 @@ expand_complex_libcall (gimple_stmt_iter > > if (code == MULT_EXPR) > bcode = ((enum built_in_function) > - (BUILT_IN_COMPLEX_MUL_MIN + mode - MIN_MODE_COMPLEX_FLOAT)); > + (BUILT_IN_COMPLEX_MUL_MIN + (mode - MIN_MODE_COMPLEX_FLOAT))); > else if (code == RDIV_EXPR) > bcode = ((enum built_in_function) > - (BUILT_IN_COMPLEX_DIV_MIN + mode - MIN_MODE_COMPLEX_FLOAT)); > + (BUILT_IN_COMPLEX_DIV_MIN + (mode - MIN_MODE_COMPLEX_FLOAT))); > else > gcc_unreachable (); > fn = builtin_decl_explicit (bcode); > --- gcc/fortran/parse.cc.jj 2025-11-08 14:44:20.421436718 +0100 > +++ gcc/fortran/parse.cc 2025-11-15 19:30:39.760371388 +0100 > @@ -7793,45 +7793,53 @@ done: > { > case OMP_REQ_ATOMIC_MEM_ORDER_SEQ_CST: > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_SEQ_CST); > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_MEMORY_ORDER_SEQ_CST)); > break; > case OMP_REQ_ATOMIC_MEM_ORDER_ACQ_REL: > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_ACQ_REL); > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_MEMORY_ORDER_ACQ_REL)); > break; > case OMP_REQ_ATOMIC_MEM_ORDER_ACQUIRE: > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_ACQUIRE); > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_MEMORY_ORDER_ACQUIRE)); > break; > case OMP_REQ_ATOMIC_MEM_ORDER_RELAXED: > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_RELAXED); > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_MEMORY_ORDER_RELAXED)); > break; > case OMP_REQ_ATOMIC_MEM_ORDER_RELEASE: > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask | OMP_MEMORY_ORDER_RELEASE); > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_MEMORY_ORDER_RELEASE)); > break; > } > > if (omp_target_seen) > omp_requires_mask = (enum omp_requires) (omp_requires_mask > - | OMP_REQUIRES_TARGET_USED); > + | int (OMP_REQUIRES_TARGET_USED)); > if (omp_requires & OMP_REQ_REVERSE_OFFLOAD) > - omp_requires_mask = (enum omp_requires) (omp_requires_mask > - | OMP_REQUIRES_REVERSE_OFFLOAD); > + omp_requires_mask > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_REQUIRES_REVERSE_OFFLOAD)); > if (omp_requires & OMP_REQ_UNIFIED_ADDRESS) > - omp_requires_mask = (enum omp_requires) (omp_requires_mask > - | OMP_REQUIRES_UNIFIED_ADDRESS); > + omp_requires_mask > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_REQUIRES_UNIFIED_ADDRESS)); > if (omp_requires & OMP_REQ_UNIFIED_SHARED_MEMORY) > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask > - | OMP_REQUIRES_UNIFIED_SHARED_MEMORY); > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_REQUIRES_UNIFIED_SHARED_MEMORY)); > if (omp_requires & OMP_REQ_SELF_MAPS) > omp_requires_mask > - = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_SELF_MAPS); > + = (enum omp_requires) (omp_requires_mask | int > (OMP_REQUIRES_SELF_MAPS)); > if (omp_requires & OMP_REQ_DYNAMIC_ALLOCATORS) > - omp_requires_mask = (enum omp_requires) (omp_requires_mask > - | OMP_REQUIRES_DYNAMIC_ALLOCATORS); > + omp_requires_mask > + = (enum omp_requires) (omp_requires_mask > + | int (OMP_REQUIRES_DYNAMIC_ALLOCATORS)); > /* Do the parse tree dump. */ > gfc_current_ns = flag_dump_fortran_original ? gfc_global_ns_list : NULL; > > --- gcc/cobol/symbols.cc.jj 2025-11-14 18:34:43.612076839 +0100 > +++ gcc/cobol/symbols.cc 2025-11-15 19:26:52.873568723 +0100 > @@ -2270,20 +2270,20 @@ symbol_table_init(void) { > > // These should match the definitions in libgcobol/constants.cc > static cbl_field_t constants[] = { > - { FldAlphanumeric, space_value_e | constq | register_e, > + { FldAlphanumeric, space_value_e | int(constq) | register_e, > {1,1,0,0, " \0\xFF"}, 0, "SPACE" }, > - { FldAlphanumeric, space_value_e | constq | register_e, > + { FldAlphanumeric, space_value_e | int(constq) | register_e, > {1,1,0,0, " \0\xFF"}, 0, "SPACES" }, > - { FldAlphanumeric, low_value_e | constq | register_e, > + { FldAlphanumeric, low_value_e | int(constq) | register_e, > {1,1,0,0, "L\0\xFF"}, 0, "LOW_VALUES" }, > - { FldAlphanumeric, zero_value_e | constq | register_e, > + { FldAlphanumeric, zero_value_e | int(constq) | register_e, > {1,1,0,0, "0"}, 0, "ZEROS" }, > - { FldAlphanumeric, high_value_e | constq | register_e, > + { FldAlphanumeric, high_value_e | int(constq) | register_e, > {1,1,0,0, "H\0\xFF"}, 0, "HIGH_VALUES" }, > // IBM standard: QUOTE is a double-quote unless APOST compiler option > - { FldAlphanumeric, quote_value_e | constq | register_e , > + { FldAlphanumeric, quote_value_e | int(constq) | register_e , > {1,1,0,0, "\"\0\xFF"}, 0, "QUOTES" }, > - { FldPointer, constq | register_e , > + { FldPointer, int(constq) | register_e , > {8,8,0,0, zeroes_for_null_pointer}, 0, "NULLS" }, > // IBM defines TALLY > // 01 TALLY GLOBAL PICTURE 9(5) USAGE BINARY VALUE ZERO. > @@ -2421,9 +2421,9 @@ symbol_table_init(void) { > { FldNumericBin5, signable_e|register_e, {2,2,4,0, NULL}, 0, > "RETURN-CODE" }, > { FldNumericBin5, register_e, {2,2,4,0, NULL}, 0, "LINAGE-COUNTER" }, > { FldLiteralA, register_e, {0,0,0,0, "/dev/stdin"}, 0, > "_dev_stdin" }, > - { FldLiteralA, constq|register_e, {0,0,0,0, "/dev/stdout"}, 0, > "_dev_stdout" }, > - { FldLiteralA, constq|register_e, {0,0,0,0, "/dev/stderr"}, 0, > "_dev_stderr" }, > - { FldLiteralA, constq|register_e, {0,0,0,0, "/dev/null"}, 0, > "_dev_null" }, > + { FldLiteralA, int(constq)|register_e, {0,0,0,0, "/dev/stdout"}, 0, > "_dev_stdout" }, > + { FldLiteralA, int(constq)|register_e, {0,0,0,0, "/dev/stderr"}, 0, > "_dev_stderr" }, > + { FldLiteralA, int(constq)|register_e, {0,0,0,0, "/dev/null"}, 0, > "_dev_null" }, > }; > > assert(table.nelem + COUNT_OF(special_registers) < table.capacity); > --- libcody/cody.hh.jj 2020-12-17 13:33:09.848010662 +0100 > +++ libcody/cody.hh 2025-11-15 19:23:39.520293500 +0100 > @@ -110,7 +110,11 @@ public: > /// Add whitespace word separator. Multiple adjacent whitespace is fine. > void Space () > { > +#if __cpp_unicode_characters >= 201411 > + Append ((char) u8' '); > +#else > Append (Detail::S2C(u8" ")); > +#endif > } > > public: > > Jakub > > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
