This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: GCC 6 symbol poisoning and c++ header usage is fragile
- From: Szabolcs Nagy <szabolcs dot nagy at arm dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>
- Cc: "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, nd <nd at arm dot com>, Rich Felker <dalias at libc dot org>, Michael Matz <matz at suse dot de>
- Date: Thu, 21 Apr 2016 12:48:36 +0100
- Subject: Re: GCC 6 symbol poisoning and c++ header usage is fragile
- Authentication-results: sourceware.org; auth=none
- Nodisclaimer: True
- References: <5718B57D dot 1000501 at arm dot com> <CAFiYyc00Q0J0VwYBZ8dyn5_3vLAcDAOAVgxEe7SJ5V2Qo+f9Ow at mail dot gmail dot com>
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:23
On 21/04/16 12:36, Richard Biener wrote:
> On Thu, Apr 21, 2016 at 1:11 PM, Szabolcs Nagy <szabolcs.nagy@arm.com> wrote:
>> building gcc6 using musl based gcc6 fails with symbol poisoning error
>> (details at the end of the mail).
>>
>> the root cause is c++: c++ headers include random libc headers with
>> _GNU_SOURCE ftm so all sorts of unexpected symbols are defined/declared.
>>
>> since it's unlikely the c++ standard gets fixed (to properly specify
>> the namespace rules) it is not acceptable to include std headers after
>> system.h, where the poisoning happens, because trivial libc header
>> change will break the build.
>>
>> c++ header use in gcc seems inconsistent, e.g. there are cases where
>> - <string> is included before system.h (go-system.h)
>> - <string> is included after system.h (indirectly through <map>)
>> - <string> is included in system.h because INCLUDE_STRING is defined.
>> - <new> is included in system.h and in source files using it.. sometimes
>>
>> i think it should be consistently before system.h (i'm not sure what's
>> going on with the INCLUDE_STRING macro), fortunately not many files are
>> affected in gcc/:
>
> system headers should be included from _within_ system.h. To avoid including
> them everywhere we use sth like
>
> /* Include <string> before "safe-ctype.h" to avoid GCC poisoning
> the ctype macros through safe-ctype.h */
>
> #ifdef __cplusplus
> #ifdef INCLUDE_STRING
> # include <string>
> #endif
> #endif
>
> so sources do
>
> #define INCLUDE_STRING
> #include "config.h"
> #include "system.h"
>
> So the <string> cases can be simplified with INCLUDE_STRING and the
> <new> case should be added similarly (unless we decide <new> is cheap
> enough to be always included).
>
<new> is always included already.
there is also <map>, <set>, <list> usage and go-system.h is special.
(and gmp.h includes <iosfwd> when built with c++)
so i can prepare a patch with INCLUDE_{MAP,SET,LIST} and remove
the explicit libc/libstdc++ includes.
> Richard.
>
>> auto-profile.c
>> diagnostic.c
>> graphite-isl-ast-to-gimple.c
>> ipa-icf.c
>> ipa-icf-gimple.c
>> pretty-print.c
>> toplev.c
>>
>> i can prepare a patch moving the c++ includes up and i'm open to
>> other suggestions. (including libc headers is also problematic because
>> of _GNU_SOURCE, but still safer than what is happening in c++ land
>> where #include <map> makes all locale.h, pthread.h, time.h, sched.h,
>> etc symbols visible).
>>
>>
>> x86_64-linux-musl-g++ -fno-PIE -c -g -O2 -DIN_GCC -fno-exceptions -fno-rtti -fasynchronous-unwind-tables
>> -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic
>> -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -DHAVE_CONFIG_H -I. -I. -I/src/gcc/gcc
>> -I/src/gcc/gcc/. -I/src/gcc/gcc/../include -I/src/gcc/gcc/../libcpp/include -I/build/host-tools/include
>> -I/build/host-tools/include -I/build/host-tools/include -I/src/gcc/gcc/../libdecnumber
>> -I/src/gcc/gcc/../libdecnumber/dpd -I../libdecnumber -I/src/gcc/gcc/../libbacktrace -o auto-profile.o -MT
>> auto-profile.o -MMD -MP -MF ./.deps/auto-profile.TPo /src/gcc/gcc/auto-profile.c
>> In file included from /tool/x86_64-linux-musl/include/pthread.h:30:0,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/x86_64-linux-musl/bits/gthr-default.h:35,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/x86_64-linux-musl/bits/gthr.h:148,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/ext/atomicity.h:35,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/bits/basic_string.h:39,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/string:52,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/stdexcept:39,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/array:39,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/tuple:39,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/bits/stl_map.h:63,
>> from /tool/x86_64-linux-musl/include/c++/6.0.1/map:61,
>> from /src/gcc/gcc/auto-profile.c:36:
>> /tool/x86_64-linux-musl/include/sched.h:74:7: error: attempt to use poisoned "calloc"
>> void *calloc(size_t, size_t);
>> ^
>> /tool/x86_64-linux-musl/include/sched.h:114:36: error: attempt to use poisoned "calloc"
>> #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
>> ^
>>
>