From owner-freebsd-bugs@freebsd.org Sun Dec 20 07:37:12 2015 Return-Path: Delivered-To: freebsd-bugs@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E42E2A402BF for ; Sun, 20 Dec 2015 07:37:12 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from kenobi.freebsd.org (kenobi.freebsd.org [IPv6:2001:1900:2254:206a::16:76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CAB411ECE for ; Sun, 20 Dec 2015 07:37:12 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from bugs.freebsd.org ([127.0.1.118]) by kenobi.freebsd.org (8.15.2/8.15.2) with ESMTP id tBK7bCkd048520 for ; Sun, 20 Dec 2015 07:37:12 GMT (envelope-from bugzilla-noreply@freebsd.org) From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [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 Date: Sun, 20 Dec 2015 07:37:12 +0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: Base System X-Bugzilla-Component: bin X-Bugzilla-Version: 11.0-CURRENT X-Bugzilla-Keywords: X-Bugzilla-Severity: Affects Only Me X-Bugzilla-Who: markmi@dsl-only.net X-Bugzilla-Status: New X-Bugzilla-Priority: --- X-Bugzilla-Assigned-To: freebsd-bugs@FreeBSD.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version rep_platform op_sys bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: https://bugs.freebsd.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Dec 2015 07:37:13 -0000 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: markmi@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(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.