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).

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?

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)

Reply via email to