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?
> {
> 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?)
> 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.
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 don't see that, btw, even though also
using a GCC 7 host compiler (but not mingw).
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.
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
> >>>>
> >>>
> >>
> >>
> >>
> >
>
>
>
--
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)