Summary: | 11.0-CURRENT libcxxrt/guard.cc uses C11's _Static_assert in conditionally-compiled C++ code and when it is used buildworld fails for syntax errors in g++ compilers | ||
---|---|---|---|
Product: | Base System | Reporter: | Mark Millard <marklmi26-fbsd> |
Component: | bin | Assignee: | freebsd-toolchain (Nobody) <toolchain> |
Status: | Closed FIXED | ||
Severity: | Affects Only Me | CC: | bapt, dim, ppc, theraven |
Priority: | --- | ||
Version: | CURRENT | ||
Hardware: | powerpc | ||
OS: | Any |
Description
Mark Millard
2015-12-20 07:37:12 UTC
I should also have noted that clang++ can report the __Static_assert syntax as not-C++ syntax but C11 instead: # clang++ -Wall -pedantic main.cc main.cc:2:1: warning: _Static_assert is a C11-specific feature [-Wc11-extensions] _Static_assert(1,"Test"); ^ 1 warning generated. Hm, this _Static_assert has an interesting history. The original review from Baptiste, https://reviews.freebsd.org/D1390, used static_assert(), but this required -std=c++11 to compile, otherwise you would get: contrib/libcxxrt/guard.cc:104:1: error: C++ requires a type specifier for all declarations static_assert(sizeof(guard_t) == sizeof(uint64_t), ""); ^~~~~~~~~~~~~ This is the version upstream eventually also used, since they apparently assume C++11 there. David suggested changing it to _Static_assert(): "This should work if you change it to _Static_assert, which I think we support for all C/C++ versions." Now that I look at the code again, I am not entirely sure why the static assertion is only for the big endian #ifdef block. It would seem more useful to put it a few lines lower, for the !_LP64 case. That said, even when moving the _Static_assert() like that, it compiles fine for me, both with base gcc, and several versions of ports gcc (I tried gcc 4.8, 4.9 and 5.2). On the other hand, your sample program indeed does not compile with the ports versions of gcc. I'm not sure where those versions are getting their version of _Static_assert() from, though... As for where _Static_assert and static_assert are gotten from: _Static_assert in C11 and static_assert in C++11 exist even for free-standing implementations. As I understand it is even stronger: no explicit headers should be required unless the notation from one language is being used in the other (ignoring simulating for older versions of languages). The handling should be automatic/built-in even for source with no #includes involved. FYI: My src.conf in use for the failing powerpc64-gcc "X" toolchain based buildworld and buildkernel (with gcc49 acting as the host toolchain) was: # more ~/src.configs/src.conf.powerpc64-xtoolchain.powerpc64-host KERNCONF=GENERIC64vtsc-NODEBUG TARGET=powerpc .if ${.MAKE.LEVEL} == 0 TARGET_ARCH=powerpc64 .export TARGET_ARCH .endif WITHOUT_CROSS_COMPILER= WITHOUT_CLANG_EXTRAS= WITH_FAST_DEPEND= WITH_LIBCPLUSPLUS= WITH_LIB32= WITH_BOOT= WITH_CLANG= WITH_CLANG_IS_CC= WITH_CLANG_FULL= WITH_LLDB= WITHOUT_GCC= WITHOUT_GNUCXX= NO_WERROR= MALLOC_PRODUCTION= WITH_DEBUG= WITH_DEBUG_FILES= CROSS_TOOLCHAIN=powerpc64-gcc .if ${.MAKE.LEVEL} == 0 CC=/usr/local/bin/gcc49 CXX=/usr/local/bin/g++49 CPP=/usr/local/bin/cpp49 .export CC .export CXX .export CPP .endif So WITH_LIBCPLUSPLUS. make.conf was empty. gcc49/g++49 had been built without 32 bit (lib32) support. gcc49 built powerpc64-gcc's update; the older powerpc64-gcc built gcc49. gcc 4.2.1 is/was not present. The kernel configuration turns on both vt and sc and turns off ps3. Fixed in r297299. |