[Bug 205453] 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
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Sun Dec 20 07:37:13 UTC 2015
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 at FreeBSD.org
Reporter: markmi at 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.
More information about the freebsd-bugs
mailing list