diff options
Diffstat (limited to 'gnulib-m4/gnulib-common.m4')
-rw-r--r-- | gnulib-m4/gnulib-common.m4 | 356 |
1 files changed, 328 insertions, 28 deletions
diff --git a/gnulib-m4/gnulib-common.m4 b/gnulib-m4/gnulib-common.m4 index d8d0904f..1fec5c5c 100644 --- a/gnulib-m4/gnulib-common.m4 +++ b/gnulib-m4/gnulib-common.m4 @@ -1,4 +1,5 @@ -# gnulib-common.m4 serial 92 +# gnulib-common.m4 +# serial 105 dnl Copyright (C) 2007-2024 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -20,10 +21,22 @@ AC_DEFUN([gl_COMMON_BODY], [ #define _GL_CONFIG_H_INCLUDED 1 ]) AH_VERBATIM([_GL_GNUC_PREREQ], -[/* True if the compiler says it groks GNU C version MAJOR.MINOR. */ -#if defined __GNUC__ && defined __GNUC_MINOR__ +[/* True if the compiler says it groks GNU C version MAJOR.MINOR. + Except that + - clang groks GNU C 4.2, even on Windows, where it does not define + __GNUC__. + - The OpenMandriva-modified clang compiler pretends that it groks + GNU C version 13.1, but it doesn't: It does not support + __attribute__ ((__malloc__ (f, i))), nor does it support + __attribute__ ((__warning__ (message))) on a function redeclaration. + - Users can make clang lie as well, through the -fgnuc-version option. */ +#if defined __GNUC__ && defined __GNUC_MINOR__ && !defined __clang__ # define _GL_GNUC_PREREQ(major, minor) \ ((major) < __GNUC__ + ((minor) <= __GNUC_MINOR__)) +#elif defined __clang__ + /* clang really only groks GNU C 4.2. */ +# define _GL_GNUC_PREREQ(major, minor) \ + ((major) < 4 + ((minor) <= 2)) #else # define _GL_GNUC_PREREQ(major, minor) 0 #endif @@ -113,8 +126,10 @@ AC_DEFUN([gl_COMMON_BODY], [ # define _GL_ATTR_nothrow _GL_GNUC_PREREQ (3, 3) # define _GL_ATTR_packed _GL_GNUC_PREREQ (2, 7) # define _GL_ATTR_pure _GL_GNUC_PREREQ (2, 96) +# define _GL_ATTR_reproducible 0 /* not yet supported, as of GCC 14 */ # define _GL_ATTR_returns_nonnull _GL_GNUC_PREREQ (4, 9) # define _GL_ATTR_sentinel _GL_GNUC_PREREQ (4, 0) +# define _GL_ATTR_unsequenced 0 /* not yet supported, as of GCC 14 */ # define _GL_ATTR_unused _GL_GNUC_PREREQ (2, 7) # define _GL_ATTR_warn_unused_result _GL_GNUC_PREREQ (3, 4) # endif @@ -130,6 +145,23 @@ AC_DEFUN([gl_COMMON_BODY], [ # define _GL_HAVE___HAS_C_ATTRIBUTE 0 #endif +/* Attributes in bracket syntax [[...]] vs. attributes in __attribute__((...)) + syntax, in function declarations. There are two problems here. + (Last tested with gcc/g++ 14 and clang/clang++ 18.) + + 1) We want that the _GL_ATTRIBUTE_* can be cumulated on the same declaration + in any order. + =========================== foo.c = foo.cc =========================== + __attribute__ ((__deprecated__)) [[__nodiscard__]] int bar1 (int); + [[__nodiscard__]] __attribute__ ((__deprecated__)) int bar2 (int); + ====================================================================== + This gives a syntax error + - in C mode with gcc + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108796>, and + - in C++ mode with clang++ version < 16, and + - in C++ mode, inside extern "C" {}, still in newer clang++ versions + <https://github.com/llvm/llvm-project/issues/101990>. + */ /* Define if, in a function declaration, the attributes in bracket syntax [[...]] must come before the attributes in __attribute__((...)) syntax. If this is defined, it is best to avoid the bracket syntax, so that the @@ -144,6 +176,176 @@ AC_DEFUN([gl_COMMON_BODY], [ # define _GL_BRACKET_BEFORE_ATTRIBUTE 1 # endif #endif +/* + 2) We want that the _GL_ATTRIBUTE_* can be placed in a declaration + - without 'extern', in C as well as in C++, + - with 'extern', in C, + - with 'extern "C"', in C++ + in the same position. That is, we don't want to be forced to use a + macro which arranges for the attribute to come before 'extern' in + one case and after 'extern' in the other case, because such a macro + would make the source code of .h files pretty ugly. + =========================== foo.c = foo.cc =========================== + #ifdef __cplusplus + # define CC "C" + #else + # define CC + #endif + + #define ND [[__nodiscard__]] + #define WUR __attribute__((__warn_unused_result__)) + + #ifdef __cplusplus + extern "C" { + #endif + // gcc clang g++ clang++ + + ND int foo (int); + int ND foo (int); // warn error warn error + int foo ND (int); + int foo (int) ND; // warn error warn error + + WUR int foo (int); + int WUR foo (int); + int fo1 WUR (int); // error error error error + int foo (int) WUR; + + #ifdef __cplusplus + } + #endif + + // gcc clang g++ clang++ + + ND extern CC int foo (int); // error error + extern CC ND int foo (int); // error error + extern CC int ND foo (int); // warn error warn error + extern CC int foo ND (int); + extern CC int foo (int) ND; // warn error warn error + + WUR extern CC int foo (int); // warn + extern CC WUR int foo (int); + extern CC int WUR foo (int); + extern CC int foo WUR (int); // error error error error + extern CC int foo (int) WUR; + + ND EXTERN_C_FUNC int foo (int); // error error + EXTERN_C_FUNC ND int foo (int); + EXTERN_C_FUNC int ND foo (int); // warn error warn error + EXTERN_C_FUNC int foo ND (int); + EXTERN_C_FUNC int foo (int) ND; // warn error warn error + + WUR EXTERN_C_FUNC int foo (int); // warn + EXTERN_C_FUNC WUR int foo (int); + EXTERN_C_FUNC int WUR foo (int); + EXTERN_C_FUNC int fo2 WUR (int); // error error error error + EXTERN_C_FUNC int foo (int) WUR; + ====================================================================== + So, if we insist on using the 'extern' keyword ('extern CC' idiom): + * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] + in both C and C++, there is one available position: + - between the function name and the parameter list. + * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax + in both C and C++, there are several available positions: + - before the return type, + - between return type and function name, + - at the end of the declaration. + * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] in C and to + __attribute__((...)) syntax in C++, there is no available position: + it would need to come before 'extern' in C but after 'extern "C"' + in C++. + * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax in C and + to bracket syntax [[...]] in C++, there is one available position: + - before the return type. + Whereas, if we use the 'EXTERN_C_FUNC' idiom, which conditionally + omits the 'extern' keyword: + * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] + in both C and C++, there are two available positions: + - before the return type, + - between the function name and the parameter list. + * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax + in both C and C++, there are several available positions: + - before the return type, + - between return type and function name, + - at the end of the declaration. + * If _GL_ATTRIBUTE_* expands to bracket syntax [[...]] in C and to + __attribute__((...)) syntax in C++, there is one available position: + - before the return type. + * If _GL_ATTRIBUTE_* expands to __attribute__((...)) syntax in C and + to bracket syntax [[...]] in C++, there is one available position: + - before the return type. + The best choice is therefore to use the 'EXTERN_C_FUNC' idiom and + put the attributes before the return type. This works regardless + to what the _GL_ATTRIBUTE_* macros expand. + */ + +/* Attributes in bracket syntax [[...]] vs. attributes in __attribute__((...)) + syntax, in static/inline function definitions. + + There are similar constraints as for function declarations. However, here, + we cannot omit the storage-class specifier. Therefore, the following rule + applies: + * The macros + _GL_ATTRIBUTE_CONST + _GL_ATTRIBUTE_DEPRECATED + _GL_ATTRIBUTE_MAYBE_UNUSED + _GL_ATTRIBUTE_NODISCARD + _GL_ATTRIBUTE_PURE + _GL_ATTRIBUTE_REPRODUCIBLE + _GL_ATTRIBUTE_UNSEQUENCED + which may expand to bracket syntax [[...]], must come first, before the + storage-class specifier. + * Other _GL_ATTRIBUTE_* macros, that expand to __attribute__((...)) syntax, + are better placed between the storage-class specifier and the return + type. + */ + +/* Attributes in bracket syntax [[...]] vs. attributes in __attribute__((...)) + syntax, in variable declarations. + + At which position can they be placed? + (Last tested with gcc/g++ 14 and clang/clang++ 18.) + + =========================== foo.c = foo.cc =========================== + #ifdef __cplusplus + # define CC "C" + #else + # define CC + #endif + + #define BD [[__deprecated__]] + #define AD __attribute__ ((__deprecated__)) + + // gcc clang g++ clang++ + + BD extern CC int var; // error error + extern CC BD int var; // error error + extern CC int BD var; // warn error warn error + extern CC int var BD; + + AD extern CC int var; // warn + extern CC AD int var; + extern CC int AD var; + extern CC int var AD; + + BD extern CC int z[]; // error error + extern CC BD int z[]; // error error + extern CC int BD z[]; // warn error warn error + extern CC int z1 BD []; + extern CC int z[] BD; // warn error error + + AD extern CC int z[]; // warn + extern CC AD int z[]; + extern CC int AD z[]; + extern CC int z2 AD []; // error error error error + extern CC int z[] AD; + ====================================================================== + + * For non-array variables, the only good position is after the variable name, + that is, at the end of the declaration. + * For array variables, you will need to distinguish C and C++: + - In C, before the 'extern' keyword. + - In C++, between the 'extern "C"' and the variable's type. + */ ]dnl There is no _GL_ATTRIBUTE_ALIGNED; use stdalign's alignas instead. [ /* _GL_ATTRIBUTE_ALLOC_SIZE ((N)) declares that the Nth argument of the function @@ -151,7 +353,7 @@ AC_DEFUN([gl_COMMON_BODY], [ _GL_ATTRIBUTE_ALLOC_SIZE ((M, N)) declares that the Mth argument multiplied by the Nth argument of the function is the size of the returned memory block. */ -/* Applies to: function, pointer to function, function types. */ +/* Applies to: functions, pointer to functions, function types. */ #ifndef _GL_ATTRIBUTE_ALLOC_SIZE # if _GL_HAS_ATTRIBUTE (alloc_size) # define _GL_ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args)) @@ -162,7 +364,7 @@ AC_DEFUN([gl_COMMON_BODY], [ /* _GL_ATTRIBUTE_ALWAYS_INLINE tells that the compiler should always inline the function and report an error if it cannot do so. */ -/* Applies to: function. */ +/* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_ALWAYS_INLINE # if _GL_HAS_ATTRIBUTE (always_inline) # define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) @@ -174,7 +376,7 @@ AC_DEFUN([gl_COMMON_BODY], [ /* _GL_ATTRIBUTE_ARTIFICIAL declares that the function is not important to show in stack traces when debugging. The compiler should omit the function from stack traces. */ -/* Applies to: function. */ +/* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_ARTIFICIAL # if _GL_HAS_ATTRIBUTE (artificial) # define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) @@ -200,18 +402,23 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif #endif -/* _GL_ATTRIBUTE_CONST declares that it is OK for a compiler to omit duplicate - calls to the function with the same arguments. - This attribute is safe for a function that neither depends on nor affects - observable state, and always returns exactly once - e.g., does not loop - forever, and does not call longjmp. - (This attribute is stricter than _GL_ATTRIBUTE_PURE.) */ +/* _GL_ATTRIBUTE_CONST declares: + It is OK for a compiler to move calls to the function and to omit + calls to the function if another call has the same arguments or the + result is not used. + This attribute is safe for a function that neither depends on + nor affects state, and always returns exactly once - + e.g., does not raise an exception, call longjmp, or loop forever. + (This attribute is stricter than _GL_ATTRIBUTE_PURE because the + function cannot observe state. It is stricter than + _GL_ATTRIBUTE_UNSEQUENCED because the function must return exactly + once and cannot depend on state addressed by its arguments.) */ /* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_CONST # if _GL_HAS_ATTRIBUTE (const) # define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) # else -# define _GL_ATTRIBUTE_CONST +# define _GL_ATTRIBUTE_CONST _GL_ATTRIBUTE_UNSEQUENCED # endif #endif @@ -480,7 +687,7 @@ AC_DEFUN([gl_COMMON_BODY], [ other attributes. */ #ifndef _GL_ATTRIBUTE_NOTHROW # if defined __cplusplus -# if _GL_GNUC_PREREQ (2, 8) || __clang_major >= 4 +# if _GL_GNUC_PREREQ (2, 8) || __clang_major__ >= 4 # if __cplusplus >= 201103L # define _GL_ATTRIBUTE_NOTHROW noexcept (true) # else @@ -505,25 +712,58 @@ AC_DEFUN([gl_COMMON_BODY], [ /* Applies to: struct members, struct, union, in C++ also: class. */ #ifndef _GL_ATTRIBUTE_PACKED -# if _GL_HAS_ATTRIBUTE (packed) +/* Oracle Studio 12.6 miscompiles code with __attribute__ ((__packed__)) despite + __has_attribute OK. */ +# if _GL_HAS_ATTRIBUTE (packed) && !defined __SUNPRO_C # define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) # else # define _GL_ATTRIBUTE_PACKED # endif #endif -/* _GL_ATTRIBUTE_PURE declares that It is OK for a compiler to omit duplicate - calls to the function with the same arguments if observable state is not - changed between calls. - This attribute is safe for a function that does not affect - observable state, and always returns exactly once. - (This attribute is looser than _GL_ATTRIBUTE_CONST.) */ +/* _GL_ATTRIBUTE_PURE declares: + It is OK for a compiler to move calls to the function and to omit + calls to the function if another call has the same arguments or the + result is not used, and if observable state is the same. + This attribute is safe for a function that does not affect observable state + and always returns exactly once. + (This attribute is looser than _GL_ATTRIBUTE_CONST because the function + can depend on observable state. It is stricter than + _GL_ATTRIBUTE_REPRODUCIBLE because the function must return exactly + once and cannot affect state addressed by its arguments.) */ /* Applies to: functions. */ #ifndef _GL_ATTRIBUTE_PURE # if _GL_HAS_ATTRIBUTE (pure) # define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else -# define _GL_ATTRIBUTE_PURE +# define _GL_ATTRIBUTE_PURE _GL_ATTRIBUTE_REPRODUCIBLE +# endif +#endif + +/* _GL_ATTRIBUTE_REPRODUCIBLE declares: + It is OK for a compiler to move calls to the function and to omit duplicate + calls to the function with the same arguments, so long as the state + addressed by its arguments is the same and is updated in time for + the rest of the program. + This attribute is safe for a function that is effectless and idempotent; see + ISO C 23 § 6.7.12.7 for a definition of these terms. + (This attribute is looser than _GL_ATTRIBUTE_UNSEQUENCED because + the function need not be stateless and idempotent. It is looser + than _GL_ATTRIBUTE_PURE because the function need not return + exactly once and can affect state addressed by its arguments.) + See also <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2956.htm> and + <https://stackoverflow.com/questions/76847905/>. */ +/* Applies to: functions, pointer to functions, function types. */ +#ifndef _GL_ATTRIBUTE_REPRODUCIBLE +/* This may be revisited when gcc and clang support [[reproducible]] or possibly + __attribute__ ((__reproducible__)). */ +# ifndef _GL_BRACKET_BEFORE_ATTRIBUTE +# if _GL_HAS_ATTRIBUTE (reproducible) +# define _GL_ATTRIBUTE_REPRODUCIBLE [[reproducible]] +# endif +# endif +# ifndef _GL_ATTRIBUTE_REPRODUCIBLE +# define _GL_ATTRIBUTE_REPRODUCIBLE # endif #endif @@ -551,6 +791,33 @@ AC_DEFUN([gl_COMMON_BODY], [ # endif #endif +/* _GL_ATTRIBUTE_UNSEQUENCED declares: + It is OK for a compiler to move calls to the function and to omit duplicate + calls to the function with the same arguments, so long as the state + addressed by its arguments is the same. + This attribute is safe for a function that is effectless, idempotent, + stateless, and independent; see ISO C 23 § 6.7.12.7 for a definition of + these terms. + (This attribute is stricter than _GL_ATTRIBUTE_REPRODUCIBLE because + the function must be stateless and independent. It is looser than + _GL_ATTRIBUTE_CONST because the function need not return exactly + once and can depend on state addressed by its arguments.) + See also <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2956.htm> and + <https://stackoverflow.com/questions/76847905/>. */ +/* Applies to: functions, pointer to functions, function types. */ +#ifndef _GL_ATTRIBUTE_UNSEQUENCED +/* This may be revisited when gcc and clang support [[unsequenced]] or possibly + __attribute__ ((__unsequenced__)). */ +# ifndef _GL_BRACKET_BEFORE_ATTRIBUTE +# if _GL_HAS_ATTRIBUTE (unsequenced) +# define _GL_ATTRIBUTE_UNSEQUENCED [[unsequenced]] +# endif +# endif +# ifndef _GL_ATTRIBUTE_UNSEQUENCED +# define _GL_ATTRIBUTE_UNSEQUENCED +# endif +#endif + /* A helper macro. Don't use it directly. */ #ifndef _GL_ATTRIBUTE_UNUSED # if _GL_HAS_ATTRIBUTE (unused) @@ -575,6 +842,35 @@ AC_DEFUN([gl_COMMON_BODY], [ # define _GL_UNUSED_LABEL # endif #endif + +/* The following attributes enable detection of multithread-safety problems + and resource leaks at compile-time, by clang ≥ 15, when the warning option + -Wthread-safety is enabled. For usage, see + <https://clang.llvm.org/docs/ThreadSafetyAnalysis.html>. */ +#ifndef _GL_ATTRIBUTE_CAPABILITY_TYPE +# if __clang_major__ >= 15 +# define _GL_ATTRIBUTE_CAPABILITY_TYPE(concept) \ + __attribute__ ((__capability__ (concept))) +#else +# define _GL_ATTRIBUTE_CAPABILITY_TYPE(concept) +# endif +#endif +#ifndef _GL_ATTRIBUTE_ACQUIRE_CAPABILITY +# if __clang_major__ >= 15 +# define _GL_ATTRIBUTE_ACQUIRE_CAPABILITY(resource) \ + __attribute__ ((__acquire_capability__ (resource))) +# else +# define _GL_ATTRIBUTE_ACQUIRE_CAPABILITY(resource) +# endif +#endif +#ifndef _GL_ATTRIBUTE_RELEASE_CAPABILITY +# if __clang_major__ >= 15 +# define _GL_ATTRIBUTE_RELEASE_CAPABILITY(resource) \ + __attribute__ ((__release_capability__ (resource))) +# else +# define _GL_ATTRIBUTE_RELEASE_CAPABILITY(resource) +# endif +#endif ]) AH_VERBATIM([c_linkage], [/* In C++, there is the concept of "language linkage", that encompasses @@ -1084,11 +1380,12 @@ AC_DEFUN([gl_CC_GNULIB_WARNINGS], dnl -Wno-type-limits >= 4.3 >= 3.9 dnl -Wno-undef >= 3 >= 3.9 dnl -Wno-unsuffixed-float-constants >= 4.5 + dnl -Wno-unused-const-variable >= 4.4 >= 3.9 dnl -Wno-unused-function >= 3 >= 3.9 dnl -Wno-unused-parameter >= 3 >= 3.9 dnl cat > conftest.c <<\EOF - #if __GNUC__ >= 3 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + #if (__GNUC__ >= 3 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) -Wno-cast-qual -Wno-conversion -Wno-float-equal @@ -1097,23 +1394,26 @@ AC_DEFUN([gl_CC_GNULIB_WARNINGS], -Wno-unused-function -Wno-unused-parameter #endif - #if __GNUC__ + (__GNUC_MINOR__ >= 9) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + #if (__GNUC__ + (__GNUC_MINOR__ >= 9) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) -Wno-float-conversion #endif - #if __GNUC__ >= 7 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + #if (__GNUC__ >= 7 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) -Wimplicit-fallthrough #endif - #if __GNUC__ + (__GNUC_MINOR__ >= 8) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + #if (__GNUC__ + (__GNUC_MINOR__ >= 8) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) -Wno-pedantic #endif #if 3 < __clang_major__ + (9 <= __clang_minor__) -Wno-tautological-constant-out-of-range-compare #endif - #if __GNUC__ + (__GNUC_MINOR__ >= 3) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) + #if (__GNUC__ + (__GNUC_MINOR__ >= 3) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) -Wno-sign-conversion -Wno-type-limits #endif - #if __GNUC__ + (__GNUC_MINOR__ >= 5) > 4 + #if (__GNUC__ + (__GNUC_MINOR__ >= 4) > 4 && !defined __clang__) || (__clang_major__ + (__clang_minor__ >= 9) > 3) + -Wno-unused-const-variable + #endif + #if (__GNUC__ + (__GNUC_MINOR__ >= 5) > 4 && !defined __clang__) -Wno-unsuffixed-float-constants #endif EOF |