From owner-svn-src-head@FreeBSD.ORG Wed Dec 7 21:19:49 2011 Return-Path: Delivered-To: svn-src-head@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DC1B1106566B; Wed, 7 Dec 2011 21:19:49 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail14.syd.optusnet.com.au (mail14.syd.optusnet.com.au [211.29.132.195]) by mx1.freebsd.org (Postfix) with ESMTP id 75D528FC15; Wed, 7 Dec 2011 21:19:49 +0000 (UTC) Received: from c211-28-227-231.carlnfd1.nsw.optusnet.com.au (c211-28-227-231.carlnfd1.nsw.optusnet.com.au [211.28.227.231]) by mail14.syd.optusnet.com.au (8.13.1/8.13.1) with ESMTP id pB7LJkgw029673 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 8 Dec 2011 08:19:47 +1100 Date: Thu, 8 Dec 2011 08:19:46 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: David Schultz In-Reply-To: <20111207191134.GA20850@zim.MIT.EDU> Message-ID: <20111208071024.J2931@besplex.bde.org> References: <201112071525.pB7FPmkH044896@svn.freebsd.org> <20111207191134.GA20850@zim.MIT.EDU> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: svn-src-head@FreeBSD.org, svn-src-all@FreeBSD.org, src-committers@FreeBSD.org, David Chisnall Subject: Re: svn commit: r228322 - in head: include lib/libc/stdlib sys/sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Dec 2011 21:19:50 -0000 On Wed, 7 Dec 2011, David Schultz wrote: > On Wed, Dec 07, 2011, David Chisnall wrote: >> Log: >> Implement quick_exit() / at_quick_exit() from C++11 / C1x. Also add a >> __noreturn macro and modify the other exiting functions to use it. >> >> The __noreturn macro, unlike __dead2, must be used BEFORE the function. >> This is in line with the C and C++ specifications that place _Noreturn (c1x) >> and [[noreturn]] (C++11) in front of the functions. As with __dead2, this >> macro falls back to using the GCC attribute. >> >> Unfortunately, clang currently sets the same value for the C version macro >> in C99 and C1x modes, so these functions are hidden by default. At some >> point before 10.0, I need to go through the headers and clean up the C1x / >> C++11 visibility. > > Nice. > > Why not use the standard spelling, '_Noreturn'? In pre-C1X modes, > _Noreturn is a reserved identifier since it starts with an underscore > and capital letter, so it's not considered namespace pollution. There is also the __dead attribute for gcc-1 and some versions of gcc-2. It has the same syntax as __noreturn, since it was implemented as `volatile' in gcc-1, and `volatile' must be in the declarator BEFORE the function name. This was changed in gcc-2 because it was determined that `volatile' for a function has some defined meaning that of course can't be the gcc-1 one. FreeBSD introduced __dead2 for newer versions of gcc-2 and kept __dead for a while. __dead remains dead (reserved for gcc-1, or perhaps anything that uses the same syntax). Not quite similarly for __pure. Someone broke its reservedness by using it for gcc-2.96+'s new __pure__ attribute, which is subtly different from the old __pure and the current __pure2 FreeBSD macros. NetBSD still had the old __dead and __pure, and no __dead2 or __pure2, as late as 2005. It still use[d] (as well as defining) __dead in a few places, and uses a hard __attribute__((__noreturn__)) instead of __dead2. Sometimes both. This change seems to break compatibility cruft related to this in the critical header , since __Noreturn is actually used there and replaces __dead2 and has a different syntax that might not work with old compilers (sys/cdefs.h still has mounds of compatibility cruft for old compilers, although this doesn't include __dead for gcc-1, and probably mostly doesn't actually work). Here is the change in cdefs.h: % Index: cdefs.h % =================================================================== % RCS file: /home/ncvs/src/sys/sys/cdefs.h,v % retrieving revision 1.117 % retrieving revision 1.118 % diff -u -2 -r1.117 -r1.118 % --- cdefs.h 12 Nov 2011 23:17:54 -0000 1.117 % +++ cdefs.h 7 Dec 2011 15:25:48 -0000 1.118 % @@ -219,4 +219,15 @@ % #endif % % + Style bug (extra blank line). % +#if defined(__cplusplus) && __cplusplus >= 201103L % +#define __noreturn [[noreturn]] % +#elif defined(__STDC_VERSION__) && __STDC_VERSION__ > 201000L % +#define __noreturn _Noreturn % +#elif defined(__GNUC__) % +#define __noreturn __attribute__((__noreturn__)) This assumes that all versions of gcc support the __noreturn__ attribute, and the new uses of this attribute assumes that __attribute__(()) works BEFORE the function name when it is used there, as it now is in . The first assumption bogotifies the fussy ifdefs used later in cdefs.h. __attribute__((__noreturn__)) is already used later, to define __dead2, and this is under several ifdefs with ugly duplication: - one for gcc-2.5 and 2.6 vs older gcc's - one for gcc >= 2.7 - one for __INTEL_COMPILER (twisted by interaction with the ones for very old gcc's) I don't trust most of the version numbers in the GNC_PREREQ()s, but these have more chance than most of being correct since they are old and detailed. If they are correct, then we see that the above is incorrect mainly for gcc-2.0 through 2.4. gcc-1 is already fully unsupported (except as a generic compiler). gcc-2.0 through gcc-2.4 are old enough to unsupport, so this is mainly a style bug. The second assumption is probably not satisfied by middle versions of gcc-2. IIRC, the reason for switching the syntax from __dead (placed before the function name) to __dead2 (placed after) was that early implementations of __attribute__() only worked if they were placed after. Otherwise, we would have just ifdefed another case for __dead. I don't know when gcc fixed this. % +#else % +#define __noreturn Defaulting to nothing for a generic/unknown compiler is good, but this combined with actually using __noreturn seems to break some previously supported cases, in particular __INTEL_COMPILER sees a null __noreturn for declarations in where it used to see a non-null __dead2. Apparently it doesn't pretend to be gcc, but it supports most gcc features so it mostly works, but it needs messy ifdefs to use these features. Perhaps __INTEL_COMPILER should be unsupported together with gcc-2. It is painful to maintain all these compatibilty ifdefs, especially if they are required to actually work. clang avoids most problems in this area by claiming to be gcc-4. % +#endif % + % ... Bruce