[2.24,1/3] Add utility macros for clang detection, and deprecation with messages.
Commit Message
There are three new macros added to features.h and sys/cdefs.h:
* __glibc_clang_prereq: just like __GNUC_PREREQ, but for clang.
* __glibc_clang_has_extension: wraps clang's intrinsic __has_extension.
Writing "#if defined __clang__ && __has_extension (...)" doesn't work,
because compilers other than clang will object to the unknown macro
__has_extension even though they don't need to evaluate it.
Instead, write "#if __glibc_clang_has_extension (...)".
* __attribute_deprecated_msg__(msg): like __attribute_deprecated__, but
if possible, prints a message.
The first two are used to define the third. The third will be used
in subsequent patches.
ChangeLog:
* include/features.h (__glibc_clang_prereq): New macro.
* misc/sys/cdefs.h (__glibc_clang_has_extension)
(__attribute_deprecated_msg__): New macros.
---
include/features.h | 19 +++++++++++++++----
misc/sys/cdefs.h | 22 +++++++++++++++++++++-
2 files changed, 36 insertions(+), 5 deletions(-)
Comments
Zack Weinberg wrote:
> +#if __GNUC_PREREQ (4,5) || \
> + __glibc_clang_has_extension (__attribute_deprecated_with_message__)
This sort of condition should be reworded to be simpler, like this:
#if __glibc_has_extension (__attribute_deprecated_with_message__)
with an implementation that looks something like this:
#ifdef __has_extension
# define __glibc_has_extension(ext) __has_extension (ext)
#else
# define __glibc_has_extension(ext) __glibc_has_extension##ext
# define __glibc_has_extension__attribute_deprecated_with_message__
__GNUC_PREREQ (4,5)
#endif
This will be easier to maintain, as only the implementation will need to worry
about GCC version numbers.
On Sun, Jul 31, 2016 at 11:29 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
> Zack Weinberg wrote:
>>
>> +#if __GNUC_PREREQ (4,5) || \
>> + __glibc_clang_has_extension (__attribute_deprecated_with_message__)
>
> This sort of condition should be reworded to be simpler, like this:
[...]
Roland asked for something similar when we were discussing an earlier
revision. I've thought about it a bunch and I have concluded that it
does not actually make _this particular situation_ any simpler. Right
now, there's only one conditional, controlling how
__attribute_deprecated_with_message__ is defined. If I were to
introduce the mechanism you want, we would have _two_ conditionals
involved in the definition of that macro.
It might still be a good idea as part of a complete revision of
sys/cdefs.h + features.h, subsuming _all_ of the GCC version checks
into this mechanism and rendering it easily extensible to more
different compilers -- which is what Roland wanted -- but that is a
separate project, not appropriate for 2.24 at this stage, and I do not
want to mission-creep _this_ patchset even to the extent of
introducing the skeleton of the mechanism.
zw
On 07/31/2016 04:09 PM, Zack Weinberg wrote:
> There are three new macros added to features.h and sys/cdefs.h:
>
> * __glibc_clang_prereq: just like __GNUC_PREREQ, but for clang.
> * __glibc_clang_has_extension: wraps clang's intrinsic __has_extension.
> Writing "#if defined __clang__ && __has_extension (...)" doesn't work,
> because compilers other than clang will object to the unknown macro
> __has_extension even though they don't need to evaluate it.
> Instead, write "#if __glibc_clang_has_extension (...)".
>
> * __attribute_deprecated_msg__(msg): like __attribute_deprecated__, but
> if possible, prints a message.
>
> The first two are used to define the third. The third will be used
> in subsequent patches.
>
> ChangeLog:
> * include/features.h (__glibc_clang_prereq): New macro.
> * misc/sys/cdefs.h (__glibc_clang_has_extension)
> (__attribute_deprecated_msg__): New macros.
This looks good to me. I have no objections like Roland or Paul about
abstracting this into some generic infrastructure. These things should
grow organically based on need IMO.
On Mon, Aug 1, 2016 at 4:09 PM, Carlos O'Donell <carlos@redhat.com> wrote:
>
> This looks good to me. I have no objections like Roland or Paul about
> abstracting this into some generic infrastructure. These things should
> grow organically based on need IMO.
For the record, I do have the generic infrastructure on my to-do list
for 2.25, but I cannot promise to actually get to it.
zw
On 08/01/2016 04:19 PM, Zack Weinberg wrote:
> On Mon, Aug 1, 2016 at 4:09 PM, Carlos O'Donell <carlos@redhat.com> wrote:
>>
>> This looks good to me. I have no objections like Roland or Paul about
>> abstracting this into some generic infrastructure. These things should
>> grow organically based on need IMO.
>
> For the record, I do have the generic infrastructure on my to-do list
> for 2.25, but I cannot promise to actually get to it.
I appreciate any of the valuable volunteer time you give to the project.
Zack Weinberg wrote:
> It might still be a good idea as part of a complete revision of
> sys/cdefs.h + features.h, subsuming _all_ of the GCC version checks
> into this mechanism and rendering it easily extensible to more
> different compilers -- which is what Roland wanted -- but that is a
> separate project, not appropriate for 2.24 at this stage, and I do not
> want to mission-creep _this_ patchset even to the extent of
> introducing the skeleton of the mechanism.
Yes, thanks, that all sounds good.
For what it's worth, the Emacs source code is already implementing something
similar to what Roland and I were proposing (using different macro names).
@@ -125,13 +125,13 @@
# define __KERNEL_STRICT_NAMES
#endif
-/* Convenience macros to test the versions of glibc and gcc.
- Use them like this:
+/* Convenience macro to test the version of gcc.
+ Use like this:
#if __GNUC_PREREQ (2,8)
... code requiring gcc 2.8 or later ...
#endif
- Note - they won't work for gcc1 or glibc1, since the _MINOR macros
- were not defined then. */
+ Note: only works for GCC 2.0 and later, because __GNUC_MINOR__ was
+ added in 2.0. */
#if defined __GNUC__ && defined __GNUC_MINOR__
# define __GNUC_PREREQ(maj, min) \
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
@@ -139,6 +139,17 @@
# define __GNUC_PREREQ(maj, min) 0
#endif
+/* Similarly for clang. Features added to GCC after version 4.2 may
+ or may not also be available in clang, and their definitions of
+ __GNUC(_MINOR)__ are fixed at 4 and 2 respectively. Not all such
+ features can be queried via __has_extension/__has_feature. */
+#if defined __clang_major__ && defined __clang_minor__
+# define __glibc_clang_prereq(maj, min) \
+ ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
+#else
+# define __glibc_clang_prereq(maj, min) 0
+#endif
+
/* _BSD_SOURCE and _SVID_SOURCE are deprecated aliases for
_DEFAULT_SOURCE. If _DEFAULT_SOURCE is present we do not
issue a warning; the expectation is that the source is being
@@ -77,6 +77,15 @@
#endif /* GCC. */
+/* Compilers that are not clang may object to
+ #if defined __clang__ && __has_extension(...)
+ even though they do not need to evaluate the right-hand side of the &&. */
+#if defined __clang__ && defined __has_extension
+# define __glibc_clang_has_extension(ext) __has_extension (ext)
+#else
+# define __glibc_clang_has_extension(ext) 0
+#endif
+
/* These two macros are not used in glibc anymore. They are kept here
only because some other projects expect the macros to be defined. */
#define __P(args) args
@@ -249,13 +258,24 @@
# define __attribute_noinline__ /* Ignore */
#endif
-/* gcc allows marking deprecated functions. */
+/* Since version 3.2, gcc allows marking deprecated functions. */
#if __GNUC_PREREQ (3,2)
# define __attribute_deprecated__ __attribute__ ((__deprecated__))
#else
# define __attribute_deprecated__ /* Ignore */
#endif
+/* Since version 4.5, gcc also allows one to specify the message printed
+ when a deprecated function is used. clang claims to be gcc 4.2, but
+ may also support this feature. */
+#if __GNUC_PREREQ (4,5) || \
+ __glibc_clang_has_extension (__attribute_deprecated_with_message__)
+# define __attribute_deprecated_msg__(msg) \
+ __attribute__ ((__deprecated__ (msg)))
+#else
+# define __attribute_deprecated_msg__(msg) __attribute_deprecated__
+#endif
+
/* At some point during the gcc 2.8 development the `format_arg' attribute
for functions was introduced. We don't want to use it unconditionally
(although this would be possible) since it generates warnings.