On 2026-01-30 15:54, Richard Biener wrote:
On Fri, 30 Jan 2026, Torbjorn SVENSSON wrote:

Hi Richard,


On 2026-01-30 15:04, Richard Biener wrote:
On Fri, 30 Jan 2026, Torbjorn SVENSSON wrote:

Hi Richard,

Thanks for the quick reply.

On 2026-01-30 14:28, Richard Biener wrote:
On Fri, 30 Jan 2026, Torbjörn SVENSSON wrote:

Ok for trunk and releases/gcc-15?

--

When building GCC with host=mingw, the following warning can be seen
multiple times in the build log if the MinGW GCC version is older than
r13-4881-g9149a5b7e0a:

In file included from /build/gcc/c/c-typeck.cc:27:0:
/build/gcc/system.h:1172:0: warning: "CONST_CAST2" redefined
    #define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))

In file included from
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/include/c++/x86_64-w64-mingw32/bits/gthr.h:148:0,
                    from
                    
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/include/c++/ext/atomicity.h:35,
                    from
                    
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/include/c++/memory:73,
                    from /build/gcc/gcc/system.h:231,
                    from /build/gcc/gcc/c/c-typeck.cc:27:
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/include/c++/x86_64-w64-mingw32/bits/gthr-default.h:33:0:
note: this is the location of the previous definition
    #define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE
    _q; TOTYPE _nq;})(X))._nq)

To ensure that the recent definition is used, always undefine any
potential define before defining the new macro.

I think it's better if we'd remove CONST_CAST2 the few remaining
uses are all from within C++ code?


A simple grep shows the following references in C++ code:

gcc/tree-nested.cc:  tree *ref_p = CONST_CAST2 (tree *, const tree *,
(const
tree *)e);
gcc/collect2.cc:  const char **object_file = CONST_CAST2 (const char **,
char
**, object_lst);
gcc/collect2.cc:      lto_c_ptr = CONST_CAST2 (const char **, char **,
lto_c_argv);
gcc/collect2.cc:  ld1 = CONST_CAST2 (const char **, char **, ld1_argv);
gcc/collect2.cc:  ld2 = CONST_CAST2 (const char **, char **, ld2_argv);
gcc/collect2.cc:  object = CONST_CAST2 (const char **, char **,
object_lst);
gcc/collect2.cc:  c_ptr = CONST_CAST2 (const char **, char **, c_argv);
gcc/collect2.cc:                            object - CONST_CAST2 (const
char
**, char **,
gcc/collect2.cc:                          object = CONST_CAST2 (const char
**,
char **,
gcc/collect2.cc:      = CONST_CAST2 (const char **, char **, object_lst);
gcc/collect2.cc:          const char ** strip_argv = CONST_CAST2 (const
char
**, char **,
gcc/collect2.cc:  const char **nm_argv = CONST_CAST2 (const char **,
char**,
real_nm_argv);
gcc/collect2.cc:  const char **ldd_argv = CONST_CAST2 (const char **, char
**,
real_ldd_argv);
gcc/collect2.cc:  const char ** argv = CONST_CAST2 (const char **, char **,
gcc/config/sparc/driver-sparc.cc:      ksp = kstat_lookup (kc, CONST_CAST2
(char *, const char *, "cpu_info"),
gcc/config/sparc/driver-sparc.cc:         kstat_data_lookup (ksp,
CONST_CAST2
(char *, const char *, "brand"));
gcc/toplev.cc:                                          CONST_CAST2 (const
char **,

For the above files, it should be safe to replace CONST_CAST2() with
CONST_CAST() without any actual code change.


gcc/gcc-ar.cc:    CONST_CAST2 (char * const *, const char **, nargv) + 1,
f);
gcc/gcc-ar.cc:               CONST_CAST2 (char * const *, const char **,
nargv),
gcc/gcc.cc:                 CONST_CAST2 (char *const *, const char **,
&new_argv[1]),

I'm not sure what would be the outcome if changing these to CONST_CAST()
instead of CONST_CAST2(). Is it safe?

I see

#ifdef __cplusplus
#define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))
#else

I'd argue no CONST_CAST2 users with !__cplusplus should be around,
so to validate that I'd enable this define unconditionally (and
kill the #else part).

That can be done, but it does not have any impact on the redefinition of the
CONST_CAST2() macro.

The actual cleanup would of course replace CONST_CAST users
with const_cast<TOTYPE> (X), but indeed I only grepped for
CONST_CAST2, not realizing CONST_CAST is defined in terms of
CONST_CAST2.

I cannot assess whether #undef is better than the diagnostic since
if the define is ever different the previous define might be the
correct one?  Thus I wonder whether an #undef after the include of
the problematical header would be better?  Is there such a convenient
place?

The problem that I see, in my environment, is that I build with a MinGW GCC
v7.3 and that contains:

/* Make sure CONST_CAST2 (origin in system.h) is declared.  */
#ifndef CONST_CAST2
#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union {FROMTYPE _q;
TOTYPE _nq;})(X))._nq)
#endif
....

This seems to be still there, in libgcc/config/i386/gthr-win32.h,
so the diagnostic is because the definition has changed now?  Can you
change libgcc/config/i386/gthr-win32.h so it uses a private identifier
since that header seems to be installed somehow and possibly used
elsewhere?

Sure. I will stop the future pollution, but it will not resolve the 
redefinition that already happens.

{
   if (TlsSetValue (__key, CONST_CAST2(void *, const void *, __ptr)) != 0)
     return 0;


As there is no way to do #undef in that header file (already released
toolchain), the only way to avoid the redefinition warning is to do #undef
just before the #define.

Sure, but the above must happen inside a header which is included from
GCC you are trying to build.  So my point was to have

#include <.. no idea what's it is actually ..>
#undef CONST_CAST2

unless it's wide-spread (it should be sth included from system.h?)

The only entry point to the foregin CONST_CAST2 definition is the `#include 
<memory>` statement in system.h. I'll move the `#undef CONST_CAST2` to just 
after that.

It will never be known what version of the CONST_CAST2 macro that is defined
in the toolcahin used to build GCC when the block in system.h is to be
evaluated, so keeping any external definition could cause unclear
build/runtime errors.
For example, if I leave the definition from the GCC v7.3 toolchain and do not
replace the definition in my system.h, then I get really complex errors due to
invalid cast usage.

If the warning is kept, I get approx 710 warnings about this when building
r16-6992-gd7e5113e592.


Let me know how you would like me to proceed.

You get the same warnings when building gcc 15 or older?  Because I
don't know what should have changed.  And it's just a warning.

I already have some build logs (all built with MinGW GCC 7.3 from Ubuntu 18.04) 
and greping for CONST_CAST2 gives me following numbers:

gcc 7: 9
gcc 9: 36
gcc 10: 36
gcc 11: 78
gcc 12: 90
gcc 13: 228

I.e., these warnings are not new.

It would be good to eliminate CONST_CAST, we're a C++ code base now,
which is why I don't see much points in keeping it working w/o
the annoying diagnostic.

I did the cleanup of CONST_CAST2 usage in 
https://gcc.gnu.org/pipermail/gcc-patches/2026-January/707238.html.
I can, at a later time, look into cleaning all the CONST_CAST* macros, but 
there are a lot more places, so it will take more time to ensure it will be 
correct.

I don't see that, btw, even though also
using a GCC 7 host compiler (but not mingw).

The reason why you do not see it is due to that your gthr-default.h file does not contain the 
macro. From what I can tell, it will only be defined for MinGW and "pa" (whatever that 
"pa" is...) (based on `grep -r --include '*gthr*.h' CONST_CAST2`).

That said, I'm fine with the #undef in system.h, but I'd rather see
that right after the offending #include and with an added comment.

I'll move it and document the reason for the #undef. Since it's not a direct 
include from system.h, there might be other include chains in the future, but 
lets deal with them if/when the arise.

V2 comming shortly.

Kind regards,
Torbjörn


Richard.

Kind regards,
Torbjörn



Richard.


libgcc/config/i386/gthr-win32.h:/* Make sure CONST_CAST2 (origin in
system.h)
is declared.  */
libgcc/config/i386/gthr-win32.h:#ifndef CONST_CAST2
libgcc/config/i386/gthr-win32.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X)
(const_cast<TOTYPE> (X))
libgcc/config/i386/gthr-win32.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X)
((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
libgcc/config/i386/gthr-win32.h:  if (TlsSetValue (__key, CONST_CAST2(void
*,
const void *, __ptr)))
libgcc/config/pa/gthr-dce.h:/* Make sure CONST_CAST2 (original in system.h)
is
defined.  */
libgcc/config/pa/gthr-dce.h:#ifndef CONST_CAST2
libgcc/config/pa/gthr-dce.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X)
(const_cast<TOTYPE> (X))
libgcc/config/pa/gthr-dce.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X)
((__extension__(union {FROMTYPE _q; TOTYPE _nq;})(X))._nq)
libgcc/config/pa/gthr-dce.h:    (__key, CONST_CAST2(void *, const void *,
__ptr));

I'm not sure if we can remove these references as the gthr file is included
indirectly from system.h (circle if we try to include system.h to get our
definition).


gcc/system.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE>
(X))
gcc/system.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union
{FROMTYPE _q; TOTYPE _nq;})(X))._nq)
gcc/system.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X) \
gcc/system.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((TOTYPE)(FROMTYPE)(X))
gcc/system.h:#define CONST_CAST(TYPE,X) CONST_CAST2 (TYPE, const TYPE, (X))
gcc/tsystem.h:#define CONST_CAST2(TOTYPE,FROMTYPE,X) ((__extension__(union
{FROMTYPE _q; TOTYPE _nq;})(X))._nq)
gcc/tsystem.h:#define CONST_CAST(TYPE,X) CONST_CAST2 (TYPE, const TYPE,
(X))

These references could be cleaned up as you said.


gcc/tree.h:(*(CONST_CAST2 (tree *, typeof (T)*, \
gcc/tree.h:(*(CONST_CAST2 (tree*, typeof (T)*, \

For these 2, is it guaranteed that these are only referenced in C++? If it
is,
then I suppose they could be replaced with CONST_CAST() instead.



The overall feeling is that there is more risk associated with this change
than the one that I proposed.
I can still send another patch to do the cleanup of the safe transition
from
CONST_CAST2() to CONST_CAST().


Kind regards,
Torbjörn


Richard.

gcc/ChangeLog:

   * system.h: Avoid redefinition of CONST_CAST2 macro.

Signed-off-by: Torbjörn SVENSSON <[email protected]>
---
    gcc/system.h | 1 +
    1 file changed, 1 insertion(+)

diff --git a/gcc/system.h b/gcc/system.h
index 588e65453f5..c6f76ae9d65 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1168,6 +1168,7 @@ extern void fancy_abort (const char *, int, const
char *)
       change after the fact).  Beyond these uses, most other cases of
       using this macro should be viewed with extreme caution.  */
    +#undef CONST_CAST2
    #ifdef __cplusplus
    #define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast<TOTYPE> (X))
    #else











Reply via email to