/* Provide public ATTRIBUTE_* names for the private _GL_ATTRIBUTE_*
macros used within Gnulib. */
+/* These attributes can be placed in two ways:
+ - At the start of a declaration (i.e. even before storage-class
+ specifiers!); then they apply to all entities that are declared
+ by the declaration.
+ - Immediately after the name of an entity being declared by the
+ declaration; then they apply to that entity only. */
+
#ifndef _GL_ATTRIBUTE_H
#define _GL_ATTRIBUTE_H
-/* C2X standard attributes have macro names that do not begin with
- 'ATTRIBUTE_'. */
+
+/* This file defines two types of attributes:
+ * C2X standard attributes. These have macro names that do not begin with
+ 'ATTRIBUTE_'.
+ * Selected GCC attributes; see:
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html
+ https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html
+ These names begin with 'ATTRIBUTE_' to avoid name clashes. */
+
+
+/* =============== Attributes for specific kinds of functions =============== */
+
+/* Attributes for functions that should not be used. */
+
+/* Warn if the entity is used. */
+/* Applies to:
+ - function, variable,
+ - struct, union, struct/union member,
+ - enumeration, enumeration item,
+ - typedef,
+ in C++ also: namespace, class, template specialization. */
#define DEPRECATED _GL_ATTRIBUTE_DEPRECATED
-#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH
-#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
-#define NODISCARD _GL_ATTRIBUTE_NODISCARD
-/* Selected GCC attributes; see:
- https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
- These names begin 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_COLD _GL_ATTRIBUTE_COLD
-#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
-#define ATTRIBUTE_DEPRECATED _GL_ATTRIBUTE_DEPRECATED
+/* If a function call is not optimized way, warn with MSG. */
+/* Applies to: functions. */
+#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING (msg)
+
+/* If a function call is not optimized way, report an error with MSG. */
+/* Applies to: functions. */
#define ATTRIBUTE_ERROR(msg) _GL_ATTRIBUTE_ERROR (msg)
-#define ATTRIBUTE_EXTERNALLY_VISIBLE _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
-#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT (spec)
-#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF
-#define ATTRIBUTE_MAY_ALIAS _GL_ATTRIBUTE_MAY_ALIAS
+
+
+/* Attributes for memory-allocating functions. */
+
+/* The function returns a pointer to freshly allocated memory. */
+/* Applies to: functions. */
#define ATTRIBUTE_MALLOC _GL_ATTRIBUTE_MALLOC
-#define ATTRIBUTE_NOINLINE _GL_ATTRIBUTE_NOINLINE
+
+/* ATTRIBUTE_ALLOC_SIZE ((N)) - The Nth argument of the function
+ is the size of the returned memory block.
+ ATTRIBUTE_ALLOC_SIZE ((M, N)) - Multiply the Mth and Nth arguments
+ to determine the size of the returned memory block. */
+/* Applies to: function, pointer to function, function types. */
+#define ATTRIBUTE_ALLOC_SIZE(args) _GL_ATTRIBUTE_ALLOC_SIZE (args)
+
+
+/* Attributes for variadic functions. */
+
+/* The variadic function expects a trailing NULL argument.
+ ATTRIBUTE_SENTINEL () - The last argument is NULL.
+ ATTRIBUTE_SENTINEL ((N)) - The (N+1)st argument from the end is NULL. */
+/* Applies to: functions. */
+#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL (pos)
+
+
+/* ================== Attributes for compiler diagnostics ================== */
+
+/* Attributes that help the compiler diagnose programmer mistakes.
+ Some of them may also help for some compiler optimizations. */
+
+/* ATTRIBUTE_FORMAT ((ARCHETYPE, STRING-INDEX, FIRST-TO-CHECK)) -
+ The STRING-INDEXth function argument is a format string of style
+ ARCHETYPE, which is one of:
+ printf, gnu_printf
+ scanf, gnu_scanf,
+ strftime, gnu_strftime,
+ strfmon,
+ or the same thing prefixed and suffixed with '__'.
+ If FIRST-TO-CHECK is not 0, arguments starting at FIRST-TO_CHECK
+ are suitable for the format string. */
+/* Applies to: functions. */
+#define ATTRIBUTE_FORMAT(spec) _GL_ATTRIBUTE_FORMAT (spec)
+
+/* ATTRIBUTE_NONNULL ((N1, N2,...)) - Arguments N1, N2,... must not be NULL.
+ ATTRIBUTE_NONNULL () - All pointer arguments must not be null. */
+/* Applies to: functions. */
#define ATTRIBUTE_NONNULL(args) _GL_ATTRIBUTE_NONNULL (args)
+
+/* The function's return value is a non-NULL pointer. */
+/* Applies to: functions. */
+#define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL
+
+/* Warn if the caller does not use the return value,
+ unless the caller uses something like ignore_value. */
+/* Applies to: function, enumeration, class. */
+#define NODISCARD _GL_ATTRIBUTE_NODISCARD
+
+
+/* Attributes that disable false alarms when the compiler diagnoses
+ programmer "mistakes". */
+
+/* Do not warn if the entity is not used. */
+/* Applies to:
+ - function, variable,
+ - struct, union, struct/union member,
+ - enumeration, enumeration item,
+ - typedef,
+ in C++ also: class. */
+#define MAYBE_UNUSED _GL_ATTRIBUTE_MAYBE_UNUSED
+
+/* The contents of a character array is not meant to be NUL-terminated. */
+/* Applies to: struct/union members and variables that are arrays of element
+ type '[[un]signed] char'. */
#define ATTRIBUTE_NONSTRING _GL_ATTRIBUTE_NONSTRING
+
+/* Do not warn if control flow falls through to the immediately
+ following 'case' or 'default' label. */
+/* Applies to: Empty statement (;), inside a 'switch' statement. */
+#define FALLTHROUGH _GL_ATTRIBUTE_FALLTHROUGH
+
+
+/* ================== Attributes for debugging information ================== */
+
+/* Attributes regarding debugging information emitted by the compiler. */
+
+/* Omit the function from stack traces when debugging. */
+/* Applies to: function. */
+#define ATTRIBUTE_ARTIFICIAL _GL_ATTRIBUTE_ARTIFICIAL
+
+/* Make the entity visible to debuggers etc., even with '-fwhole-program'. */
+/* Applies to: functions, variables. */
+#define ATTRIBUTE_EXTERNALLY_VISIBLE _GL_ATTRIBUTE_EXTERNALLY_VISIBLE
+
+
+/* ========== Attributes that mainly direct compiler optimizations ========== */
+
+/* The function does not throw exceptions. */
+/* Applies to: functions. */
#define ATTRIBUTE_NOTHROW _GL_ATTRIBUTE_NOTHROW
-#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED
+
+/* Do not inline the function. */
+/* Applies to: functions. */
+#define ATTRIBUTE_NOINLINE _GL_ATTRIBUTE_NOINLINE
+
+/* Always inline the function, and report an error if the compiler
+ cannot inline. */
+/* Applies to: function. */
+#define ATTRIBUTE_ALWAYS_INLINE _GL_ATTRIBUTE_ALWAYS_INLINE
+
+/* The function does not affect observable state, and always returns a value.
+ Compilers can omit duplicate calls with the same arguments if
+ observable state is not changed between calls. (This attribute is
+ looser than ATTRIBUTE_CONST.) */
+/* Applies to: functions. */
#define ATTRIBUTE_PURE _GL_ATTRIBUTE_PURE
-#define ATTRIBUTE_RETURNS_NONNULL _GL_ATTRIBUTE_RETURNS_NONNULL
-#define ATTRIBUTE_SENTINEL(pos) _GL_ATTRIBUTE_SENTINEL (pos)
-#define ATTRIBUTE_WARNING(msg) _GL_ATTRIBUTE_WARNING (msg)
+
+/* The function neither depends on nor affects observable state,
+ and always returns a value. Compilers can omit duplicate calls with
+ the same arguments. (This attribute is stricter than ATTRIBUTE_PURE.) */
+/* Applies to: functions. */
+#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
+
+/* The function is rarely executed. */
+/* Applies to: functions. */
+#define ATTRIBUTE_COLD _GL_ATTRIBUTE_COLD
+
+/* If called from some other compilation unit, the function executes
+ code from that unit only by return or by exception handling,
+ letting the compiler optimize that unit more aggressively. */
+/* Applies to: functions. */
+#define ATTRIBUTE_LEAF _GL_ATTRIBUTE_LEAF
+
+/* For struct members: The member has the smallest possible alignment.
+ For struct, union, class: All members have the smallest possible alignment,
+ minimizing the memory required. */
+/* Applies to: struct members, struct, union,
+ in C++ also: class. */
+#define ATTRIBUTE_PACKED _GL_ATTRIBUTE_PACKED
+
+
+/* ================ Attributes that make invalid code valid ================ */
+
+/* Attributes that prevent fatal compiler optimizations for code that is not
+ fully ISO C compliant. */
+
+/* Pointers to the type may point to the same storage as pointers to
+ other types, thus disabling strict aliasing optimization. */
+/* Applies to: types. */
+#define ATTRIBUTE_MAY_ALIAS _GL_ATTRIBUTE_MAY_ALIAS
+
#endif /* _GL_ATTRIBUTE_H */
SSIZE_MAX < SIZE_MAX ? (size_t) SSIZE_MAX + 1 : SIZE_MAX;
char stack_buf[1024];
+#if (defined GCC_LINT || defined lint) && _GL_GNUC_PREREQ (10, 1)
+ /* Pacify preadlinkat without creating a pointer to the stack
+ that a broken gcc -Wreturn-local-addr would cry wolf about. See:
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95044
+ This workaround differs from the mainline code, but
+ no other way to pacify GCC 10.1.0 is known; even an explicit
+ #pragma does not pacify GCC. When the GCC bug is fixed this
+ workaround should be limited to the broken GCC versions. */
+# define WORK_AROUND_GCC_BUG_95044
+#endif
+
if (! alloc)
alloc = &stdlib_allocator;
- if (! buffer_size)
+ if (!buffer)
{
+#ifdef WORK_AROUND_GCC_BUG_95044
+ buffer = alloc->allocate (sizeof stack_buf);
+#else
/* Allocate the initial buffer on the stack. This way, in the
common case of a symlink of small size, we get away with a
single small malloc() instead of a big malloc() followed by a
shrinking realloc(). */
buffer = stack_buf;
+#endif
buffer_size = sizeof stack_buf;
}
buf = buffer;
buf_size = buffer_size;
- do
+ while (buf)
{
/* Attempt to read the link into the current buffer. */
ssize_t link_length = preadlinkat (fd, filename, buf, buf_size);
if (buf == stack_buf)
{
- char *b = (char *) alloc->allocate (link_size);
+ char *b = alloc->allocate (link_size);
buf_size = link_size;
if (! b)
break;
- memcpy (b, buf, link_size);
- buf = b;
+ return memcpy (b, buf, link_size);
}
- else if (link_size < buf_size && buf != buffer && alloc->reallocate)
+
+ if (link_size < buf_size && buf != buffer && alloc->reallocate)
{
/* Shrink BUF before returning it. */
- char *b = (char *) alloc->reallocate (buf, link_size);
+ char *b = alloc->reallocate (buf, link_size);
if (b)
- buf = b;
+ return b;
}
return buf;
if (buf != buffer)
alloc->free (buf);
- if (buf_size <= buf_size_max / 2)
- buf_size *= 2;
+ if (buf_size < buf_size_max / 2)
+ buf_size = 2 * buf_size + 1;
else if (buf_size < buf_size_max)
buf_size = buf_size_max;
else if (buf_size_max < SIZE_MAX)
}
else
break;
- buf = (char *) alloc->allocate (buf_size);
+ buf = alloc->allocate (buf_size);
}
- while (buf);
if (alloc->die)
alloc->die (buf_size);
GB18030 and the character to be searched is a digit. */
# undef strchr
/* Assume strchr is always declared. */
-_GL_WARN_ON_USE (strchr, "strchr cannot work correctly on character strings "
- "in some multibyte locales - "
- "use mbschr if you care about internationalization");
+_GL_WARN_ON_USE_CXX (strchr, const char *, (const char *, int),
+ "strchr cannot work correctly on character strings "
+ "in some multibyte locales - "
+ "use mbschr if you care about internationalization");
#endif
/* Find the first occurrence of C in S or the final NUL byte. */
locale encoding is GB18030 and one of the characters to be searched is a
digit. */
# undef strpbrk
-_GL_WARN_ON_USE (strpbrk, "strpbrk cannot work correctly on character strings "
- "in multibyte locales - "
- "use mbspbrk if you care about internationalization");
+_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *),
+ "strpbrk cannot work correctly on character strings "
+ "in multibyte locales - "
+ "use mbspbrk if you care about internationalization");
# endif
#elif defined GNULIB_POSIXCHECK
# undef strpbrk
# if HAVE_RAW_DECL_STRPBRK
-_GL_WARN_ON_USE (strpbrk, "strpbrk is unportable - "
- "use gnulib module strpbrk for portability");
+_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *),
+ "strpbrk is unportable - "
+ "use gnulib module strpbrk for portability");
# endif
#endif
GB18030 and the character to be searched is a digit. */
# undef strrchr
/* Assume strrchr is always declared. */
-_GL_WARN_ON_USE (strrchr, "strrchr cannot work correctly on character strings "
- "in some multibyte locales - "
- "use mbsrchr if you care about internationalization");
+_GL_WARN_ON_USE_CXX (strrchr, const char *, (const char *, int),
+ "strrchr cannot work correctly on character strings "
+ "in some multibyte locales - "
+ "use mbsrchr if you care about internationalization");
#endif
/* Search the next delimiter (char listed in DELIM) starting at *STRINGP.
#endif
/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
- is like _GL_WARN_ON_USE (function, "string"), except that the function is
- declared with the given prototype, consisting of return type, parameters,
- and attributes.
+ is like _GL_WARN_ON_USE (function, "string"), except that in C++ mode the
+ function is declared with the given prototype, consisting of return type,
+ parameters, and attributes.
This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
not work in this case. */
#ifndef _GL_WARN_ON_USE_CXX
-# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+# if !defined __cplusplus
# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+ _GL_WARN_ON_USE (function, msg)
+# else
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
extern rettype function parameters_and_attributes \
__attribute__ ((__warning__ (msg)))
-# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
/* Verify the existence of the function. */
-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
extern rettype function parameters_and_attributes
-# else /* Unsupported. */
-# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+# else /* Unsupported. */
+# define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
_GL_WARN_EXTERN_C int _gl_warn_on_use
+# endif
# endif
#endif