On 5/1/20 12:58 AM, Marc Nieper-Wißkirchen wrote:
> this can even be reused by many existing Gnulib modules,

That suggests that we should define _GL_ATTRIBUTE* variants, which can be used
in Gnulib header files safely.

A fancier patch is attached, to do that. I also looked for other uses of
__attribute__ in Gnulib and add macros for most of them. I haven't tested this,
or seen how to use it to simplify other modules; it's merely a proof of concept.

> To my knowledge, C2x will standardize attributes

Ah, I hadn't been following that. Thanks for mentioning it. I incorporated that
into the attached patch.
>From de35c4f63bb070063cbcac0b982670c9005ade99 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Fri, 1 May 2020 18:12:12 -0700
Subject: [PROOF-OF-CONCEPT] New module attribute

* MODULES.html.sh: Add attribute.
* doc/attribute.texi, lib/attribute-gl.h, lib/attribute.h:
* modules/attribute: New files.
* doc/gnulib.texi (Particular Modules): Add Attributes.
---
 ChangeLog          |   8 +++
 MODULES.html.sh    |   1 +
 doc/attribute.texi |  43 ++++++++++++++
 doc/gnulib.texi    |   3 +
 lib/attribute-gl.h | 140 +++++++++++++++++++++++++++++++++++++++++++++
 lib/attribute.h    |  48 ++++++++++++++++
 modules/attribute  |  21 +++++++
 7 files changed, 264 insertions(+)
 create mode 100644 doc/attribute.texi
 create mode 100644 lib/attribute-gl.h
 create mode 100644 lib/attribute.h
 create mode 100644 modules/attribute

diff --git a/ChangeLog b/ChangeLog
index 033f3be48..9e9c0a827 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2020-05-01  Paul Eggert  <egg...@cs.ucla.edu>
+
+	New module attribute
+	* MODULES.html.sh: Add attribute.
+	* doc/attribute.texi, lib/attribute-gl.h, lib/attribute.h:
+	* modules/attribute: New files.
+	* doc/gnulib.texi (Particular Modules): Add Attributes.
+
 2020-05-01  Bruno Haible  <br...@clisp.org>
 
 	list: Add remove_first and remove_last operations.
diff --git a/MODULES.html.sh b/MODULES.html.sh
index 240a9ee20..318a15a1d 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -2364,6 +2364,7 @@ func_all_modules ()
   func_echo "$element"
 
   func_begin_table
+  func_module attribute
   func_module builtin-expect
   func_module ieee754-h
   func_module limits-h
diff --git a/doc/attribute.texi b/doc/attribute.texi
new file mode 100644
index 000000000..86591f16c
--- /dev/null
+++ b/doc/attribute.texi
@@ -0,0 +1,43 @@
+@c attribute module documentation
+
+@c Copyright 2020 Free Software Foundation, Inc.
+
+@c Permission is granted to copy, distribute and/or modify this document
+@c under the terms of the GNU Free Documentation License, Version 1.3 or
+@c any later version published by the Free Software Foundation; with no
+@c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
+@c copy of the license is at <https://www.gnu.org/licenses/fdl-1.3.en.html>.
+
+@node Attributes
+@section Attributes
+
+@cindex Attributes
+@findex __attribute__
+
+This module provides a header file @file{attribute.h} that defines
+macros related to C and C++ attributes and the GCC
+@code{__attribute__} keyword.
+
+Here is an example of its use:
+
+@example
+#include <attribute.h>
+
+extern char *crypt (char const *, char const *)
+  ATTRIBUTE_NOTHROW ATTRIBUTE_LEAF ATTRIBUTE_NONNULL ((1, 2));
+@end example
+
+@noindent
+@code{ATTRIBUTE_NOTHROW} expands to @code{__attribute__
+((__nothrow__))} if the compiler is a recent-enough GCC or GCC-like
+compiler, and to nothing otherwise.  Similarly for
+@code{ATTRIBUTE_LEAF}.  @code{ATTRIBUTE_NONNULL ((1, 2))} expands to
+@code{__attribute__ ((__nonnull__ (1, 2)))} if the compiler is
+recent-enough GCC, and to nothing otherwise.
+
+Most of these attribute names begin with @code{ATTRIBUTE_}.
+A few do not, because they are part of C2X and their
+names are not likely to clash with other macro names.
+These macros are @code{DEPRECATED}, @code{FALLTHROUGH},
+@code{MAYBE_UNUSED}, and @code{NODISCARD}, which can
+be defined to @code{[[deprecated]]} etc.@: on C2X platforms.
diff --git a/doc/gnulib.texi b/doc/gnulib.texi
index c9501ca23..b27f91f58 100644
--- a/doc/gnulib.texi
+++ b/doc/gnulib.texi
@@ -6654,6 +6654,7 @@ to POSIX that it can be treated like any other Unix-like platform.
 * alloca::
 * alloca-opt::
 * Safe Allocation Macros::
+* GCC Attributes::
 * Compile-time Assertions::
 * Non-returning Functions::
 * Integer Properties::
@@ -6685,6 +6686,8 @@ to POSIX that it can be treated like any other Unix-like platform.
 
 @include safe-alloc.texi
 
+@include attribute.texi
+
 @include verify.texi
 
 @include noreturn.texi
diff --git a/lib/attribute-gl.h b/lib/attribute-gl.h
new file mode 100644
index 000000000..ddb9aa5bd
--- /dev/null
+++ b/lib/attribute-gl.h
@@ -0,0 +1,140 @@
+/* _GL_ATTRIBUTE_* macros for using attributes in GCC and similar compilers
+
+   Copyright 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* Each _GL_ATTRIBUTE_* macro expands to the like-named GCC attribute if
+   possible.  Parameters may need parenthsization.  For example,
+   _GL_ATTRIBUTE_NONNULL ((1, 2)) is __attribute__ ((__nonnull__ (1, 2)))
+   if the compiler is recent-enough GCC, and empty otherwise.  */
+
+#ifndef _GL_ATTRIBUTE_GCC_GL_H
+#define _GL_ATTRIBUTE_GCC_GL_H
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+/* There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's _Alignas instead.  */
+
+#if __GNUC_PREREQ (4, 3)
+# define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
+#else
+# define _GL_ATTRIBUTE_ALLOC_SIZE(args)
+#endif
+
+#if __GNUC_PREREQ (3, 2)
+# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__))
+#else
+# define _GL_ATTRIBUTE_ALWAYS_INLINE
+#endif
+# define __attribute_artificial__ __attribute__ ((__artificial__))
+
+#if __GNUC_PREREQ (4, 3)
+# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__))
+# define _GL_ATTRIBUTE_ERROR(msg) __attribute__((__error__ (msg)))
+# define _GL_ATTRIBUTE_WARNING(msg) __attribute__((__warning__ (msg)))
+#elsem
+# define _GL_ATTRIBUTE_ARTIFICIAL
+# define _GL_ATTRIBUTE_ERROR(msg)
+# define _GL_ATTRIBUTE_WARNING(msg)
+#endif
+
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_DEPRECATED [[__deprecated__]]
+#elif __GNUC_PREREQ (3, 1)
+# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__))
+#else
+# define _GL_ATTRIBUTE_DEPRECATED
+#endif
+
+/* FALLTHROUGH is special, because it always expands to something.  */
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_FALLTHROUGH [[__fallthrough__]]
+#elif __GNUC_PREREQ (7, 0)
+# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((__fallthrough__))
+#else
+# define _GL_ATTRIBUTE_FALLTHROUGH ((void) 0)
+#endif
+
+#if __GNUC_PREREQ (2, 7)
+# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
+#else
+# define _GL_ATTRIBUTE_FORMAT(spec)
+#endif
+
+#if __GNUC_PREREQ (4, 6)
+# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__))
+#else
+# define _GL_ATTRIBUTE_LEAF
+#endif
+
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_MAYBE_UNUSED [[__maybe_unused__]]
+#elif __GNUC_PREREQ (3, 1)
+# define _GL_ATTRIBUTE_MAYBE_UNUSED __attribute__ ((__unused__))
+#else
+# define _GL_ATTRIBUTE_MAYBE_UNUSED
+#endif
+
+#if 201710L < __STDC_VERSION__
+# define _GL_ATTRIBUTE_NODISCARD [[__nodiscard__]]
+#elif __GNUC_PREREQ (3, 4)
+# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__))
+#else
+# define _GL_ATTRIBUTE_NODISCARD
+#endif
+
+#if __GNUC_PREREQ (3, 3)
+# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args))
+#else
+# define _GL_ATTRIBUTE_NONNULL(args)
+#endif
+
+#if __GNUC_PREREQ (8, 0)
+# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__))
+#else
+# define _GL_ATTRIBUTE_NONSTRING
+#endif
+
+/* There is no _GL_ATTRIBUTE_NORETURN; use _Noreturn instead.  */
+
+#if !defined __cplusplus && __GNUC_PREREQ (3, 3)
+# define _GL_ATTRIBUTE_NOTHROW __attribute__ ((__nothrow__))
+#else
+# define _GL_ATTRIBUTE_NOTHROW
+#endif
+
+#if __GNUC_PREREQ (2, 7)
+# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__))
+#else
+# define _GL_ATTRIBUTE_PACKED
+#endif
+
+#if __GNUC_PREREQ (4, 0)
+# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos))
+#else
+# define _GL_ATTRIBUTE_SENTINEL(pos)
+#endif
+
+/* There is no _GL_ATTRIBUTE_VISIBILITY; see m4/visibility.m4 instead.  */
+
+#endif /* _GL_ATTRIBUTE_GCC_GL_H */
diff --git a/lib/attribute.h b/lib/attribute.h
new file mode 100644
index 000000000..a067ced92
--- /dev/null
+++ b/lib/attribute.h
@@ -0,0 +1,48 @@
+/* ATTRIBUTE_* macros for using attributes in GCC and similar compilers
+
+   Copyright 2020 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_*
+   macros used within Gnulib.  */
+
+#ifndef _GL_ATTRIBUTE_GCC_H
+#define _GL_ATTRIBUTE_GCC_H
+
+/* C2X standard attributes have macro names that do not begin with
+   'ATTRIBUTE_'.  */
+#define DEPRECATED _GL_ATTRIBUTE_DEPRECATED
+#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH
+#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
+#define NODISCARD _GL_ATTRIBUTE_NODISCARD
+
+/* Attributes from GCC have macro names beginning with 'ATTRIBUTE_' to
+   avoid name clashes.  */
+#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE(args)
+#define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE
+#define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL
+#define ATTRIBUTE_ERROR(msg) _GL_ATTRIBUTE_ERROR(msg)
+#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT(spec)
+#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF
+#define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL(args)
+#define ATTRIBUTE_NONSTRING _GL_ATTRIBUTE_NONSTRING
+#define ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW
+#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED
+#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL(pos)
+#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING(msg)
+
+#endif
diff --git a/modules/attribute b/modules/attribute
new file mode 100644
index 000000000..9ece14fe0
--- /dev/null
+++ b/modules/attribute
@@ -0,0 +1,21 @@
+Description:
+C/C++ attributes
+
+Files:
+lib/attribute.h
+lib/attribute-gl.h
+m4/attribute.m4
+
+Depends-on:
+
+configure.ac:
+
+Makefile.am:
+
+Include:
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-- 
2.17.1

Reply via email to