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?

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

Reply via email to