https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=205453
Bug ID: 205453 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 Version: 11.0-CURRENT Hardware: ppc OS: Any Status: New Severity: Affects Only Me Priority: --- Component: bin Assignee: freebsd-bugs@FreeBSD.org Reporter: mar...@dsl-only.net [There might be some debate if g++ compilers should directly support C11's _Static_assert. I've pick the component to submit under under the answer "no".] A 6 line program can show the behavior of FreeBSD's sys/cdefs.h's _Static_assert handling vs. g++ compilers for C++ code that ties to use _Static_assert, even in contexts where libcxxrt/gaurd.cc is not involved: # more main.cc #include "/usr/include/sys/cdefs.h" _Static_assert(1,"Test"); int main(void) { return 0; } For example: # g++49 main.cc main.cc:2:15: error: expected constructor, destructor, or type conversion before '(' token _Static_assert(1,"Test"); ^ This is also true with the include commented out as well. g++49, g++5, and powerpc64-portbld-freebsd11.0-g++ all reject the above source the same way that libcxxrt/guard.cc compiles are rejected during powerpc64-portbld-freebsd11.0-g++ based buildworld lib32 -m32 compiles. gcc49, gcc5, and powerpc64-portbld-freebsd11.0-gcc all accept the above instead (when in main.c instead of main.cc so it is handle as C code), with or without the include. _Static_assert is specific to C11 and is not part of C++. It takes explicit definitions to make the syntax acceptable as C++. Note: clang++ (3.7) accepts the use of the C11 _Static_assert, with or without the include, going well outside the C++ language definition. With that as the simplified-context the FreeBSD details involved in the buildworld failures are: The sys/cdefs.h include is not (re-)defining the _Static_assert notation for C++ compiles by g++ compilers to translate to C++ notation or to any syntax acceptable to the g++ compilers. The following sys/cdefs.h code seems to assume that if _Static_assert is supported for gcc it is also supported for g++, which is not currently the case because of the distinct languages involved. #if !__has_extension(c_static_assert) #if (defined(__cplusplus) && __cplusplus >= 201103L) || \ __has_extension(cxx_static_assert) #define _Static_assert(x, y) static_assert(x, y) #elif __GNUC_PREREQ__(4,6) /* Nothing, gcc 4.6 and higher has _Static_assert built-in */ #elif defined(__COUNTER__) #define _Static_assert(x, y) __Static_assert(x, __COUNTER__) #define __Static_assert(x, y) ___Static_assert(x, y) #define ___Static_assert(x, y) typedef char __assert_ ## y[(x) ? 1 : -1] \ __unused #else #define _Static_assert(x, y) struct __hack #endif Why a C++ source is using a C11-only declaration syntax instead of a C++ syntax I do not know. But as long as FreeBSD does such it would appear that the above code was supposed to provide a translation to C++ syntax --or for g++ to a g++ compatible syntax. Otherwise libcxxrt/guard.cc just needs to be fixed to be C++ compliant (spanning fairly modern clang++ and g++). The libcxxrt/guard.cc non-arm/non-LP64/non-little-endian context comes from the #if/#elif/. . . structure: #ifdef __arm__ . . . #elif defined(_LP64) . . . #else typedef uint32_t guard_lock_t; # if defined(__LITTLE_ENDIAN__) . . . # else typedef struct { uint32_t init_half; uint32_t lock_half; } guard_t; _Static_assert(sizeof(guard_t) == sizeof(uint64_t), ""); static const uint32_t LOCKED = 1; static const uint32_t INITIALISED = static_cast<guard_lock_t>(1) << 24; # endif #define LOCK_PART(guard) (&(guard)->lock_half) #define INIT_PART(guard) (&(guard)->init_half) #endif An example of the buildworld failure that reached the _Static_assert is: --- guard.po --- /usr/local/bin/powerpc64-portbld-freebsd11.0-g++ -m32 -mcpu=powerpc . . . -c /usr/src/lib/libcxxrt/../../contrib/libcxxrt/guard.cc -o guard.po . . . --- guard.po --- /usr/src/lib/libcxxrt/../../contrib/libcxxrt/guard.cc:104:15: error: expected constructor, destructor, or type conversion before '(' token _Static_assert(sizeof(guard_t) == sizeof(uint64_t), ""); -- You are receiving this mail because: You are the assignee for the bug. _______________________________________________ freebsd-bugs@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/freebsd-bugs To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"