bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* Possible testing case of snprintf.
@ 2020-02-09 14:44 Mats Erik Andersson
  2020-02-09 15:24 ` Tim Rühsen
  0 siblings, 1 reply; 20+ messages in thread
From: Mats Erik Andersson @ 2020-02-09 14:44 UTC (permalink / raw)
  To: bug-gnulib

Hello there!

This note has its origin in a report received at bug-inetutils.
The following test code for snprintf() is a simplyfied detection
I have implemented as a warning-only test in Gnu Inetutils.
My point is that Linux/glibc and kfreebsd/glibc triggers this
warning, but OpenSolaris, OpenIndiana, FreeBSD, OpenBSD, NetBSD,
and DragonflyBSD do not! Reading the replacement code for the
Gnulib module snprintf, neither would your function, should it
undergo the test. In conclusion, this is a case where the native
glibc function snprintf() behaves worse than does your replacement.

  #define MESSAGE       "try a fool"
  #define WRONG_MESSAGE "fool"

  char msg[sizeof (MESSAGE)] = "try a ";

  snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);

  if (!strcmp (msg, WRONG_MESSAGE))
    printf ("Warning! snprintf got confused!\n");

Observe that `msg' is target, as well as source. POSIX mentions
nothing about such a use case, but glibc will produce "fool",
whereas all BSD unices as well as OpenSolaris descendants will
produce "try a fool". Tacitly, POSIX would probably cry out
a statement like "Undefined"!

It is my opinion that this discrepancies should at least be documented
in 'snprintf.texi', were you not to take matter so far as to include
this as some sort of test, after due elaboration.

Gnu Inetutils uses legacy code from BSD4.4, where the related use
is present and did not cause troubles, but as the recent report
submitted to us, the code does produce portability issues when
brought to glibc. It has taken a long time to discover this state
of affaires, but now it has surfaced!

On behalf of Gnu Inetutils,

  Mats Erik Andersson.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Possible testing case of snprintf.
  2020-02-09 14:44 Possible testing case of snprintf Mats Erik Andersson
@ 2020-02-09 15:24 ` Tim Rühsen
  2020-02-10  3:02   ` restrict Bruno Haible
  0 siblings, 1 reply; 20+ messages in thread
From: Tim Rühsen @ 2020-02-09 15:24 UTC (permalink / raw)
  To: Mats Erik Andersson, bug-gnulib


[-- Attachment #1.1: Type: text/plain, Size: 2379 bytes --]

On 09.02.20 15:44, Mats Erik Andersson wrote:
> Hello there!
> 
> This note has its origin in a report received at bug-inetutils.
> The following test code for snprintf() is a simplyfied detection
> I have implemented as a warning-only test in Gnu Inetutils.
> My point is that Linux/glibc and kfreebsd/glibc triggers this
> warning, but OpenSolaris, OpenIndiana, FreeBSD, OpenBSD, NetBSD,
> and DragonflyBSD do not! Reading the replacement code for the
> Gnulib module snprintf, neither would your function, should it
> undergo the test. In conclusion, this is a case where the native
> glibc function snprintf() behaves worse than does your replacement.
> 
>   #define MESSAGE       "try a fool"
>   #define WRONG_MESSAGE "fool"
> 
>   char msg[sizeof (MESSAGE)] = "try a ";
> 
>   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
> 
>   if (!strcmp (msg, WRONG_MESSAGE))
>     printf ("Warning! snprintf got confused!\n");
> 
> Observe that `msg' is target, as well as source. POSIX mentions
> nothing about such a use case, but glibc will produce "fool",
> whereas all BSD unices as well as OpenSolaris descendants will
> produce "try a fool". Tacitly, POSIX would probably cry out
> a statement like "Undefined"!

s(n)printf declaration uses the restrict keyword. That basically means
that each of the pointers in the arguments points to the same block of
memory.

gcc -Wall tells you so (gcc 8 and upwards):
$ gcc -Wall msg.c -o msg
msg.c: In function ‘main’:
msg.c:11:13: warning: passing argument 1 to restrict-qualified parameter
aliases with argument 4 [-Wrestrict]
   11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
      |             ^~~                        ~~~
msg.c:11:35: warning: ‘%s’ directive output may be truncated writing 4
bytes into a region of size between 1 and 11 [-Wformat-truncation=]
   11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
      |                                   ^~
msg.c:11:3: note: ‘snprintf’ output between 5 and 15 bytes into a
destination of size 11
   11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Except in rare cases, compiler warnings indicate that the programmer is
wrong. Turn them all (well, almost all) on !

Regards, Tim


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-09 15:24 ` Tim Rühsen
@ 2020-02-10  3:02   ` Bruno Haible
  2020-02-10  8:39     ` restrict Jeffrey Walton
                       ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Bruno Haible @ 2020-02-10  3:02 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

Tim Rühsen wrote:
> gcc -Wall tells you so (gcc 8 and upwards):
> $ gcc -Wall msg.c -o msg
> msg.c: In function ‘main’:
> msg.c:11:13: warning: passing argument 1 to restrict-qualified parameter
> aliases with argument 4 [-Wrestrict]
>    11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
>       |             ^~~                        ~~~
> msg.c:11:35: warning: ‘%s’ directive output may be truncated writing 4
> bytes into a region of size between 1 and 11 [-Wformat-truncation=]
>    11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
>       |                                   ^~
> msg.c:11:3: note: ‘snprintf’ output between 5 and 15 bytes into a
> destination of size 11
>    11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
>       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 

Oh, the 'restrict' keyword is actually useful (other than for micro-
optimizations)! Thanks for this pointer, Tim.

So, it would make sense to use this keyword in function declarations in
public .h files in gnulib.

For internal .h files in gnulib, there's no point - this code is assumed
correct, no need to try to get GCC to produce warnings here.

What does 'restrict' precisely mean? ISO C 99 § 6.7.3.(7):
  "An object that is accessed through a restrict-qualified pointer has a
   special association with that pointer. This association, defined in
   6.7.3.1 below, requires that all accesses to that object use, directly
   or indirectly, the value of that particular pointer.115) The intended
   use of the restrict qualifier (like the register storage class) is to
   promote optimization, and deleting all instances of the qualifier from
   all preprocessing translation units composing a conforming program
   does not change its meaning (i.e., observable behavior)."

Which function declarations could therefore profit from the 'restrict'
keyword?

  - Only parameters of pointer types, excluding function pointer types,
    matter.

  - If all pointer parameters are 'const SOMETHING *', the function
    is not writing into them, therefore 'restrict' is redundant.
    Example: int strcmp (const char *, const char *);

  - If all pointer parameters point to different types, excluding 'void *',
    ISO C forbids aliasing anyway, therefore 'restrict' is redundant.
    Example: void dfacomp (char const *, ptrdiff_t, struct dfa *, bool);
    and https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html

  - If, among the parameters, there are N parameters of type
      [const] TYPE *
    adding the 'restrict' keyword to N-1 of them is equivalent to adding
    the 'restrict' keyword to all N of them.
    See ISO C 99 § 6.7.3.1.(7) [Example 1].

    GCC's warning facility understands this, regarding the non-const pointer.
    Test case:
    ========================================================================
    #include <stddef.h>
    extern int smprintf (char *restrict, size_t, const char *, ...)
         __attribute__ ((__format__ (__printf__, 3, 4)));
    int main ()
    {
      char msg[sizeof ("try a fool")] = "try a ";
      smprintf (msg, sizeof (msg), "%s%s", msg, "fool");
    }
    ========================================================================

  - If a function has an input parameter of type
      const TYPE *
    and an output parameter of type
      TYPE *
    then the 'restrict' keyword means that the implementation may write
    the output before having finished reading all the input.
    Example:
      void arctwo_encrypt (arctwo_context *context, const char *inbuf,
                           char * restrict outbuf, size_t length);
    Whereas the absence of the 'restrict' keyword means that the
    implementation will read all the input _before_ starting to store
    the output.
    Example:
      int hmac_md5 (const void *key, size_t keylen,
                    const void *buffer, size_t buflen, void *resbuf);

  - 'restrict' should NOT be used for multiple output parameters of the
    same type, when only a single word is written through each parameter.
    Example: ssize_t copy_file_range (int ifd, off_t *ipos, int ofd, off_t *opos,
                                      size_t len, unsigned flags);
    Rationale: It is OK to have ipos and opos point to different elements
    of the same off_t[] array.

Is this all right, or did I misinterpret something?

If it is right, then how about this start of a patch? (Not sure whether I need
to add the 'restrict' keyword also in the function definitions?)

Bruno


diff --git a/lib/amemxfrm.h b/lib/amemxfrm.h
index 7cfc283..0edd3d5 100644
--- a/lib/amemxfrm.h
+++ b/lib/amemxfrm.h
@@ -38,7 +38,8 @@ extern "C" {
    freshly allocated string is returned.  In both cases, *lengthp is set to the
    length of the returned string.
    Upon failure, return NULL, with errno set.  */
-extern char * amemxfrm (char *s, size_t n, char *resultbuf, size_t *lengthp);
+extern char * amemxfrm (char * restrict s, size_t n,
+                        char * restrict resultbuf, size_t *lengthp);
 
 
 #ifdef __cplusplus
diff --git a/lib/arcfour.h b/lib/arcfour.h
index b77df1a..b23e792 100644
--- a/lib/arcfour.h
+++ b/lib/arcfour.h
@@ -37,7 +37,7 @@ typedef struct
    before this function is called. */
 extern void
 arcfour_stream (arcfour_context * context,
-                const char *inbuf, char *outbuf, size_t length);
+                const char *inbuf, char * restrict outbuf, size_t length);
 
 /* Initialize CONTEXT using encryption KEY of KEYLEN bytes.  KEY
    should be 40 bits (5 bytes) or longer.  The KEY cannot be zero
diff --git a/lib/arctwo.h b/lib/arctwo.h
index 91f725f..e88489a 100644
--- a/lib/arctwo.h
+++ b/lib/arctwo.h
@@ -48,7 +48,7 @@ arctwo_setkey_ekb (arctwo_context *context,
    arctwo_setkey_ekb. */
 extern void
 arctwo_encrypt (arctwo_context *context, const char *inbuf,
-                char *outbuf, size_t length);
+                char * restrict outbuf, size_t length);
 
 /* Decrypt INBUF of size LENGTH into OUTBUF.  LENGTH must be a
    multiple of ARCTWO_BLOCK_SIZE.  CONTEXT hold the decryption key,
@@ -56,6 +56,6 @@ arctwo_encrypt (arctwo_context *context, const char *inbuf,
    arctwo_setkey_ekb. */
 extern void
 arctwo_decrypt (arctwo_context *context, const char *inbuf,
-                char *outbuf, size_t length);
+                char * restrict outbuf, size_t length);
 
 #endif /* ARCTWO_H */
diff --git a/lib/astrxfrm.h b/lib/astrxfrm.h
index a23ed70..9906659 100644
--- a/lib/astrxfrm.h
+++ b/lib/astrxfrm.h
@@ -37,7 +37,8 @@ extern "C" {
    freshly allocated string is returned.  In both cases, *lengthp is set to the
    length of the returned string.
    Upon failure, return NULL, with errno set.  */
-extern char * astrxfrm (const char *s, char *resultbuf, size_t *lengthp);
+extern char * astrxfrm (const char *s,
+                        char * restrict resultbuf, size_t *lengthp);
 
 
 #ifdef __cplusplus
diff --git a/lib/c-snprintf.h b/lib/c-snprintf.h
index bfdc081..3b31bd4 100644
--- a/lib/c-snprintf.h
+++ b/lib/c-snprintf.h
@@ -36,7 +36,8 @@
 extern "C" {
 #endif
 
-int c_snprintf (char *str, size_t size, const char *format, ...)
+extern int c_snprintf (char * restrict str, size_t size,
+                       const char *format, ...)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
 
 #ifdef __cplusplus
diff --git a/lib/c-vasnprintf.h b/lib/c-vasnprintf.h
index 1a69e56..c44a31b 100644
--- a/lib/c-vasnprintf.h
+++ b/lib/c-vasnprintf.h
@@ -66,7 +66,8 @@ extern "C" {
    Formatting takes place in the C locale, that is, the decimal point used in
    floating-point formatting directives is always '.'.
   */
-extern char *c_vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
+extern char *c_vasnprintf (char * restrict resultbuf, size_t *lengthp,
+                           const char *format, va_list args)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
 
 #ifdef __cplusplus
diff --git a/lib/c-vsnprintf.h b/lib/c-vsnprintf.h
index 97a2816..1b20fd5 100644
--- a/lib/c-vsnprintf.h
+++ b/lib/c-vsnprintf.h
@@ -39,7 +39,8 @@
 extern "C" {
 #endif
 
-int c_vsnprintf (char *str, size_t size, const char *format, va_list args)
+extern int c_vsnprintf (char * restrict str, size_t size,
+                        const char *format, va_list args)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
 
 #ifdef __cplusplus
diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h
index 584cfe9..f249ab6 100644
--- a/lib/careadlinkat.h
+++ b/lib/careadlinkat.h
@@ -47,7 +47,7 @@ struct allocator;
    set errno.  */
 
 char *careadlinkat (int fd, char const *filename,
-                    char *buffer, size_t buffer_size,
+                    char * restrict buffer, size_t buffer_size,
                     struct allocator const *alloc,
                     ssize_t (*preadlinkat) (int, char const *,
                                             char *, size_t));
diff --git a/lib/gc.h b/lib/gc.h
index 05fb8a3..bd90bd0 100644
--- a/lib/gc.h
+++ b/lib/gc.h
@@ -185,12 +185,12 @@ extern Gc_rc
 gc_pbkdf2_hmac (Gc_hash hash,
                 const char *P, size_t Plen,
                 const char *S, size_t Slen,
-                unsigned int c, char *DK, size_t dkLen);
+                unsigned int c, char * restrict DK, size_t dkLen);
 
 extern Gc_rc
 gc_pbkdf2_sha1 (const char *P, size_t Plen,
                 const char *S, size_t Slen,
-                unsigned int c, char *DK, size_t dkLen);
+                unsigned int c, char * restrict DK, size_t dkLen);
 
 /*
   TODO:
diff --git a/lib/gl_openssl.h b/lib/gl_openssl.h
index e5991d8..d188a6a 100644
--- a/lib/gl_openssl.h
+++ b/lib/gl_openssl.h
@@ -90,15 +90,15 @@ GL_CRYPTO_FN (_process_block) (const void *buf, size_t len, struct _gl_ctx *ctx)
 #endif
 
 GL_OPENSSL_INLINE void *
-GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void *res)
+GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void * restrict res)
 { OPENSSL_FN (_Final) ((unsigned char *) res, (_gl_CTX *) ctx); return res; }
 
 GL_OPENSSL_INLINE void *
-GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void *res)
+GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void * restrict res)
 { return OPENSSL_FN () ((const unsigned char *) buf, len, (unsigned char *) res); }
 
 GL_OPENSSL_INLINE void *
-GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void *res)
+GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void * restrict res)
 {
   /* Assume any unprocessed bytes in ctx are not to be ignored.  */
   _gl_CTX tmp_ctx = *(_gl_CTX *) ctx;
diff --git a/lib/memcoll.h b/lib/memcoll.h
index add0968..233385b 100644
--- a/lib/memcoll.h
+++ b/lib/memcoll.h
@@ -22,7 +22,7 @@
 
 # include <stddef.h>
 
-int memcoll (char *, size_t, char *, size_t);
+int memcoll (char * restrict, size_t, char * restrict, size_t);
 int memcoll0 (char const *, size_t, char const *, size_t);
 
 #endif /* MEMCOLL_H_ */
diff --git a/lib/monetary.in.h b/lib/monetary.in.h
index ab17917..5b67cec 100644
--- a/lib/monetary.in.h
+++ b/lib/monetary.in.h
@@ -79,15 +79,18 @@ extern "C" {
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define strfmon_l rpl_strfmon_l
 #  endif
-_GL_FUNCDECL_RPL (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
+_GL_FUNCDECL_RPL (strfmon_l, ssize_t, (char * restrict s, size_t maxsize,
+                                       locale_t locale,
                                        const char *format, ...)
                                       _GL_ATTRIBUTE_FORMAT_STRFMON (4, 5)
                                       _GL_ARG_NONNULL ((4)));
-_GL_CXXALIAS_RPL (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
+_GL_CXXALIAS_RPL (strfmon_l, ssize_t, (char * restrict s, size_t maxsize,
+                                       locale_t locale,
                                        const char *format, ...));
 # else
 #  if @HAVE_STRFMON_L@
-_GL_CXXALIAS_SYS (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
+_GL_CXXALIAS_SYS (strfmon_l, ssize_t, (char * restrict s, size_t maxsize,
+                                       locale_t locale,
                                        const char *format, ...));
 #  endif
 # endif
diff --git a/lib/parse-datetime.h b/lib/parse-datetime.h
index ab9b576..d2c7518 100644
--- a/lib/parse-datetime.h
+++ b/lib/parse-datetime.h
@@ -19,11 +19,13 @@
 #include <stdbool.h>
 #include <time.h>
 
-bool parse_datetime (struct timespec *, char const *, struct timespec const *);
+bool parse_datetime (struct timespec * restrict,
+                     char const *, struct timespec const *);
 
 /* parse_datetime2 flag: if set, print debug/progress information to STDERR */
 #define PARSE_DATETIME_DEBUG 1
 
 /* same as above, supporting additional flags */
-bool parse_datetime2 (struct timespec *, char const *, struct timespec const *,
+bool parse_datetime2 (struct timespec * restrict,
+                      char const *, struct timespec const *,
                       unsigned int flags, timezone_t, char const *);
diff --git a/lib/quotearg.h b/lib/quotearg.h
index d30fdd1..1261c8f 100644
--- a/lib/quotearg.h
+++ b/lib/quotearg.h
@@ -323,7 +323,7 @@ void set_custom_quoting (struct quoting_options *o,
    On output, BUFFER might contain embedded null bytes if ARGSIZE was
    not -1, the style of O does not use backslash escapes, and the
    flags of O do not request elision of null bytes.*/
-size_t quotearg_buffer (char *buffer, size_t buffersize,
+size_t quotearg_buffer (char * restrict buffer, size_t buffersize,
                         char const *arg, size_t argsize,
                         struct quoting_options const *o);
 
diff --git a/lib/regex-quote.h b/lib/regex-quote.h
index 185f9fe..0d166c7 100644
--- a/lib/regex-quote.h
+++ b/lib/regex-quote.h
@@ -77,7 +77,7 @@ extern size_t
 /* Copies the quoted string to p and returns the incremented p.
    There must be room for regex_quote_length (string, spec) + 1 bytes at p.  */
 extern char *
-       regex_quote_copy (char *p,
+       regex_quote_copy (char * restrict p,
                          const char *string, const struct regex_quote_spec *spec);
 
 /* Returns the freshly allocated quoted string.  */
diff --git a/lib/rijndael-api-fst.h b/lib/rijndael-api-fst.h
index 0553acc..e6ac5ab 100644
--- a/lib/rijndael-api-fst.h
+++ b/lib/rijndael-api-fst.h
@@ -157,7 +157,7 @@ extern int
 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
                       const rijndaelKeyInstance *key,
                       const char *input, size_t inputLen,
-                      char *outBuffer);
+                      char * restrict outBuffer);
 
 /* Encrypt data in INPUT, of INPUTOCTETS bytes length, placing the
    output in the pre-allocated OUTBUFFER which must hold at least
@@ -172,7 +172,7 @@ extern int
 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
                     const rijndaelKeyInstance *key,
                     const char *input, size_t inputOctets,
-                    char *outBuffer);
+                    char * restrict outBuffer);
 
 /* Decrypt data in INPUT, of INPUTLEN/8 bytes length, placing the
    output in the pre-allocated OUTBUFFER which must hold at least
@@ -185,7 +185,7 @@ extern int
 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
                       const rijndaelKeyInstance *key,
                       const char *input, size_t inputLen,
-                      char *outBuffer);
+                      char * restrict outBuffer);
 
 /* Decrypt data in INPUT, of INPUTOCTETS bytes length, placing the
    output in the pre-allocated OUTBUFFER which must hold at least
@@ -200,6 +200,6 @@ extern int
 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
                     const rijndaelKeyInstance *key,
                     const char *input, size_t inputOctets,
-                    char *outBuffer);
+                    char * restrict outBuffer);
 
 #endif /* __RIJNDAEL_API_FST_H */
diff --git a/lib/sh-quote.h b/lib/sh-quote.h
index 9dcd4cf..2f9a69b 100644
--- a/lib/sh-quote.h
+++ b/lib/sh-quote.h
@@ -33,7 +33,7 @@ extern size_t shell_quote_length (const char *string);
 
 /* Copies the quoted string to p and returns the incremented p.
    There must be room for shell_quote_length (string) + 1 bytes at p.  */
-extern char * shell_quote_copy (char *p, const char *string);
+extern char * shell_quote_copy (char * restrict p, const char *string);
 
 /* Returns the freshly allocated quoted string.  */
 extern char * shell_quote (const char *string);
diff --git a/lib/sha1.h b/lib/sha1.h
index 99c53da..e97914b 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -71,13 +71,13 @@ extern void sha1_process_bytes (const void *buffer, size_t len,
    in first 20 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
+extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void * restrict resbuf);
 
 
 /* Put result from CTX in first 20 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
+extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void * restrict resbuf);
 
 
 /* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
diff --git a/lib/sha256.h b/lib/sha256.h
index 1bc61d4..a1dad2e 100644
--- a/lib/sha256.h
+++ b/lib/sha256.h
@@ -70,15 +70,17 @@ extern void sha256_process_bytes (const void *buffer, size_t len,
    in first 32 (28) bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf);
-extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf);
+extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void * restrict resbuf);
+extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void * restrict resbuf);
 
 
 /* Put result from CTX in first 32 (28) bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
-extern void *sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
+extern void *sha256_read_ctx (const struct sha256_ctx *ctx,
+                              void * restrict resbuf);
+extern void *sha224_read_ctx (const struct sha256_ctx *ctx,
+                              void * restrict resbuf);
 
 
 /* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER.  The
diff --git a/lib/sha512.h b/lib/sha512.h
index aaf35a5..20818e0 100644
--- a/lib/sha512.h
+++ b/lib/sha512.h
@@ -70,8 +70,8 @@ extern void sha512_process_bytes (const void *buffer, size_t len,
    in first 64 (48) bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
-extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
+extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void * restrict resbuf);
+extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void * restrict resbuf);
 
 
 /* Put result from CTX in first 64 (48) bytes following RESBUF.  The result is
@@ -80,8 +80,10 @@ extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
 
    IMPORTANT: On some systems it is required that RESBUF is correctly
    aligned for a 32 bits value.  */
-extern void *sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
-extern void *sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
+extern void *sha512_read_ctx (const struct sha512_ctx *ctx,
+                              void * restrict resbuf);
+extern void *sha384_read_ctx (const struct sha512_ctx *ctx,
+                              void * restrict resbuf);
 
 
 /* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER.  The
diff --git a/lib/signal.in.h b/lib/signal.in.h
index 9fe9f60..9690953 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -133,16 +133,20 @@ typedef void (*sighandler_t) (int);
 #   define pthread_sigmask rpl_pthread_sigmask
 #  endif
 _GL_FUNCDECL_RPL (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how, const sigset_t *new_mask,
+                   sigset_t * restrict old_mask));
 _GL_CXXALIAS_RPL (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how, const sigset_t *new_mask,
+                   sigset_t * restrict old_mask));
 # else
 #  if !(@HAVE_PTHREAD_SIGMASK@ || defined pthread_sigmask)
 _GL_FUNCDECL_SYS (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how, const sigset_t *new_mask,
+                   sigset_t * restrict old_mask));
 #  endif
 _GL_CXXALIAS_SYS (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how, const sigset_t *new_mask,
+                   sigset_t * restrict old_mask));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (pthread_sigmask);
@@ -295,10 +299,12 @@ _GL_CXXALIASWARN (sigpending);
 #  define SIG_SETMASK 1  /* blocked_set = *set; */
 #  define SIG_UNBLOCK 2  /* blocked_set = blocked_set & ~*set; */
 _GL_FUNCDECL_SYS (sigprocmask, int,
-                  (int operation, const sigset_t *set, sigset_t *old_set));
+                  (int operation, const sigset_t *set,
+                   sigset_t * restrict old_set));
 # endif
 _GL_CXXALIAS_SYS (sigprocmask, int,
-                  (int operation, const sigset_t *set, sigset_t *old_set));
+                  (int operation, const sigset_t *set,
+                   sigset_t * restrict old_set));
 _GL_CXXALIASWARN (sigprocmask);
 
 /* Install the handler FUNC for signal SIG, and return the previous
diff --git a/lib/sm3.h b/lib/sm3.h
index e0bdd90..9da0ab3 100644
--- a/lib/sm3.h
+++ b/lib/sm3.h
@@ -75,12 +75,12 @@ extern void sm3_process_bytes (const void *buffer, size_t len,
    in first 32 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sm3_finish_ctx (struct sm3_ctx *ctx, void *resbuf);
+extern void *sm3_finish_ctx (struct sm3_ctx *ctx, void * restrict resbuf);
 
 /* Put result from CTX in first 32 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *sm3_read_ctx (const struct sm3_ctx *ctx, void *resbuf);
+extern void *sm3_read_ctx (const struct sm3_ctx *ctx, void * restrict resbuf);
 
 /* Compute SM3 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index 388565d..2386852 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -1113,20 +1113,20 @@ _GL_CXXALIASWARN (scanf);
 #   define snprintf rpl_snprintf
 #  endif
 _GL_FUNCDECL_RPL (snprintf, int,
-                  (char *str, size_t size, const char *format, ...)
+                  (char * restrict str, size_t size, const char *format, ...)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4)
                   _GL_ARG_NONNULL ((3)));
 _GL_CXXALIAS_RPL (snprintf, int,
-                  (char *str, size_t size, const char *format, ...));
+                  (char * restrict str, size_t size, const char *format, ...));
 # else
 #  if !@HAVE_DECL_SNPRINTF@
 _GL_FUNCDECL_SYS (snprintf, int,
-                  (char *str, size_t size, const char *format, ...)
+                  (char * restrict str, size_t size, const char *format, ...)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4)
                   _GL_ARG_NONNULL ((3)));
 #  endif
 _GL_CXXALIAS_SYS (snprintf, int,
-                  (char *str, size_t size, const char *format, ...));
+                  (char * restrict str, size_t size, const char *format, ...));
 # endif
 _GL_CXXALIASWARN (snprintf);
 #elif defined GNULIB_POSIXCHECK
@@ -1151,12 +1151,12 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define sprintf rpl_sprintf
 #  endif
-_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...)
+_GL_FUNCDECL_RPL (sprintf, int, (char * restrict str, const char *format, ...)
                                 _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
                                 _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...));
+_GL_CXXALIAS_RPL (sprintf, int, (char * restrict str, const char *format, ...));
 # else
-_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...));
+_GL_CXXALIAS_SYS (sprintf, int, (char * restrict str, const char *format, ...));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (sprintf);
@@ -1386,20 +1386,24 @@ _GL_CXXALIASWARN (vscanf);
 #   define vsnprintf rpl_vsnprintf
 #  endif
 _GL_FUNCDECL_RPL (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args)
+                  (char * restrict str, size_t size,
+                   const char *format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0)
                   _GL_ARG_NONNULL ((3)));
 _GL_CXXALIAS_RPL (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args));
+                  (char * restrict str, size_t size,
+                   const char *format, va_list args));
 # else
 #  if !@HAVE_DECL_VSNPRINTF@
 _GL_FUNCDECL_SYS (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args)
+                  (char * restrict str, size_t size,
+                   const char *format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0)
                   _GL_ARG_NONNULL ((3)));
 #  endif
 _GL_CXXALIAS_SYS (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args));
+                  (char * restrict str, size_t size,
+                   const char *format, va_list args));
 # endif
 _GL_CXXALIASWARN (vsnprintf);
 #elif defined GNULIB_POSIXCHECK
@@ -1416,17 +1420,17 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - "
 #   define vsprintf rpl_vsprintf
 #  endif
 _GL_FUNCDECL_RPL (vsprintf, int,
-                  (char *str, const char *format, va_list args)
+                  (char * restrict str, const char *format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (vsprintf, int,
-                  (char *str, const char *format, va_list args));
+                  (char * restrict str, const char *format, va_list args));
 # else
 /* Need to cast, because on Solaris, the third parameter is
                                                        __va_list args
    and GCC's fixincludes did not change this to __gnuc_va_list.  */
 _GL_CXXALIAS_SYS_CAST (vsprintf, int,
-                       (char *str, const char *format, va_list args));
+                       (char * restrict str, const char *format, va_list args));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vsprintf);
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 49bbf6f..5ae909d 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -866,15 +866,19 @@ _GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define realpath rpl_realpath
 #  endif
-_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved)
-                                    _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved));
+_GL_FUNCDECL_RPL (realpath, char *,
+                  (const char *name, char * restrict resolved)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (realpath, char *,
+                  (const char *name, char * restrict resolved));
 # else
 #  if !@HAVE_REALPATH@
-_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved)
-                                    _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_SYS (realpath, char *,
+                  (const char *name, char * restrict resolved)
+                  _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved));
+_GL_CXXALIAS_SYS (realpath, char *,
+                  (const char *name, char * restrict resolved));
 # endif
 _GL_CXXALIASWARN (realpath);
 #elif defined GNULIB_POSIXCHECK
diff --git a/lib/strftime.h b/lib/strftime.h
index 97a062c..d0ac48e 100644
--- a/lib/strftime.h
+++ b/lib/strftime.h
@@ -25,7 +25,7 @@ extern "C" {
    POSIX requires that strftime use the local timezone information.
    Use the timezone __TZ instead.  Use __NS as the number of
    nanoseconds in the %N directive.  */
-size_t nstrftime (char *, size_t, char const *, struct tm const *,
+size_t nstrftime (char * restrict, size_t, char const *, struct tm const *,
                   timezone_t __tz, int __ns);
 
 #ifdef __cplusplus
diff --git a/lib/string.in.h b/lib/string.in.h
index 2be474d..de97453 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -411,11 +411,14 @@ _GL_WARN_ON_USE (strdup, "strdup is unportable - "
 #   undef strncat
 #   define strncat rpl_strncat
 #  endif
-_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n)
-                                   _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n));
+_GL_FUNCDECL_RPL (strncat, char *,
+                  (char * restrict dest, const char *src, size_t n)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strncat, char *,
+                  (char * restrict dest, const char *src, size_t n));
 # else
-_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n));
+_GL_CXXALIAS_SYS (strncat, char *,
+                  (char * restrict dest, const char *src, size_t n));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (strncat);
@@ -966,7 +969,8 @@ _GL_EXTERN_C char * mbssep (char **stringp, const char *delim)
    Caveat: The identity of the delimiting character is lost.
 
    See also mbssep().  */
-_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr)
+_GL_EXTERN_C char * mbstok_r (char * restrict string, const char *delim,
+                              char **save_ptr)
      _GL_ARG_NONNULL ((2, 3));
 #endif
 
diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h
index 8e013e6..2c44801 100644
--- a/lib/sys_socket.in.h
+++ b/lib/sys_socket.in.h
@@ -462,15 +462,18 @@ _GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - "
 #   define getsockopt rpl_getsockopt
 #  endif
 _GL_FUNCDECL_RPL (getsockopt, int, (int fd, int level, int optname,
-                                    void *optval, socklen_t *optlen)
+                                    void * restrict optval,
+                                    socklen_t * restrict optlen)
                                    _GL_ARG_NONNULL ((4, 5)));
 _GL_CXXALIAS_RPL (getsockopt, int, (int fd, int level, int optname,
-                                    void *optval, socklen_t *optlen));
+                                    void * restrict optval,
+                                    socklen_t * restrict optlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the fifth parameter is
                                                        void *optlen.  */
 _GL_CXXALIAS_SYS_CAST (getsockopt, int, (int fd, int level, int optname,
-                                         void *optval, socklen_t *optlen));
+                                         void * restrict optval,
+                                         socklen_t * restrict optlen));
 # endif
 _GL_CXXALIASWARN (getsockopt);
 #elif @HAVE_WINSOCK2_H@
@@ -571,17 +574,17 @@ _GL_WARN_ON_USE (send, "send is not always POSIX compliant - "
 #   define recvfrom rpl_recvfrom
 #  endif
 _GL_FUNCDECL_RPL (recvfrom, ssize_t,
-                  (int fd, void *buf, size_t len, int flags,
+                  (int fd, void * restrict buf, size_t len, int flags,
                    struct sockaddr *from, socklen_t *fromlen)
                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (recvfrom, ssize_t,
-                  (int fd, void *buf, size_t len, int flags,
+                  (int fd, void * restrict buf, size_t len, int flags,
                    struct sockaddr *from, socklen_t *fromlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the sixth parameter is
                                                void *fromlen.  */
 _GL_CXXALIAS_SYS_CAST (recvfrom, ssize_t,
-                       (int fd, void *buf, size_t len, int flags,
+                       (int fd, void * restrict buf, size_t len, int flags,
                         struct sockaddr *from, socklen_t *fromlen));
 # endif
 _GL_CXXALIASWARN (recvfrom);
diff --git a/lib/system-quote.h b/lib/system-quote.h
index d31d47f..2f50779 100644
--- a/lib/system-quote.h
+++ b/lib/system-quote.h
@@ -77,7 +77,7 @@ extern size_t
 /* Copies the quoted string to p and returns the incremented p.
    There must be room for system_quote_length (string) + 1 bytes at p.  */
 extern char *
-       system_quote_copy (char *p,
+       system_quote_copy (char * restrict p,
                           enum system_command_interpreter interpreter,
                           const char *string);
 
diff --git a/lib/time.in.h b/lib/time.in.h
index 7304668..0edf0b3 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -286,13 +286,13 @@ _GL_CXXALIASWARN (ctime);
 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #    define strftime rpl_strftime
 #   endif
-_GL_FUNCDECL_RPL (strftime, size_t, (char *__buf, size_t __bufsize,
+_GL_FUNCDECL_RPL (strftime, size_t, (char * restrict __buf, size_t __bufsize,
                                      const char *__fmt, const struct tm *__tp)
                                     _GL_ARG_NONNULL ((1, 3, 4)));
-_GL_CXXALIAS_RPL (strftime, size_t, (char *__buf, size_t __bufsize,
+_GL_CXXALIAS_RPL (strftime, size_t, (char * restrict __buf, size_t __bufsize,
                                      const char *__fmt, const struct tm *__tp));
 #  else
-_GL_CXXALIAS_SYS (strftime, size_t, (char *__buf, size_t __bufsize,
+_GL_CXXALIAS_SYS (strftime, size_t, (char * restrict __buf, size_t __bufsize,
                                      const char *__fmt, const struct tm *__tp));
 #  endif
 #  if __GLIBC__ >= 2
diff --git a/lib/unicase.in.h b/lib/unicase.in.h
index 45c5f91..b622ac4 100644
--- a/lib/unicase.in.h
+++ b/lib/unicase.in.h
@@ -96,15 +96,15 @@ extern const char *
 extern uint8_t *
        u8_toupper (const uint8_t *s, size_t n, const char *iso639_language,
                    uninorm_t nf,
-                   uint8_t *resultbuf, size_t *lengthp);
+                   uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_toupper (const uint16_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint16_t *resultbuf, size_t *lengthp);
+                    uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_toupper (const uint32_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint32_t *resultbuf, size_t *lengthp);
+                    uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* Return the lowercase mapping of a string.
    The nf argument identifies the normalization form to apply after the
@@ -112,15 +112,15 @@ extern uint32_t *
 extern uint8_t *
        u8_tolower (const uint8_t *s, size_t n, const char *iso639_language,
                    uninorm_t nf,
-                   uint8_t *resultbuf, size_t *lengthp);
+                   uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_tolower (const uint16_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint16_t *resultbuf, size_t *lengthp);
+                    uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_tolower (const uint32_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint32_t *resultbuf, size_t *lengthp);
+                    uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* Return the titlecase mapping of a string.
    The nf argument identifies the normalization form to apply after the
@@ -128,15 +128,15 @@ extern uint32_t *
 extern uint8_t *
        u8_totitle (const uint8_t *s, size_t n, const char *iso639_language,
                    uninorm_t nf,
-                   uint8_t *resultbuf, size_t *lengthp);
+                   uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_totitle (const uint16_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint16_t *resultbuf, size_t *lengthp);
+                    uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_totitle (const uint32_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint32_t *resultbuf, size_t *lengthp);
+                    uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* The case-mapping context given by a prefix string.  */
 typedef struct casing_prefix_context
@@ -204,21 +204,21 @@ extern uint8_t *
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint8_t *resultbuf, size_t *lengthp);
+                      uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_toupper (const uint16_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_toupper (const uint32_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* Return the lowercase mapping of a string that is surrounded by a prefix
    and a suffix.  */
@@ -228,21 +228,21 @@ extern uint8_t *
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint8_t *resultbuf, size_t *lengthp);
+                      uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_tolower (const uint16_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_tolower (const uint32_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* Return the titlecase mapping of a string that is surrounded by a prefix
    and a suffix.  */
@@ -252,21 +252,21 @@ extern uint8_t *
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint8_t *resultbuf, size_t *lengthp);
+                      uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_totitle (const uint16_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_totitle (const uint32_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* Return the case folded string.
    Comparing uN_casefold (S1) and uN_casefold (S2) with uN_cmp2() is equivalent
@@ -276,15 +276,15 @@ extern uint32_t *
 extern uint8_t *
        u8_casefold (const uint8_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint8_t *resultbuf, size_t *lengthp);
+                    uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_casefold (const uint16_t *s, size_t n, const char *iso639_language,
                      uninorm_t nf,
-                     uint16_t *resultbuf, size_t *lengthp);
+                     uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_casefold (const uint32_t *s, size_t n, const char *iso639_language,
                      uninorm_t nf,
-                     uint32_t *resultbuf, size_t *lengthp);
+                     uint32_t * restrict resultbuf, size_t *lengthp);
 /* Likewise, for a string that is surrounded by a prefix and a suffix.  */
 extern uint8_t *
        u8_ct_casefold (const uint8_t *s, size_t n,
@@ -292,21 +292,21 @@ extern uint8_t *
                        casing_suffix_context_t suffix_context,
                        const char *iso639_language,
                        uninorm_t nf,
-                       uint8_t *resultbuf, size_t *lengthp);
+                       uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_casefold (const uint16_t *s, size_t n,
                         casing_prefix_context_t prefix_context,
                         casing_suffix_context_t suffix_context,
                         const char *iso639_language,
                         uninorm_t nf,
-                        uint16_t *resultbuf, size_t *lengthp);
+                        uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_casefold (const uint32_t *s, size_t n,
                         casing_prefix_context_t prefix_context,
                         casing_suffix_context_t suffix_context,
                         const char *iso639_language,
                         uninorm_t nf,
-                        uint32_t *resultbuf, size_t *lengthp);
+                        uint32_t * restrict resultbuf, size_t *lengthp);
 
 /* Compare S1 and S2, ignoring differences in case and normalization.
    The nf argument identifies the normalization form to apply after the
@@ -336,16 +336,16 @@ extern int
    NF must be either UNINORM_NFC, UNINORM_NFKC, or NULL for no normalization.  */
 extern char *
        u8_casexfrm (const uint8_t *s, size_t n, const char *iso639_language,
-                    uninorm_t nf, char *resultbuf, size_t *lengthp);
+                    uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
 extern char *
        u16_casexfrm (const uint16_t *s, size_t n, const char *iso639_language,
-                     uninorm_t nf, char *resultbuf, size_t *lengthp);
+                     uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
 extern char *
        u32_casexfrm (const uint32_t *s, size_t n, const char *iso639_language,
-                     uninorm_t nf, char *resultbuf, size_t *lengthp);
+                     uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
 extern char *
        ulc_casexfrm (const char *s, size_t n, const char *iso639_language,
-                     uninorm_t nf, char *resultbuf, size_t *lengthp);
+                     uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
 
 /* Compare S1 and S2, ignoring differences in case and normalization, using the
    collation rules of the current locale.
diff --git a/lib/uniconv.in.h b/lib/uniconv.in.h
index 53dc3fc..4e7f872 100644
--- a/lib/uniconv.in.h
+++ b/lib/uniconv.in.h
@@ -98,19 +98,19 @@ extern char *
                             enum iconv_ilseq_handler handler,
                             const uint8_t *src, size_t srclen,
                             size_t *offsets,
-                            char *resultbuf, size_t *lengthp);
+                            char * restrict resultbuf, size_t *lengthp);
 extern char *
        u16_conv_to_encoding (const char *tocode,
                              enum iconv_ilseq_handler handler,
                              const uint16_t *src, size_t srclen,
                              size_t *offsets,
-                             char *resultbuf, size_t *lengthp);
+                             char * restrict resultbuf, size_t *lengthp);
 extern char *
        u32_conv_to_encoding (const char *tocode,
                              enum iconv_ilseq_handler handler,
                              const uint32_t *src, size_t srclen,
                              size_t *offsets,
-                             char *resultbuf, size_t *lengthp);
+                             char * restrict resultbuf, size_t *lengthp);
 
 /* Converts a NUL terminated string from a given encoding.
    The result is malloc allocated, or NULL (with errno set) in case of error.
diff --git a/lib/unilbrk.in.h b/lib/unilbrk.in.h
index 408b905..83ba59c 100644
--- a/lib/unilbrk.in.h
+++ b/lib/unilbrk.in.h
@@ -58,16 +58,16 @@ enum
  */
 extern void
        u8_possible_linebreaks (const uint8_t *s, size_t n,
-                               const char *encoding, char *p);
+                               const char *encoding, char * restrict p);
 extern void
        u16_possible_linebreaks (const uint16_t *s, size_t n,
-                                const char *encoding, char *p);
+                                const char *encoding, char * restrict p);
 extern void
        u32_possible_linebreaks (const uint32_t *s, size_t n,
-                                const char *encoding, char *p);
+                                const char *encoding, char * restrict p);
 extern void
        ulc_possible_linebreaks (const char *s, size_t n,
-                                const char *encoding, char *p);
+                                const char *encoding, char * restrict p);
 
 /* Choose the best line breaks, assuming the uc_width function.
    The string is s[0..n-1].  The maximum number of columns per line is given
@@ -84,22 +84,22 @@ extern int
        u8_width_linebreaks (const uint8_t *s, size_t n, int width,
                             int start_column, int at_end_columns,
                             const char *o, const char *encoding,
-                            char *p);
+                            char * restrict p);
 extern int
        u16_width_linebreaks (const uint16_t *s, size_t n, int width,
                              int start_column, int at_end_columns,
                              const char *o, const char *encoding,
-                             char *p);
+                             char * restrict p);
 extern int
        u32_width_linebreaks (const uint32_t *s, size_t n, int width,
                              int start_column, int at_end_columns,
                              const char *o, const char *encoding,
-                             char *p);
+                             char * restrict p);
 extern int
        ulc_width_linebreaks (const char *s, size_t n, int width,
                              int start_column, int at_end_columns,
                              const char *o, const char *encoding,
-                             char *p);
+                             char * restrict p);
 
 
 #ifdef __cplusplus
diff --git a/lib/uninorm.in.h b/lib/uninorm.in.h
index 9ebdb6b..e4cb7d9 100644
--- a/lib/uninorm.in.h
+++ b/lib/uninorm.in.h
@@ -143,13 +143,13 @@ extern uninorm_t
 /* Return the specified normalization form of a string.  */
 extern uint8_t *
        u8_normalize (uninorm_t nf, const uint8_t *s, size_t n,
-                     uint8_t *resultbuf, size_t *lengthp);
+                     uint8_t * restrict resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_normalize (uninorm_t nf, const uint16_t *s, size_t n,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t * restrict resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_normalize (uninorm_t nf, const uint32_t *s, size_t n,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t * restrict resultbuf, size_t *lengthp);
 
 
 /* Compare S1 and S2, ignoring differences in normalization.
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 6db7ff2..297f6dd 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1370,18 +1370,18 @@ _GL_CXXALIASWARN (read);
 #   define readlink rpl_readlink
 #  endif
 _GL_FUNCDECL_RPL (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize)
+                  (const char *file, char * restrict buf, size_t bufsize)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize));
+                  (const char *file, char * restrict buf, size_t bufsize));
 # else
 #  if !@HAVE_READLINK@
 _GL_FUNCDECL_SYS (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize)
+                  (const char *file, char * restrict buf, size_t bufsize)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 _GL_CXXALIAS_SYS (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize));
+                  (const char *file, char * restrict buf, size_t bufsize));
 # endif
 _GL_CXXALIASWARN (readlink);
 #elif defined GNULIB_POSIXCHECK
@@ -1399,18 +1399,18 @@ _GL_WARN_ON_USE (readlink, "readlink is unportable - "
 #   define readlinkat rpl_readlinkat
 #  endif
 _GL_FUNCDECL_RPL (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len)
+                  (int fd, char const *file, char * restrict buf, size_t len)
                   _GL_ARG_NONNULL ((2, 3)));
 _GL_CXXALIAS_RPL (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len));
+                  (int fd, char const *file, char * restrict buf, size_t len));
 # else
 #  if !@HAVE_READLINKAT@
 _GL_FUNCDECL_SYS (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len)
+                  (int fd, char const *file, char * restrict buf, size_t len)
                   _GL_ARG_NONNULL ((2, 3)));
 #  endif
 _GL_CXXALIAS_SYS (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len));
+                  (int fd, char const *file, char * restrict buf, size_t len));
 # endif
 _GL_CXXALIASWARN (readlinkat);
 #elif defined GNULIB_POSIXCHECK
diff --git a/lib/unistdio.in.h b/lib/unistdio.in.h
index e6091ec..615d21b 100644
--- a/lib/unistdio.in.h
+++ b/lib/unistdio.in.h
@@ -61,28 +61,28 @@ extern "C" {
 
 /* ASCII format string, result in locale dependent encoded 'char *'.  */
 extern int
-       ulc_sprintf (char *buf,
+       ulc_sprintf (char * restrict buf,
                     const char *format, ...);
 extern int
-       ulc_snprintf (char *buf, size_t size,
+       ulc_snprintf (char * restrict buf, size_t size,
                      const char *format, ...);
 extern int
        ulc_asprintf (char **resultp,
                      const char *format, ...);
 extern char *
-       ulc_asnprintf (char *resultbuf, size_t *lengthp,
+       ulc_asnprintf (char * restrict resultbuf, size_t *lengthp,
                       const char *format, ...);
 extern int
-       ulc_vsprintf (char *buf,
+       ulc_vsprintf (char * restrict buf,
                      const char *format, va_list ap);
 extern int
-       ulc_vsnprintf (char *buf, size_t size,
+       ulc_vsnprintf (char * restrict buf, size_t size,
                       const char *format, va_list ap);
 extern int
        ulc_vasprintf (char **resultp,
                       const char *format, va_list ap);
 extern char *
-       ulc_vasnprintf (char *resultbuf, size_t *lengthp,
+       ulc_vasnprintf (char * restrict resultbuf, size_t *lengthp,
                        const char *format, va_list ap);
 
 /* ASCII format string, result in UTF-8 format.  */
@@ -113,28 +113,28 @@ extern uint8_t *
 
 /* UTF-8 format string, result in UTF-8 format.  */
 extern int
-       u8_u8_sprintf (uint8_t *buf,
+       u8_u8_sprintf (uint8_t * restrict buf,
                       const uint8_t *format, ...);
 extern int
-       u8_u8_snprintf (uint8_t *buf, size_t size,
+       u8_u8_snprintf (uint8_t * restrict buf, size_t size,
                        const uint8_t *format, ...);
 extern int
        u8_u8_asprintf (uint8_t **resultp,
                        const uint8_t *format, ...);
 extern uint8_t *
-       u8_u8_asnprintf (uint8_t *resultbuf, size_t *lengthp,
+       u8_u8_asnprintf (uint8_t * restrict resultbuf, size_t *lengthp,
                         const uint8_t *format, ...);
 extern int
-       u8_u8_vsprintf (uint8_t *buf,
+       u8_u8_vsprintf (uint8_t * restrict buf,
                        const uint8_t *format, va_list ap);
 extern int
-       u8_u8_vsnprintf (uint8_t *buf, size_t size,
+       u8_u8_vsnprintf (uint8_t * restrict buf, size_t size,
                         const uint8_t *format, va_list ap);
 extern int
        u8_u8_vasprintf (uint8_t **resultp,
                         const uint8_t *format, va_list ap);
 extern uint8_t *
-       u8_u8_vasnprintf (uint8_t *resultbuf, size_t *lengthp,
+       u8_u8_vasnprintf (uint8_t * restrict resultbuf, size_t *lengthp,
                          const uint8_t *format, va_list ap);
 
 /* ASCII format string, result in UTF-16 format.  */
@@ -165,28 +165,28 @@ extern uint16_t *
 
 /* UTF-16 format string, result in UTF-16 format.  */
 extern int
-       u16_u16_sprintf (uint16_t *buf,
+       u16_u16_sprintf (uint16_t * restrict buf,
                         const uint16_t *format, ...);
 extern int
-       u16_u16_snprintf (uint16_t *buf, size_t size,
+       u16_u16_snprintf (uint16_t * restrict buf, size_t size,
                          const uint16_t *format, ...);
 extern int
        u16_u16_asprintf (uint16_t **resultp,
                          const uint16_t *format, ...);
 extern uint16_t *
-       u16_u16_asnprintf (uint16_t *resultbuf, size_t *lengthp,
+       u16_u16_asnprintf (uint16_t * restrict resultbuf, size_t *lengthp,
                           const uint16_t *format, ...);
 extern int
-       u16_u16_vsprintf (uint16_t *buf,
+       u16_u16_vsprintf (uint16_t * restrict buf,
                          const uint16_t *format, va_list ap);
 extern int
-       u16_u16_vsnprintf (uint16_t *buf, size_t size,
+       u16_u16_vsnprintf (uint16_t * restrict buf, size_t size,
                           const uint16_t *format, va_list ap);
 extern int
        u16_u16_vasprintf (uint16_t **resultp,
                           const uint16_t *format, va_list ap);
 extern uint16_t *
-       u16_u16_vasnprintf (uint16_t *resultbuf, size_t *lengthp,
+       u16_u16_vasnprintf (uint16_t * restrict resultbuf, size_t *lengthp,
                            const uint16_t *format, va_list ap);
 
 /* ASCII format string, result in UTF-32 format.  */
@@ -217,28 +217,28 @@ extern uint32_t *
 
 /* UTF-32 format string, result in UTF-32 format.  */
 extern int
-       u32_u32_sprintf (uint32_t *buf,
+       u32_u32_sprintf (uint32_t * restrict buf,
                         const uint32_t *format, ...);
 extern int
-       u32_u32_snprintf (uint32_t *buf, size_t size,
+       u32_u32_snprintf (uint32_t * restrict buf, size_t size,
                          const uint32_t *format, ...);
 extern int
        u32_u32_asprintf (uint32_t **resultp,
                          const uint32_t *format, ...);
 extern uint32_t *
-       u32_u32_asnprintf (uint32_t *resultbuf, size_t *lengthp,
+       u32_u32_asnprintf (uint32_t * restrict resultbuf, size_t *lengthp,
                           const uint32_t *format, ...);
 extern int
-       u32_u32_vsprintf (uint32_t *buf,
+       u32_u32_vsprintf (uint32_t * restrict buf,
                          const uint32_t *format, va_list ap);
 extern int
-       u32_u32_vsnprintf (uint32_t *buf, size_t size,
+       u32_u32_vsnprintf (uint32_t * restrict buf, size_t size,
                           const uint32_t *format, va_list ap);
 extern int
        u32_u32_vasprintf (uint32_t **resultp,
                           const uint32_t *format, va_list ap);
 extern uint32_t *
-       u32_u32_vasnprintf (uint32_t *resultbuf, size_t *lengthp,
+       u32_u32_vasnprintf (uint32_t * restrict resultbuf, size_t *lengthp,
                            const uint32_t *format, va_list ap);
 
 /* ASCII format string, output to FILE in locale dependent encoding.  */
diff --git a/lib/unistr.in.h b/lib/unistr.in.h
index bc0d237..c580774 100644
--- a/lib/unistr.in.h
+++ b/lib/unistr.in.h
@@ -373,11 +373,11 @@ u32_uctomb (uint32_t *s, ucs4_t uc, int n)
 /* Copy N units from SRC to DEST.  */
 /* Similar to memcpy().  */
 extern uint8_t *
-       u8_cpy (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_cpy (uint8_t * restrict dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_cpy (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_cpy (uint16_t * restrict dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_cpy (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_cpy (uint32_t * restrict dest, const uint32_t *src, size_t n);
 
 /* Copy N units from SRC to DEST, guaranteeing correct behavior for
    overlapping memory areas.  */
@@ -528,57 +528,57 @@ extern size_t
 /* Copy SRC to DEST.  */
 /* Similar to strcpy(), wcscpy().  */
 extern uint8_t *
-       u8_strcpy (uint8_t *dest, const uint8_t *src);
+       u8_strcpy (uint8_t * restrict dest, const uint8_t *src);
 extern uint16_t *
-       u16_strcpy (uint16_t *dest, const uint16_t *src);
+       u16_strcpy (uint16_t * restrict dest, const uint16_t *src);
 extern uint32_t *
-       u32_strcpy (uint32_t *dest, const uint32_t *src);
+       u32_strcpy (uint32_t * restrict dest, const uint32_t *src);
 
 /* Copy SRC to DEST, returning the address of the terminating NUL in DEST.  */
 /* Similar to stpcpy().  */
 extern uint8_t *
-       u8_stpcpy (uint8_t *dest, const uint8_t *src);
+       u8_stpcpy (uint8_t * restrict dest, const uint8_t *src);
 extern uint16_t *
-       u16_stpcpy (uint16_t *dest, const uint16_t *src);
+       u16_stpcpy (uint16_t * restrict dest, const uint16_t *src);
 extern uint32_t *
-       u32_stpcpy (uint32_t *dest, const uint32_t *src);
+       u32_stpcpy (uint32_t * restrict dest, const uint32_t *src);
 
 /* Copy no more than N units of SRC to DEST.  */
 /* Similar to strncpy(), wcsncpy().  */
 extern uint8_t *
-       u8_strncpy (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_strncpy (uint8_t * restrict dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_strncpy (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_strncpy (uint16_t * restrict dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_strncpy (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_strncpy (uint32_t * restrict dest, const uint32_t *src, size_t n);
 
 /* Copy no more than N units of SRC to DEST.  Return a pointer past the last
    non-NUL unit written into DEST.  */
 /* Similar to stpncpy().  */
 extern uint8_t *
-       u8_stpncpy (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_stpncpy (uint8_t * restrict dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_stpncpy (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_stpncpy (uint16_t * restrict dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_stpncpy (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_stpncpy (uint32_t * restrict dest, const uint32_t *src, size_t n);
 
 /* Append SRC onto DEST.  */
 /* Similar to strcat(), wcscat().  */
 extern uint8_t *
-       u8_strcat (uint8_t *dest, const uint8_t *src);
+       u8_strcat (uint8_t * restrict dest, const uint8_t *src);
 extern uint16_t *
-       u16_strcat (uint16_t *dest, const uint16_t *src);
+       u16_strcat (uint16_t * restrict dest, const uint16_t *src);
 extern uint32_t *
-       u32_strcat (uint32_t *dest, const uint32_t *src);
+       u32_strcat (uint32_t * restrict dest, const uint32_t *src);
 
 /* Append no more than N units of SRC onto DEST.  */
 /* Similar to strncat(), wcsncat().  */
 extern uint8_t *
-       u8_strncat (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_strncat (uint8_t * restrict dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_strncat (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_strncat (uint16_t * restrict dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_strncat (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_strncat (uint32_t * restrict dest, const uint32_t *src, size_t n);
 
 /* Compare S1 and S2.  */
 /* Similar to strcmp(), wcscmp().  */
@@ -732,11 +732,14 @@ extern bool
    This interface is actually more similar to wcstok than to strtok.  */
 /* Similar to strtok_r(), wcstok().  */
 extern uint8_t *
-       u8_strtok (uint8_t *str, const uint8_t *delim, uint8_t **ptr);
+       u8_strtok (uint8_t * restrict str, const uint8_t *delim,
+                  uint8_t **ptr);
 extern uint16_t *
-       u16_strtok (uint16_t *str, const uint16_t *delim, uint16_t **ptr);
+       u16_strtok (uint16_t * restrict str, const uint16_t *delim,
+                   uint16_t **ptr);
 extern uint32_t *
-       u32_strtok (uint32_t *str, const uint32_t *delim, uint32_t **ptr);
+       u32_strtok (uint32_t * restrict str, const uint32_t *delim,
+                   uint32_t **ptr);
 
 
 #ifdef __cplusplus
diff --git a/lib/uniwbrk.in.h b/lib/uniwbrk.in.h
index 1407644..940ae7d 100644
--- a/lib/uniwbrk.in.h
+++ b/lib/uniwbrk.in.h
@@ -81,7 +81,7 @@ extern void
 extern void
        u32_wordbreaks (const uint32_t *s, size_t n, char *p);
 extern void
-       ulc_wordbreaks (const char *s, size_t n, char *p);
+       ulc_wordbreaks (const char *s, size_t n, char * restrict p);
 
 /* ========================================================================= */
 
diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h
index 345e6a8..58b9912 100644
--- a/lib/vasnprintf.h
+++ b/lib/vasnprintf.h
@@ -67,9 +67,11 @@ extern "C" {
 # define asnprintf rpl_asnprintf
 # define vasnprintf rpl_vasnprintf
 #endif
-extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
+extern char * asnprintf (char * restrict resultbuf, size_t *lengthp,
+                         const char *format, ...)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
-extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
+extern char * vasnprintf (char * restrict resultbuf, size_t *lengthp,
+                          const char *format, va_list args)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
 
 #ifdef __cplusplus
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 74cd670..16f9d6c 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -547,10 +547,10 @@ _GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - "
 #if @GNULIB_WMEMCPY@
 # if !@HAVE_WMEMCPY@
 _GL_FUNCDECL_SYS (wmemcpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wmemcpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wmemcpy);
 # endif
@@ -640,9 +640,11 @@ _GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - "
 /* Copy SRC to DEST.  */
 #if @GNULIB_WCSCPY@
 # if !@HAVE_WCSCPY@
-_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_FUNCDECL_SYS (wcscpy, wchar_t *,
+                  (wchar_t * restrict dest, const wchar_t *src));
 # endif
-_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_CXXALIAS_SYS (wcscpy, wchar_t *,
+                  (wchar_t * restrict dest, const wchar_t *src));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcscpy);
 # endif
@@ -658,9 +660,11 @@ _GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - "
 /* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST.  */
 #if @GNULIB_WCPCPY@
 # if !@HAVE_WCPCPY@
-_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_FUNCDECL_SYS (wcpcpy, wchar_t *,
+                  (wchar_t * restrict dest, const wchar_t *src));
 # endif
-_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_CXXALIAS_SYS (wcpcpy, wchar_t *,
+                  (wchar_t * restrict dest, const wchar_t *src));
 _GL_CXXALIASWARN (wcpcpy);
 #elif defined GNULIB_POSIXCHECK
 # undef wcpcpy
@@ -675,10 +679,10 @@ _GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - "
 #if @GNULIB_WCSNCPY@
 # if !@HAVE_WCSNCPY@
 _GL_FUNCDECL_SYS (wcsncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wcsncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsncpy);
 # endif
@@ -696,10 +700,10 @@ _GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - "
 #if @GNULIB_WCPNCPY@
 # if !@HAVE_WCPNCPY@
 _GL_FUNCDECL_SYS (wcpncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wcpncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 _GL_CXXALIASWARN (wcpncpy);
 #elif defined GNULIB_POSIXCHECK
 # undef wcpncpy
@@ -713,9 +717,11 @@ _GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - "
 /* Append SRC onto DEST.  */
 #if @GNULIB_WCSCAT@
 # if !@HAVE_WCSCAT@
-_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_FUNCDECL_SYS (wcscat, wchar_t *,
+                  (wchar_t * restrict dest, const wchar_t *src));
 # endif
-_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_CXXALIAS_SYS (wcscat, wchar_t *,
+                  (wchar_t * restrict dest, const wchar_t *src));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcscat);
 # endif
@@ -732,10 +738,10 @@ _GL_WARN_ON_USE (wcscat, "wcscat is unportable - "
 #if @GNULIB_WCSNCAT@
 # if !@HAVE_WCSNCAT@
 _GL_FUNCDECL_SYS (wcsncat, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wcsncat, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsncat);
 # endif
@@ -848,9 +854,11 @@ _GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - "
    original strings.  */
 #if @GNULIB_WCSXFRM@
 # if !@HAVE_WCSXFRM@
-_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n));
+_GL_FUNCDECL_SYS (wcsxfrm, size_t,
+                  (wchar_t * restrict s1, const wchar_t *s2, size_t n));
 # endif
-_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n));
+_GL_CXXALIAS_SYS (wcsxfrm, size_t,
+                  (wchar_t * restrict s1, const wchar_t *s2, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsxfrm);
 # endif
@@ -1053,16 +1061,20 @@ _GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - "
 #   define wcstok rpl_wcstok
 #  endif
 _GL_FUNCDECL_RPL (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t * restrict wcs, const wchar_t *delim,
+                   wchar_t **ptr));
 _GL_CXXALIAS_RPL (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t * restrict wcs, const wchar_t *delim,
+                   wchar_t **ptr));
 # else
 #  if !@HAVE_WCSTOK@
 _GL_FUNCDECL_SYS (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t * restrict wcs, const wchar_t *delim,
+                   wchar_t **ptr));
 #  endif
 _GL_CXXALIAS_SYS (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t * restrict wcs, const wchar_t *delim,
+                   wchar_t **ptr));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcstok);
@@ -1114,18 +1126,18 @@ _GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - "
 #   undef wcsftime
 #   define wcsftime rpl_wcsftime
 #  endif
-_GL_FUNCDECL_RPL (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
+_GL_FUNCDECL_RPL (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
                                      const wchar_t *__fmt, const struct tm *__tp)
                                     _GL_ARG_NONNULL ((1, 3, 4)));
-_GL_CXXALIAS_RPL (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
+_GL_CXXALIAS_RPL (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
                                      const wchar_t *__fmt, const struct tm *__tp));
 # else
 #  if !@HAVE_WCSFTIME@
-_GL_FUNCDECL_SYS (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
+_GL_FUNCDECL_SYS (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
                                      const wchar_t *__fmt, const struct tm *__tp)
                                     _GL_ARG_NONNULL ((1, 3, 4)));
 #  endif
-_GL_CXXALIAS_SYS (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
+_GL_CXXALIAS_SYS (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
                                      const wchar_t *__fmt, const struct tm *__tp));
 # endif
 # if __GLIBC__ >= 2
diff --git a/lib/xmemcoll.h b/lib/xmemcoll.h
index 4170b9b..ea546b8 100644
--- a/lib/xmemcoll.h
+++ b/lib/xmemcoll.h
@@ -1,3 +1,3 @@
 #include <stddef.h>
-int xmemcoll (char *, size_t, char *, size_t);
+int xmemcoll (char * restrict, size_t, char * restrict, size_t);
 int xmemcoll0 (char const *, size_t, char const *, size_t);




^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-10  3:02   ` restrict Bruno Haible
@ 2020-02-10  8:39     ` Jeffrey Walton
  2020-02-10 10:11     ` restrict Tim Rühsen
                       ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Jeffrey Walton @ 2020-02-10  8:39 UTC (permalink / raw)
  To: Bruno Haible; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

On Sun, Feb 9, 2020 at 10:03 PM Bruno Haible <bruno@clisp.org> wrote:
> ...
> Which function declarations could therefore profit from the 'restrict'
> keyword?

[SNIP ...]

I think the case of interest is subobjects of arrays:

    char a[] = "Hello World";
    char* b = a+5;

memcpy(a,b,5) would get you in trouble due to restrict. memmov(a,b,5)
would be OK.

Punning might be another interesting case, like the way the internet
functions seem to cast everything to byte arrays.

Jeff


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-10  3:02   ` restrict Bruno Haible
  2020-02-10  8:39     ` restrict Jeffrey Walton
@ 2020-02-10 10:11     ` Tim Rühsen
  2020-02-16 21:44     ` restrict Paul Eggert
  2020-02-17 21:19     ` restrict - summary Bruno Haible
  3 siblings, 0 replies; 20+ messages in thread
From: Tim Rühsen @ 2020-02-10 10:11 UTC (permalink / raw)
  To: Bruno Haible, bug-gnulib; +Cc: Mats Erik Andersson


[-- Attachment #1.1: Type: text/plain, Size: 77743 bytes --]

On 2/10/20 4:02 AM, Bruno Haible wrote:
> Tim Rühsen wrote:
>> gcc -Wall tells you so (gcc 8 and upwards):
>> $ gcc -Wall msg.c -o msg
>> msg.c: In function ‘main’:
>> msg.c:11:13: warning: passing argument 1 to restrict-qualified parameter
>> aliases with argument 4 [-Wrestrict]
>>    11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
>>       |             ^~~                        ~~~
>> msg.c:11:35: warning: ‘%s’ directive output may be truncated writing 4
>> bytes into a region of size between 1 and 11 [-Wformat-truncation=]
>>    11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
>>       |                                   ^~
>> msg.c:11:3: note: ‘snprintf’ output between 5 and 15 bytes into a
>> destination of size 11
>>    11 |   snprintf (msg, sizeof (msg), "%s%s", msg, WRONG_MESSAGE);
>>       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>
> 
> Oh, the 'restrict' keyword is actually useful (other than for micro-
> optimizations)! Thanks for this pointer, Tim.
> 
> So, it would make sense to use this keyword in function declarations in
> public .h files in gnulib.
> 
> For internal .h files in gnulib, there's no point - this code is assumed
> correct, no need to try to get GCC to produce warnings here.
> 
> What does 'restrict' precisely mean? ISO C 99 § 6.7.3.(7):
>   "An object that is accessed through a restrict-qualified pointer has a
>    special association with that pointer. This association, defined in
>    6.7.3.1 below, requires that all accesses to that object use, directly
>    or indirectly, the value of that particular pointer.115) The intended
>    use of the restrict qualifier (like the register storage class) is to
>    promote optimization, and deleting all instances of the qualifier from
>    all preprocessing translation units composing a conforming program
>    does not change its meaning (i.e., observable behavior)."
> 
> Which function declarations could therefore profit from the 'restrict'
> keyword?
> 
>   - Only parameters of pointer types, excluding function pointer types,
>     matter.
> 
>   - If all pointer parameters are 'const SOMETHING *', the function
>     is not writing into them, therefore 'restrict' is redundant.
>     Example: int strcmp (const char *, const char *);
> 
>   - If all pointer parameters point to different types, excluding 'void *',
>     ISO C forbids aliasing anyway, therefore 'restrict' is redundant.
>     Example: void dfacomp (char const *, ptrdiff_t, struct dfa *, bool);
>     and https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html
> 
>   - If, among the parameters, there are N parameters of type
>       [const] TYPE *
>     adding the 'restrict' keyword to N-1 of them is equivalent to adding
>     the 'restrict' keyword to all N of them.
>     See ISO C 99 § 6.7.3.1.(7) [Example 1].
> 
>     GCC's warning facility understands this, regarding the non-const pointer.
>     Test case:
>     ========================================================================
>     #include <stddef.h>
>     extern int smprintf (char *restrict, size_t, const char *, ...)
>          __attribute__ ((__format__ (__printf__, 3, 4)));
>     int main ()
>     {
>       char msg[sizeof ("try a fool")] = "try a ";
>       smprintf (msg, sizeof (msg), "%s%s", msg, "fool");
>     }
>     ========================================================================
> 
>   - If a function has an input parameter of type
>       const TYPE *
>     and an output parameter of type
>       TYPE *
>     then the 'restrict' keyword means that the implementation may write
>     the output before having finished reading all the input.
>     Example:
>       void arctwo_encrypt (arctwo_context *context, const char *inbuf,
>                            char * restrict outbuf, size_t length);

Doesn't this need 'restrict' for the 'inbuf' parameter as well ?
If not, why is glibc applying restrict to both parameters of strcpy ?

>     Whereas the absence of the 'restrict' keyword means that the
>     implementation will read all the input _before_ starting to store
>     the output.

Can we say
"Whereas the absence of the 'restrict' keyword means that the
implementation guarantees documented operation for any aliasing of input
and output"
?

>     Example:
>       int hmac_md5 (const void *key, size_t keylen,
>                     const void *buffer, size_t buflen, void *resbuf);
> 
>   - 'restrict' should NOT be used for multiple output parameters of the
>     same type, when only a single word is written through each parameter.
>     Example: ssize_t copy_file_range (int ifd, off_t *ipos, int ofd, off_t *opos,
>                                       size_t len, unsigned flags);
>     Rationale: It is OK to have ipos and opos point to different elements
>     of the same off_t[] array.
> 
> Is this all right, or did I misinterpret something?

IMO, a very good interpretation and summary !
I can't add anything except the above questions.

> If it is right, then how about this start of a patch? (Not sure whether I need
> to add the 'restrict' keyword also in the function definitions?)

AFAIK, 'restrict' in declarations should be enough, except you just have
a definition (e.g. static functions).

Function pointer typedefs also need the restrict keywords (but the
compiler should warn about it in case you forget *and* not use casts).

Regards, Tim

> 
> Bruno
> 
> 
> diff --git a/lib/amemxfrm.h b/lib/amemxfrm.h
> index 7cfc283..0edd3d5 100644
> --- a/lib/amemxfrm.h
> +++ b/lib/amemxfrm.h
> @@ -38,7 +38,8 @@ extern "C" {
>     freshly allocated string is returned.  In both cases, *lengthp is set to the
>     length of the returned string.
>     Upon failure, return NULL, with errno set.  */
> -extern char * amemxfrm (char *s, size_t n, char *resultbuf, size_t *lengthp);
> +extern char * amemxfrm (char * restrict s, size_t n,
> +                        char * restrict resultbuf, size_t *lengthp);
>  
>  
>  #ifdef __cplusplus
> diff --git a/lib/arcfour.h b/lib/arcfour.h
> index b77df1a..b23e792 100644
> --- a/lib/arcfour.h
> +++ b/lib/arcfour.h
> @@ -37,7 +37,7 @@ typedef struct
>     before this function is called. */
>  extern void
>  arcfour_stream (arcfour_context * context,
> -                const char *inbuf, char *outbuf, size_t length);
> +                const char *inbuf, char * restrict outbuf, size_t length);
>  
>  /* Initialize CONTEXT using encryption KEY of KEYLEN bytes.  KEY
>     should be 40 bits (5 bytes) or longer.  The KEY cannot be zero
> diff --git a/lib/arctwo.h b/lib/arctwo.h
> index 91f725f..e88489a 100644
> --- a/lib/arctwo.h
> +++ b/lib/arctwo.h
> @@ -48,7 +48,7 @@ arctwo_setkey_ekb (arctwo_context *context,
>     arctwo_setkey_ekb. */
>  extern void
>  arctwo_encrypt (arctwo_context *context, const char *inbuf,
> -                char *outbuf, size_t length);
> +                char * restrict outbuf, size_t length);
>  
>  /* Decrypt INBUF of size LENGTH into OUTBUF.  LENGTH must be a
>     multiple of ARCTWO_BLOCK_SIZE.  CONTEXT hold the decryption key,
> @@ -56,6 +56,6 @@ arctwo_encrypt (arctwo_context *context, const char *inbuf,
>     arctwo_setkey_ekb. */
>  extern void
>  arctwo_decrypt (arctwo_context *context, const char *inbuf,
> -                char *outbuf, size_t length);
> +                char * restrict outbuf, size_t length);
>  
>  #endif /* ARCTWO_H */
> diff --git a/lib/astrxfrm.h b/lib/astrxfrm.h
> index a23ed70..9906659 100644
> --- a/lib/astrxfrm.h
> +++ b/lib/astrxfrm.h
> @@ -37,7 +37,8 @@ extern "C" {
>     freshly allocated string is returned.  In both cases, *lengthp is set to the
>     length of the returned string.
>     Upon failure, return NULL, with errno set.  */
> -extern char * astrxfrm (const char *s, char *resultbuf, size_t *lengthp);
> +extern char * astrxfrm (const char *s,
> +                        char * restrict resultbuf, size_t *lengthp);
>  
>  
>  #ifdef __cplusplus
> diff --git a/lib/c-snprintf.h b/lib/c-snprintf.h
> index bfdc081..3b31bd4 100644
> --- a/lib/c-snprintf.h
> +++ b/lib/c-snprintf.h
> @@ -36,7 +36,8 @@
>  extern "C" {
>  #endif
>  
> -int c_snprintf (char *str, size_t size, const char *format, ...)
> +extern int c_snprintf (char * restrict str, size_t size,
> +                       const char *format, ...)
>         _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
>  
>  #ifdef __cplusplus
> diff --git a/lib/c-vasnprintf.h b/lib/c-vasnprintf.h
> index 1a69e56..c44a31b 100644
> --- a/lib/c-vasnprintf.h
> +++ b/lib/c-vasnprintf.h
> @@ -66,7 +66,8 @@ extern "C" {
>     Formatting takes place in the C locale, that is, the decimal point used in
>     floating-point formatting directives is always '.'.
>    */
> -extern char *c_vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
> +extern char *c_vasnprintf (char * restrict resultbuf, size_t *lengthp,
> +                           const char *format, va_list args)
>         _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
>  
>  #ifdef __cplusplus
> diff --git a/lib/c-vsnprintf.h b/lib/c-vsnprintf.h
> index 97a2816..1b20fd5 100644
> --- a/lib/c-vsnprintf.h
> +++ b/lib/c-vsnprintf.h
> @@ -39,7 +39,8 @@
>  extern "C" {
>  #endif
>  
> -int c_vsnprintf (char *str, size_t size, const char *format, va_list args)
> +extern int c_vsnprintf (char * restrict str, size_t size,
> +                        const char *format, va_list args)
>         _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
>  
>  #ifdef __cplusplus
> diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h
> index 584cfe9..f249ab6 100644
> --- a/lib/careadlinkat.h
> +++ b/lib/careadlinkat.h
> @@ -47,7 +47,7 @@ struct allocator;
>     set errno.  */
>  
>  char *careadlinkat (int fd, char const *filename,
> -                    char *buffer, size_t buffer_size,
> +                    char * restrict buffer, size_t buffer_size,
>                      struct allocator const *alloc,
>                      ssize_t (*preadlinkat) (int, char const *,
>                                              char *, size_t));
> diff --git a/lib/gc.h b/lib/gc.h
> index 05fb8a3..bd90bd0 100644
> --- a/lib/gc.h
> +++ b/lib/gc.h
> @@ -185,12 +185,12 @@ extern Gc_rc
>  gc_pbkdf2_hmac (Gc_hash hash,
>                  const char *P, size_t Plen,
>                  const char *S, size_t Slen,
> -                unsigned int c, char *DK, size_t dkLen);
> +                unsigned int c, char * restrict DK, size_t dkLen);
>  
>  extern Gc_rc
>  gc_pbkdf2_sha1 (const char *P, size_t Plen,
>                  const char *S, size_t Slen,
> -                unsigned int c, char *DK, size_t dkLen);
> +                unsigned int c, char * restrict DK, size_t dkLen);
>  
>  /*
>    TODO:
> diff --git a/lib/gl_openssl.h b/lib/gl_openssl.h
> index e5991d8..d188a6a 100644
> --- a/lib/gl_openssl.h
> +++ b/lib/gl_openssl.h
> @@ -90,15 +90,15 @@ GL_CRYPTO_FN (_process_block) (const void *buf, size_t len, struct _gl_ctx *ctx)
>  #endif
>  
>  GL_OPENSSL_INLINE void *
> -GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void *res)
> +GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void * restrict res)
>  { OPENSSL_FN (_Final) ((unsigned char *) res, (_gl_CTX *) ctx); return res; }
>  
>  GL_OPENSSL_INLINE void *
> -GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void *res)
> +GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void * restrict res)
>  { return OPENSSL_FN () ((const unsigned char *) buf, len, (unsigned char *) res); }
>  
>  GL_OPENSSL_INLINE void *
> -GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void *res)
> +GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void * restrict res)
>  {
>    /* Assume any unprocessed bytes in ctx are not to be ignored.  */
>    _gl_CTX tmp_ctx = *(_gl_CTX *) ctx;
> diff --git a/lib/memcoll.h b/lib/memcoll.h
> index add0968..233385b 100644
> --- a/lib/memcoll.h
> +++ b/lib/memcoll.h
> @@ -22,7 +22,7 @@
>  
>  # include <stddef.h>
>  
> -int memcoll (char *, size_t, char *, size_t);
> +int memcoll (char * restrict, size_t, char * restrict, size_t);
>  int memcoll0 (char const *, size_t, char const *, size_t);
>  
>  #endif /* MEMCOLL_H_ */
> diff --git a/lib/monetary.in.h b/lib/monetary.in.h
> index ab17917..5b67cec 100644
> --- a/lib/monetary.in.h
> +++ b/lib/monetary.in.h
> @@ -79,15 +79,18 @@ extern "C" {
>  #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
>  #   define strfmon_l rpl_strfmon_l
>  #  endif
> -_GL_FUNCDECL_RPL (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
> +_GL_FUNCDECL_RPL (strfmon_l, ssize_t, (char * restrict s, size_t maxsize,
> +                                       locale_t locale,
>                                         const char *format, ...)
>                                        _GL_ATTRIBUTE_FORMAT_STRFMON (4, 5)
>                                        _GL_ARG_NONNULL ((4)));
> -_GL_CXXALIAS_RPL (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
> +_GL_CXXALIAS_RPL (strfmon_l, ssize_t, (char * restrict s, size_t maxsize,
> +                                       locale_t locale,
>                                         const char *format, ...));
>  # else
>  #  if @HAVE_STRFMON_L@
> -_GL_CXXALIAS_SYS (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
> +_GL_CXXALIAS_SYS (strfmon_l, ssize_t, (char * restrict s, size_t maxsize,
> +                                       locale_t locale,
>                                         const char *format, ...));
>  #  endif
>  # endif
> diff --git a/lib/parse-datetime.h b/lib/parse-datetime.h
> index ab9b576..d2c7518 100644
> --- a/lib/parse-datetime.h
> +++ b/lib/parse-datetime.h
> @@ -19,11 +19,13 @@
>  #include <stdbool.h>
>  #include <time.h>
>  
> -bool parse_datetime (struct timespec *, char const *, struct timespec const *);
> +bool parse_datetime (struct timespec * restrict,
> +                     char const *, struct timespec const *);
>  
>  /* parse_datetime2 flag: if set, print debug/progress information to STDERR */
>  #define PARSE_DATETIME_DEBUG 1
>  
>  /* same as above, supporting additional flags */
> -bool parse_datetime2 (struct timespec *, char const *, struct timespec const *,
> +bool parse_datetime2 (struct timespec * restrict,
> +                      char const *, struct timespec const *,
>                        unsigned int flags, timezone_t, char const *);
> diff --git a/lib/quotearg.h b/lib/quotearg.h
> index d30fdd1..1261c8f 100644
> --- a/lib/quotearg.h
> +++ b/lib/quotearg.h
> @@ -323,7 +323,7 @@ void set_custom_quoting (struct quoting_options *o,
>     On output, BUFFER might contain embedded null bytes if ARGSIZE was
>     not -1, the style of O does not use backslash escapes, and the
>     flags of O do not request elision of null bytes.*/
> -size_t quotearg_buffer (char *buffer, size_t buffersize,
> +size_t quotearg_buffer (char * restrict buffer, size_t buffersize,
>                          char const *arg, size_t argsize,
>                          struct quoting_options const *o);
>  
> diff --git a/lib/regex-quote.h b/lib/regex-quote.h
> index 185f9fe..0d166c7 100644
> --- a/lib/regex-quote.h
> +++ b/lib/regex-quote.h
> @@ -77,7 +77,7 @@ extern size_t
>  /* Copies the quoted string to p and returns the incremented p.
>     There must be room for regex_quote_length (string, spec) + 1 bytes at p.  */
>  extern char *
> -       regex_quote_copy (char *p,
> +       regex_quote_copy (char * restrict p,
>                           const char *string, const struct regex_quote_spec *spec);
>  
>  /* Returns the freshly allocated quoted string.  */
> diff --git a/lib/rijndael-api-fst.h b/lib/rijndael-api-fst.h
> index 0553acc..e6ac5ab 100644
> --- a/lib/rijndael-api-fst.h
> +++ b/lib/rijndael-api-fst.h
> @@ -157,7 +157,7 @@ extern int
>  rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
>                        const rijndaelKeyInstance *key,
>                        const char *input, size_t inputLen,
> -                      char *outBuffer);
> +                      char * restrict outBuffer);
>  
>  /* Encrypt data in INPUT, of INPUTOCTETS bytes length, placing the
>     output in the pre-allocated OUTBUFFER which must hold at least
> @@ -172,7 +172,7 @@ extern int
>  rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
>                      const rijndaelKeyInstance *key,
>                      const char *input, size_t inputOctets,
> -                    char *outBuffer);
> +                    char * restrict outBuffer);
>  
>  /* Decrypt data in INPUT, of INPUTLEN/8 bytes length, placing the
>     output in the pre-allocated OUTBUFFER which must hold at least
> @@ -185,7 +185,7 @@ extern int
>  rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
>                        const rijndaelKeyInstance *key,
>                        const char *input, size_t inputLen,
> -                      char *outBuffer);
> +                      char * restrict outBuffer);
>  
>  /* Decrypt data in INPUT, of INPUTOCTETS bytes length, placing the
>     output in the pre-allocated OUTBUFFER which must hold at least
> @@ -200,6 +200,6 @@ extern int
>  rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
>                      const rijndaelKeyInstance *key,
>                      const char *input, size_t inputOctets,
> -                    char *outBuffer);
> +                    char * restrict outBuffer);
>  
>  #endif /* __RIJNDAEL_API_FST_H */
> diff --git a/lib/sh-quote.h b/lib/sh-quote.h
> index 9dcd4cf..2f9a69b 100644
> --- a/lib/sh-quote.h
> +++ b/lib/sh-quote.h
> @@ -33,7 +33,7 @@ extern size_t shell_quote_length (const char *string);
>  
>  /* Copies the quoted string to p and returns the incremented p.
>     There must be room for shell_quote_length (string) + 1 bytes at p.  */
> -extern char * shell_quote_copy (char *p, const char *string);
> +extern char * shell_quote_copy (char * restrict p, const char *string);
>  
>  /* Returns the freshly allocated quoted string.  */
>  extern char * shell_quote (const char *string);
> diff --git a/lib/sha1.h b/lib/sha1.h
> index 99c53da..e97914b 100644
> --- a/lib/sha1.h
> +++ b/lib/sha1.h
> @@ -71,13 +71,13 @@ extern void sha1_process_bytes (const void *buffer, size_t len,
>     in first 20 bytes following RESBUF.  The result is always in little
>     endian byte order, so that a byte-wise output yields to the wanted
>     ASCII representation of the message digest.  */
> -extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
> +extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void * restrict resbuf);
>  
>  
>  /* Put result from CTX in first 20 bytes following RESBUF.  The result is
>     always in little endian byte order, so that a byte-wise output yields
>     to the wanted ASCII representation of the message digest.  */
> -extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
> +extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void * restrict resbuf);
>  
>  
>  /* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
> diff --git a/lib/sha256.h b/lib/sha256.h
> index 1bc61d4..a1dad2e 100644
> --- a/lib/sha256.h
> +++ b/lib/sha256.h
> @@ -70,15 +70,17 @@ extern void sha256_process_bytes (const void *buffer, size_t len,
>     in first 32 (28) bytes following RESBUF.  The result is always in little
>     endian byte order, so that a byte-wise output yields to the wanted
>     ASCII representation of the message digest.  */
> -extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf);
> -extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf);
> +extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void * restrict resbuf);
> +extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void * restrict resbuf);
>  
>  
>  /* Put result from CTX in first 32 (28) bytes following RESBUF.  The result is
>     always in little endian byte order, so that a byte-wise output yields
>     to the wanted ASCII representation of the message digest.  */
> -extern void *sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
> -extern void *sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
> +extern void *sha256_read_ctx (const struct sha256_ctx *ctx,
> +                              void * restrict resbuf);
> +extern void *sha224_read_ctx (const struct sha256_ctx *ctx,
> +                              void * restrict resbuf);
>  
>  
>  /* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER.  The
> diff --git a/lib/sha512.h b/lib/sha512.h
> index aaf35a5..20818e0 100644
> --- a/lib/sha512.h
> +++ b/lib/sha512.h
> @@ -70,8 +70,8 @@ extern void sha512_process_bytes (const void *buffer, size_t len,
>     in first 64 (48) bytes following RESBUF.  The result is always in little
>     endian byte order, so that a byte-wise output yields to the wanted
>     ASCII representation of the message digest.  */
> -extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
> -extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
> +extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void * restrict resbuf);
> +extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void * restrict resbuf);
>  
>  
>  /* Put result from CTX in first 64 (48) bytes following RESBUF.  The result is
> @@ -80,8 +80,10 @@ extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
>  
>     IMPORTANT: On some systems it is required that RESBUF is correctly
>     aligned for a 32 bits value.  */
> -extern void *sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
> -extern void *sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
> +extern void *sha512_read_ctx (const struct sha512_ctx *ctx,
> +                              void * restrict resbuf);
> +extern void *sha384_read_ctx (const struct sha512_ctx *ctx,
> +                              void * restrict resbuf);
>  
>  
>  /* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER.  The
> diff --git a/lib/signal.in.h b/lib/signal.in.h
> index 9fe9f60..9690953 100644
> --- a/lib/signal.in.h
> +++ b/lib/signal.in.h
> @@ -133,16 +133,20 @@ typedef void (*sighandler_t) (int);
>  #   define pthread_sigmask rpl_pthread_sigmask
>  #  endif
>  _GL_FUNCDECL_RPL (pthread_sigmask, int,
> -                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
> +                  (int how, const sigset_t *new_mask,
> +                   sigset_t * restrict old_mask));
>  _GL_CXXALIAS_RPL (pthread_sigmask, int,
> -                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
> +                  (int how, const sigset_t *new_mask,
> +                   sigset_t * restrict old_mask));
>  # else
>  #  if !(@HAVE_PTHREAD_SIGMASK@ || defined pthread_sigmask)
>  _GL_FUNCDECL_SYS (pthread_sigmask, int,
> -                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
> +                  (int how, const sigset_t *new_mask,
> +                   sigset_t * restrict old_mask));
>  #  endif
>  _GL_CXXALIAS_SYS (pthread_sigmask, int,
> -                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
> +                  (int how, const sigset_t *new_mask,
> +                   sigset_t * restrict old_mask));
>  # endif
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (pthread_sigmask);
> @@ -295,10 +299,12 @@ _GL_CXXALIASWARN (sigpending);
>  #  define SIG_SETMASK 1  /* blocked_set = *set; */
>  #  define SIG_UNBLOCK 2  /* blocked_set = blocked_set & ~*set; */
>  _GL_FUNCDECL_SYS (sigprocmask, int,
> -                  (int operation, const sigset_t *set, sigset_t *old_set));
> +                  (int operation, const sigset_t *set,
> +                   sigset_t * restrict old_set));
>  # endif
>  _GL_CXXALIAS_SYS (sigprocmask, int,
> -                  (int operation, const sigset_t *set, sigset_t *old_set));
> +                  (int operation, const sigset_t *set,
> +                   sigset_t * restrict old_set));
>  _GL_CXXALIASWARN (sigprocmask);
>  
>  /* Install the handler FUNC for signal SIG, and return the previous
> diff --git a/lib/sm3.h b/lib/sm3.h
> index e0bdd90..9da0ab3 100644
> --- a/lib/sm3.h
> +++ b/lib/sm3.h
> @@ -75,12 +75,12 @@ extern void sm3_process_bytes (const void *buffer, size_t len,
>     in first 32 bytes following RESBUF.  The result is always in little
>     endian byte order, so that a byte-wise output yields to the wanted
>     ASCII representation of the message digest.  */
> -extern void *sm3_finish_ctx (struct sm3_ctx *ctx, void *resbuf);
> +extern void *sm3_finish_ctx (struct sm3_ctx *ctx, void * restrict resbuf);
>  
>  /* Put result from CTX in first 32 bytes following RESBUF.  The result is
>     always in little endian byte order, so that a byte-wise output yields
>     to the wanted ASCII representation of the message digest.  */
> -extern void *sm3_read_ctx (const struct sm3_ctx *ctx, void *resbuf);
> +extern void *sm3_read_ctx (const struct sm3_ctx *ctx, void * restrict resbuf);
>  
>  /* Compute SM3 message digest for LEN bytes beginning at BUFFER.  The
>     result is always in little endian byte order, so that a byte-wise
> diff --git a/lib/stdio.in.h b/lib/stdio.in.h
> index 388565d..2386852 100644
> --- a/lib/stdio.in.h
> +++ b/lib/stdio.in.h
> @@ -1113,20 +1113,20 @@ _GL_CXXALIASWARN (scanf);
>  #   define snprintf rpl_snprintf
>  #  endif
>  _GL_FUNCDECL_RPL (snprintf, int,
> -                  (char *str, size_t size, const char *format, ...)
> +                  (char * restrict str, size_t size, const char *format, ...)
>                    _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4)
>                    _GL_ARG_NONNULL ((3)));
>  _GL_CXXALIAS_RPL (snprintf, int,
> -                  (char *str, size_t size, const char *format, ...));
> +                  (char * restrict str, size_t size, const char *format, ...));
>  # else
>  #  if !@HAVE_DECL_SNPRINTF@
>  _GL_FUNCDECL_SYS (snprintf, int,
> -                  (char *str, size_t size, const char *format, ...)
> +                  (char * restrict str, size_t size, const char *format, ...)
>                    _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4)
>                    _GL_ARG_NONNULL ((3)));
>  #  endif
>  _GL_CXXALIAS_SYS (snprintf, int,
> -                  (char *str, size_t size, const char *format, ...));
> +                  (char * restrict str, size_t size, const char *format, ...));
>  # endif
>  _GL_CXXALIASWARN (snprintf);
>  #elif defined GNULIB_POSIXCHECK
> @@ -1151,12 +1151,12 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - "
>  #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
>  #   define sprintf rpl_sprintf
>  #  endif
> -_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...)
> +_GL_FUNCDECL_RPL (sprintf, int, (char * restrict str, const char *format, ...)
>                                  _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
>                                  _GL_ARG_NONNULL ((1, 2)));
> -_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...));
> +_GL_CXXALIAS_RPL (sprintf, int, (char * restrict str, const char *format, ...));
>  # else
> -_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...));
> +_GL_CXXALIAS_SYS (sprintf, int, (char * restrict str, const char *format, ...));
>  # endif
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (sprintf);
> @@ -1386,20 +1386,24 @@ _GL_CXXALIASWARN (vscanf);
>  #   define vsnprintf rpl_vsnprintf
>  #  endif
>  _GL_FUNCDECL_RPL (vsnprintf, int,
> -                  (char *str, size_t size, const char *format, va_list args)
> +                  (char * restrict str, size_t size,
> +                   const char *format, va_list args)
>                    _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0)
>                    _GL_ARG_NONNULL ((3)));
>  _GL_CXXALIAS_RPL (vsnprintf, int,
> -                  (char *str, size_t size, const char *format, va_list args));
> +                  (char * restrict str, size_t size,
> +                   const char *format, va_list args));
>  # else
>  #  if !@HAVE_DECL_VSNPRINTF@
>  _GL_FUNCDECL_SYS (vsnprintf, int,
> -                  (char *str, size_t size, const char *format, va_list args)
> +                  (char * restrict str, size_t size,
> +                   const char *format, va_list args)
>                    _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0)
>                    _GL_ARG_NONNULL ((3)));
>  #  endif
>  _GL_CXXALIAS_SYS (vsnprintf, int,
> -                  (char *str, size_t size, const char *format, va_list args));
> +                  (char * restrict str, size_t size,
> +                   const char *format, va_list args));
>  # endif
>  _GL_CXXALIASWARN (vsnprintf);
>  #elif defined GNULIB_POSIXCHECK
> @@ -1416,17 +1420,17 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - "
>  #   define vsprintf rpl_vsprintf
>  #  endif
>  _GL_FUNCDECL_RPL (vsprintf, int,
> -                  (char *str, const char *format, va_list args)
> +                  (char * restrict str, const char *format, va_list args)
>                    _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
>                    _GL_ARG_NONNULL ((1, 2)));
>  _GL_CXXALIAS_RPL (vsprintf, int,
> -                  (char *str, const char *format, va_list args));
> +                  (char * restrict str, const char *format, va_list args));
>  # else
>  /* Need to cast, because on Solaris, the third parameter is
>                                                         __va_list args
>     and GCC's fixincludes did not change this to __gnuc_va_list.  */
>  _GL_CXXALIAS_SYS_CAST (vsprintf, int,
> -                       (char *str, const char *format, va_list args));
> +                       (char * restrict str, const char *format, va_list args));
>  # endif
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (vsprintf);
> diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
> index 49bbf6f..5ae909d 100644
> --- a/lib/stdlib.in.h
> +++ b/lib/stdlib.in.h
> @@ -866,15 +866,19 @@ _GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - "
>  #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
>  #   define realpath rpl_realpath
>  #  endif
> -_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved)
> -                                    _GL_ARG_NONNULL ((1)));
> -_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved));
> +_GL_FUNCDECL_RPL (realpath, char *,
> +                  (const char *name, char * restrict resolved)
> +                  _GL_ARG_NONNULL ((1)));
> +_GL_CXXALIAS_RPL (realpath, char *,
> +                  (const char *name, char * restrict resolved));
>  # else
>  #  if !@HAVE_REALPATH@
> -_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved)
> -                                    _GL_ARG_NONNULL ((1)));
> +_GL_FUNCDECL_SYS (realpath, char *,
> +                  (const char *name, char * restrict resolved)
> +                  _GL_ARG_NONNULL ((1)));
>  #  endif
> -_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved));
> +_GL_CXXALIAS_SYS (realpath, char *,
> +                  (const char *name, char * restrict resolved));
>  # endif
>  _GL_CXXALIASWARN (realpath);
>  #elif defined GNULIB_POSIXCHECK
> diff --git a/lib/strftime.h b/lib/strftime.h
> index 97a062c..d0ac48e 100644
> --- a/lib/strftime.h
> +++ b/lib/strftime.h
> @@ -25,7 +25,7 @@ extern "C" {
>     POSIX requires that strftime use the local timezone information.
>     Use the timezone __TZ instead.  Use __NS as the number of
>     nanoseconds in the %N directive.  */
> -size_t nstrftime (char *, size_t, char const *, struct tm const *,
> +size_t nstrftime (char * restrict, size_t, char const *, struct tm const *,
>                    timezone_t __tz, int __ns);
>  
>  #ifdef __cplusplus
> diff --git a/lib/string.in.h b/lib/string.in.h
> index 2be474d..de97453 100644
> --- a/lib/string.in.h
> +++ b/lib/string.in.h
> @@ -411,11 +411,14 @@ _GL_WARN_ON_USE (strdup, "strdup is unportable - "
>  #   undef strncat
>  #   define strncat rpl_strncat
>  #  endif
> -_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n)
> -                                   _GL_ARG_NONNULL ((1, 2)));
> -_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n));
> +_GL_FUNCDECL_RPL (strncat, char *,
> +                  (char * restrict dest, const char *src, size_t n)
> +                  _GL_ARG_NONNULL ((1, 2)));
> +_GL_CXXALIAS_RPL (strncat, char *,
> +                  (char * restrict dest, const char *src, size_t n));
>  # else
> -_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n));
> +_GL_CXXALIAS_SYS (strncat, char *,
> +                  (char * restrict dest, const char *src, size_t n));
>  # endif
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (strncat);
> @@ -966,7 +969,8 @@ _GL_EXTERN_C char * mbssep (char **stringp, const char *delim)
>     Caveat: The identity of the delimiting character is lost.
>  
>     See also mbssep().  */
> -_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr)
> +_GL_EXTERN_C char * mbstok_r (char * restrict string, const char *delim,
> +                              char **save_ptr)
>       _GL_ARG_NONNULL ((2, 3));
>  #endif
>  
> diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h
> index 8e013e6..2c44801 100644
> --- a/lib/sys_socket.in.h
> +++ b/lib/sys_socket.in.h
> @@ -462,15 +462,18 @@ _GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - "
>  #   define getsockopt rpl_getsockopt
>  #  endif
>  _GL_FUNCDECL_RPL (getsockopt, int, (int fd, int level, int optname,
> -                                    void *optval, socklen_t *optlen)
> +                                    void * restrict optval,
> +                                    socklen_t * restrict optlen)
>                                     _GL_ARG_NONNULL ((4, 5)));
>  _GL_CXXALIAS_RPL (getsockopt, int, (int fd, int level, int optname,
> -                                    void *optval, socklen_t *optlen));
> +                                    void * restrict optval,
> +                                    socklen_t * restrict optlen));
>  # else
>  /* Need to cast, because on Solaris 10 systems, the fifth parameter is
>                                                         void *optlen.  */
>  _GL_CXXALIAS_SYS_CAST (getsockopt, int, (int fd, int level, int optname,
> -                                         void *optval, socklen_t *optlen));
> +                                         void * restrict optval,
> +                                         socklen_t * restrict optlen));
>  # endif
>  _GL_CXXALIASWARN (getsockopt);
>  #elif @HAVE_WINSOCK2_H@
> @@ -571,17 +574,17 @@ _GL_WARN_ON_USE (send, "send is not always POSIX compliant - "
>  #   define recvfrom rpl_recvfrom
>  #  endif
>  _GL_FUNCDECL_RPL (recvfrom, ssize_t,
> -                  (int fd, void *buf, size_t len, int flags,
> +                  (int fd, void * restrict buf, size_t len, int flags,
>                     struct sockaddr *from, socklen_t *fromlen)
>                    _GL_ARG_NONNULL ((2)));
>  _GL_CXXALIAS_RPL (recvfrom, ssize_t,
> -                  (int fd, void *buf, size_t len, int flags,
> +                  (int fd, void * restrict buf, size_t len, int flags,
>                     struct sockaddr *from, socklen_t *fromlen));
>  # else
>  /* Need to cast, because on Solaris 10 systems, the sixth parameter is
>                                                 void *fromlen.  */
>  _GL_CXXALIAS_SYS_CAST (recvfrom, ssize_t,
> -                       (int fd, void *buf, size_t len, int flags,
> +                       (int fd, void * restrict buf, size_t len, int flags,
>                          struct sockaddr *from, socklen_t *fromlen));
>  # endif
>  _GL_CXXALIASWARN (recvfrom);
> diff --git a/lib/system-quote.h b/lib/system-quote.h
> index d31d47f..2f50779 100644
> --- a/lib/system-quote.h
> +++ b/lib/system-quote.h
> @@ -77,7 +77,7 @@ extern size_t
>  /* Copies the quoted string to p and returns the incremented p.
>     There must be room for system_quote_length (string) + 1 bytes at p.  */
>  extern char *
> -       system_quote_copy (char *p,
> +       system_quote_copy (char * restrict p,
>                            enum system_command_interpreter interpreter,
>                            const char *string);
>  
> diff --git a/lib/time.in.h b/lib/time.in.h
> index 7304668..0edf0b3 100644
> --- a/lib/time.in.h
> +++ b/lib/time.in.h
> @@ -286,13 +286,13 @@ _GL_CXXALIASWARN (ctime);
>  #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
>  #    define strftime rpl_strftime
>  #   endif
> -_GL_FUNCDECL_RPL (strftime, size_t, (char *__buf, size_t __bufsize,
> +_GL_FUNCDECL_RPL (strftime, size_t, (char * restrict __buf, size_t __bufsize,
>                                       const char *__fmt, const struct tm *__tp)
>                                      _GL_ARG_NONNULL ((1, 3, 4)));
> -_GL_CXXALIAS_RPL (strftime, size_t, (char *__buf, size_t __bufsize,
> +_GL_CXXALIAS_RPL (strftime, size_t, (char * restrict __buf, size_t __bufsize,
>                                       const char *__fmt, const struct tm *__tp));
>  #  else
> -_GL_CXXALIAS_SYS (strftime, size_t, (char *__buf, size_t __bufsize,
> +_GL_CXXALIAS_SYS (strftime, size_t, (char * restrict __buf, size_t __bufsize,
>                                       const char *__fmt, const struct tm *__tp));
>  #  endif
>  #  if __GLIBC__ >= 2
> diff --git a/lib/unicase.in.h b/lib/unicase.in.h
> index 45c5f91..b622ac4 100644
> --- a/lib/unicase.in.h
> +++ b/lib/unicase.in.h
> @@ -96,15 +96,15 @@ extern const char *
>  extern uint8_t *
>         u8_toupper (const uint8_t *s, size_t n, const char *iso639_language,
>                     uninorm_t nf,
> -                   uint8_t *resultbuf, size_t *lengthp);
> +                   uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_toupper (const uint16_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint16_t *resultbuf, size_t *lengthp);
> +                    uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_toupper (const uint32_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint32_t *resultbuf, size_t *lengthp);
> +                    uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* Return the lowercase mapping of a string.
>     The nf argument identifies the normalization form to apply after the
> @@ -112,15 +112,15 @@ extern uint32_t *
>  extern uint8_t *
>         u8_tolower (const uint8_t *s, size_t n, const char *iso639_language,
>                     uninorm_t nf,
> -                   uint8_t *resultbuf, size_t *lengthp);
> +                   uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_tolower (const uint16_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint16_t *resultbuf, size_t *lengthp);
> +                    uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_tolower (const uint32_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint32_t *resultbuf, size_t *lengthp);
> +                    uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* Return the titlecase mapping of a string.
>     The nf argument identifies the normalization form to apply after the
> @@ -128,15 +128,15 @@ extern uint32_t *
>  extern uint8_t *
>         u8_totitle (const uint8_t *s, size_t n, const char *iso639_language,
>                     uninorm_t nf,
> -                   uint8_t *resultbuf, size_t *lengthp);
> +                   uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_totitle (const uint16_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint16_t *resultbuf, size_t *lengthp);
> +                    uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_totitle (const uint32_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint32_t *resultbuf, size_t *lengthp);
> +                    uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* The case-mapping context given by a prefix string.  */
>  typedef struct casing_prefix_context
> @@ -204,21 +204,21 @@ extern uint8_t *
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint8_t *resultbuf, size_t *lengthp);
> +                      uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_ct_toupper (const uint16_t *s, size_t n,
>                        casing_prefix_context_t prefix_context,
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint16_t *resultbuf, size_t *lengthp);
> +                      uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_ct_toupper (const uint32_t *s, size_t n,
>                        casing_prefix_context_t prefix_context,
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint32_t *resultbuf, size_t *lengthp);
> +                      uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* Return the lowercase mapping of a string that is surrounded by a prefix
>     and a suffix.  */
> @@ -228,21 +228,21 @@ extern uint8_t *
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint8_t *resultbuf, size_t *lengthp);
> +                      uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_ct_tolower (const uint16_t *s, size_t n,
>                        casing_prefix_context_t prefix_context,
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint16_t *resultbuf, size_t *lengthp);
> +                      uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_ct_tolower (const uint32_t *s, size_t n,
>                        casing_prefix_context_t prefix_context,
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint32_t *resultbuf, size_t *lengthp);
> +                      uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* Return the titlecase mapping of a string that is surrounded by a prefix
>     and a suffix.  */
> @@ -252,21 +252,21 @@ extern uint8_t *
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint8_t *resultbuf, size_t *lengthp);
> +                      uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_ct_totitle (const uint16_t *s, size_t n,
>                        casing_prefix_context_t prefix_context,
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint16_t *resultbuf, size_t *lengthp);
> +                      uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_ct_totitle (const uint32_t *s, size_t n,
>                        casing_prefix_context_t prefix_context,
>                        casing_suffix_context_t suffix_context,
>                        const char *iso639_language,
>                        uninorm_t nf,
> -                      uint32_t *resultbuf, size_t *lengthp);
> +                      uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* Return the case folded string.
>     Comparing uN_casefold (S1) and uN_casefold (S2) with uN_cmp2() is equivalent
> @@ -276,15 +276,15 @@ extern uint32_t *
>  extern uint8_t *
>         u8_casefold (const uint8_t *s, size_t n, const char *iso639_language,
>                      uninorm_t nf,
> -                    uint8_t *resultbuf, size_t *lengthp);
> +                    uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_casefold (const uint16_t *s, size_t n, const char *iso639_language,
>                       uninorm_t nf,
> -                     uint16_t *resultbuf, size_t *lengthp);
> +                     uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_casefold (const uint32_t *s, size_t n, const char *iso639_language,
>                       uninorm_t nf,
> -                     uint32_t *resultbuf, size_t *lengthp);
> +                     uint32_t * restrict resultbuf, size_t *lengthp);
>  /* Likewise, for a string that is surrounded by a prefix and a suffix.  */
>  extern uint8_t *
>         u8_ct_casefold (const uint8_t *s, size_t n,
> @@ -292,21 +292,21 @@ extern uint8_t *
>                         casing_suffix_context_t suffix_context,
>                         const char *iso639_language,
>                         uninorm_t nf,
> -                       uint8_t *resultbuf, size_t *lengthp);
> +                       uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_ct_casefold (const uint16_t *s, size_t n,
>                          casing_prefix_context_t prefix_context,
>                          casing_suffix_context_t suffix_context,
>                          const char *iso639_language,
>                          uninorm_t nf,
> -                        uint16_t *resultbuf, size_t *lengthp);
> +                        uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_ct_casefold (const uint32_t *s, size_t n,
>                          casing_prefix_context_t prefix_context,
>                          casing_suffix_context_t suffix_context,
>                          const char *iso639_language,
>                          uninorm_t nf,
> -                        uint32_t *resultbuf, size_t *lengthp);
> +                        uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  /* Compare S1 and S2, ignoring differences in case and normalization.
>     The nf argument identifies the normalization form to apply after the
> @@ -336,16 +336,16 @@ extern int
>     NF must be either UNINORM_NFC, UNINORM_NFKC, or NULL for no normalization.  */
>  extern char *
>         u8_casexfrm (const uint8_t *s, size_t n, const char *iso639_language,
> -                    uninorm_t nf, char *resultbuf, size_t *lengthp);
> +                    uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
>  extern char *
>         u16_casexfrm (const uint16_t *s, size_t n, const char *iso639_language,
> -                     uninorm_t nf, char *resultbuf, size_t *lengthp);
> +                     uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
>  extern char *
>         u32_casexfrm (const uint32_t *s, size_t n, const char *iso639_language,
> -                     uninorm_t nf, char *resultbuf, size_t *lengthp);
> +                     uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
>  extern char *
>         ulc_casexfrm (const char *s, size_t n, const char *iso639_language,
> -                     uninorm_t nf, char *resultbuf, size_t *lengthp);
> +                     uninorm_t nf, char * restrict resultbuf, size_t *lengthp);
>  
>  /* Compare S1 and S2, ignoring differences in case and normalization, using the
>     collation rules of the current locale.
> diff --git a/lib/uniconv.in.h b/lib/uniconv.in.h
> index 53dc3fc..4e7f872 100644
> --- a/lib/uniconv.in.h
> +++ b/lib/uniconv.in.h
> @@ -98,19 +98,19 @@ extern char *
>                              enum iconv_ilseq_handler handler,
>                              const uint8_t *src, size_t srclen,
>                              size_t *offsets,
> -                            char *resultbuf, size_t *lengthp);
> +                            char * restrict resultbuf, size_t *lengthp);
>  extern char *
>         u16_conv_to_encoding (const char *tocode,
>                               enum iconv_ilseq_handler handler,
>                               const uint16_t *src, size_t srclen,
>                               size_t *offsets,
> -                             char *resultbuf, size_t *lengthp);
> +                             char * restrict resultbuf, size_t *lengthp);
>  extern char *
>         u32_conv_to_encoding (const char *tocode,
>                               enum iconv_ilseq_handler handler,
>                               const uint32_t *src, size_t srclen,
>                               size_t *offsets,
> -                             char *resultbuf, size_t *lengthp);
> +                             char * restrict resultbuf, size_t *lengthp);
>  
>  /* Converts a NUL terminated string from a given encoding.
>     The result is malloc allocated, or NULL (with errno set) in case of error.
> diff --git a/lib/unilbrk.in.h b/lib/unilbrk.in.h
> index 408b905..83ba59c 100644
> --- a/lib/unilbrk.in.h
> +++ b/lib/unilbrk.in.h
> @@ -58,16 +58,16 @@ enum
>   */
>  extern void
>         u8_possible_linebreaks (const uint8_t *s, size_t n,
> -                               const char *encoding, char *p);
> +                               const char *encoding, char * restrict p);
>  extern void
>         u16_possible_linebreaks (const uint16_t *s, size_t n,
> -                                const char *encoding, char *p);
> +                                const char *encoding, char * restrict p);
>  extern void
>         u32_possible_linebreaks (const uint32_t *s, size_t n,
> -                                const char *encoding, char *p);
> +                                const char *encoding, char * restrict p);
>  extern void
>         ulc_possible_linebreaks (const char *s, size_t n,
> -                                const char *encoding, char *p);
> +                                const char *encoding, char * restrict p);
>  
>  /* Choose the best line breaks, assuming the uc_width function.
>     The string is s[0..n-1].  The maximum number of columns per line is given
> @@ -84,22 +84,22 @@ extern int
>         u8_width_linebreaks (const uint8_t *s, size_t n, int width,
>                              int start_column, int at_end_columns,
>                              const char *o, const char *encoding,
> -                            char *p);
> +                            char * restrict p);
>  extern int
>         u16_width_linebreaks (const uint16_t *s, size_t n, int width,
>                               int start_column, int at_end_columns,
>                               const char *o, const char *encoding,
> -                             char *p);
> +                             char * restrict p);
>  extern int
>         u32_width_linebreaks (const uint32_t *s, size_t n, int width,
>                               int start_column, int at_end_columns,
>                               const char *o, const char *encoding,
> -                             char *p);
> +                             char * restrict p);
>  extern int
>         ulc_width_linebreaks (const char *s, size_t n, int width,
>                               int start_column, int at_end_columns,
>                               const char *o, const char *encoding,
> -                             char *p);
> +                             char * restrict p);
>  
>  
>  #ifdef __cplusplus
> diff --git a/lib/uninorm.in.h b/lib/uninorm.in.h
> index 9ebdb6b..e4cb7d9 100644
> --- a/lib/uninorm.in.h
> +++ b/lib/uninorm.in.h
> @@ -143,13 +143,13 @@ extern uninorm_t
>  /* Return the specified normalization form of a string.  */
>  extern uint8_t *
>         u8_normalize (uninorm_t nf, const uint8_t *s, size_t n,
> -                     uint8_t *resultbuf, size_t *lengthp);
> +                     uint8_t * restrict resultbuf, size_t *lengthp);
>  extern uint16_t *
>         u16_normalize (uninorm_t nf, const uint16_t *s, size_t n,
> -                      uint16_t *resultbuf, size_t *lengthp);
> +                      uint16_t * restrict resultbuf, size_t *lengthp);
>  extern uint32_t *
>         u32_normalize (uninorm_t nf, const uint32_t *s, size_t n,
> -                      uint32_t *resultbuf, size_t *lengthp);
> +                      uint32_t * restrict resultbuf, size_t *lengthp);
>  
>  
>  /* Compare S1 and S2, ignoring differences in normalization.
> diff --git a/lib/unistd.in.h b/lib/unistd.in.h
> index 6db7ff2..297f6dd 100644
> --- a/lib/unistd.in.h
> +++ b/lib/unistd.in.h
> @@ -1370,18 +1370,18 @@ _GL_CXXALIASWARN (read);
>  #   define readlink rpl_readlink
>  #  endif
>  _GL_FUNCDECL_RPL (readlink, ssize_t,
> -                  (const char *file, char *buf, size_t bufsize)
> +                  (const char *file, char * restrict buf, size_t bufsize)
>                    _GL_ARG_NONNULL ((1, 2)));
>  _GL_CXXALIAS_RPL (readlink, ssize_t,
> -                  (const char *file, char *buf, size_t bufsize));
> +                  (const char *file, char * restrict buf, size_t bufsize));
>  # else
>  #  if !@HAVE_READLINK@
>  _GL_FUNCDECL_SYS (readlink, ssize_t,
> -                  (const char *file, char *buf, size_t bufsize)
> +                  (const char *file, char * restrict buf, size_t bufsize)
>                    _GL_ARG_NONNULL ((1, 2)));
>  #  endif
>  _GL_CXXALIAS_SYS (readlink, ssize_t,
> -                  (const char *file, char *buf, size_t bufsize));
> +                  (const char *file, char * restrict buf, size_t bufsize));
>  # endif
>  _GL_CXXALIASWARN (readlink);
>  #elif defined GNULIB_POSIXCHECK
> @@ -1399,18 +1399,18 @@ _GL_WARN_ON_USE (readlink, "readlink is unportable - "
>  #   define readlinkat rpl_readlinkat
>  #  endif
>  _GL_FUNCDECL_RPL (readlinkat, ssize_t,
> -                  (int fd, char const *file, char *buf, size_t len)
> +                  (int fd, char const *file, char * restrict buf, size_t len)
>                    _GL_ARG_NONNULL ((2, 3)));
>  _GL_CXXALIAS_RPL (readlinkat, ssize_t,
> -                  (int fd, char const *file, char *buf, size_t len));
> +                  (int fd, char const *file, char * restrict buf, size_t len));
>  # else
>  #  if !@HAVE_READLINKAT@
>  _GL_FUNCDECL_SYS (readlinkat, ssize_t,
> -                  (int fd, char const *file, char *buf, size_t len)
> +                  (int fd, char const *file, char * restrict buf, size_t len)
>                    _GL_ARG_NONNULL ((2, 3)));
>  #  endif
>  _GL_CXXALIAS_SYS (readlinkat, ssize_t,
> -                  (int fd, char const *file, char *buf, size_t len));
> +                  (int fd, char const *file, char * restrict buf, size_t len));
>  # endif
>  _GL_CXXALIASWARN (readlinkat);
>  #elif defined GNULIB_POSIXCHECK
> diff --git a/lib/unistdio.in.h b/lib/unistdio.in.h
> index e6091ec..615d21b 100644
> --- a/lib/unistdio.in.h
> +++ b/lib/unistdio.in.h
> @@ -61,28 +61,28 @@ extern "C" {
>  
>  /* ASCII format string, result in locale dependent encoded 'char *'.  */
>  extern int
> -       ulc_sprintf (char *buf,
> +       ulc_sprintf (char * restrict buf,
>                      const char *format, ...);
>  extern int
> -       ulc_snprintf (char *buf, size_t size,
> +       ulc_snprintf (char * restrict buf, size_t size,
>                       const char *format, ...);
>  extern int
>         ulc_asprintf (char **resultp,
>                       const char *format, ...);
>  extern char *
> -       ulc_asnprintf (char *resultbuf, size_t *lengthp,
> +       ulc_asnprintf (char * restrict resultbuf, size_t *lengthp,
>                        const char *format, ...);
>  extern int
> -       ulc_vsprintf (char *buf,
> +       ulc_vsprintf (char * restrict buf,
>                       const char *format, va_list ap);
>  extern int
> -       ulc_vsnprintf (char *buf, size_t size,
> +       ulc_vsnprintf (char * restrict buf, size_t size,
>                        const char *format, va_list ap);
>  extern int
>         ulc_vasprintf (char **resultp,
>                        const char *format, va_list ap);
>  extern char *
> -       ulc_vasnprintf (char *resultbuf, size_t *lengthp,
> +       ulc_vasnprintf (char * restrict resultbuf, size_t *lengthp,
>                         const char *format, va_list ap);
>  
>  /* ASCII format string, result in UTF-8 format.  */
> @@ -113,28 +113,28 @@ extern uint8_t *
>  
>  /* UTF-8 format string, result in UTF-8 format.  */
>  extern int
> -       u8_u8_sprintf (uint8_t *buf,
> +       u8_u8_sprintf (uint8_t * restrict buf,
>                        const uint8_t *format, ...);
>  extern int
> -       u8_u8_snprintf (uint8_t *buf, size_t size,
> +       u8_u8_snprintf (uint8_t * restrict buf, size_t size,
>                         const uint8_t *format, ...);
>  extern int
>         u8_u8_asprintf (uint8_t **resultp,
>                         const uint8_t *format, ...);
>  extern uint8_t *
> -       u8_u8_asnprintf (uint8_t *resultbuf, size_t *lengthp,
> +       u8_u8_asnprintf (uint8_t * restrict resultbuf, size_t *lengthp,
>                          const uint8_t *format, ...);
>  extern int
> -       u8_u8_vsprintf (uint8_t *buf,
> +       u8_u8_vsprintf (uint8_t * restrict buf,
>                         const uint8_t *format, va_list ap);
>  extern int
> -       u8_u8_vsnprintf (uint8_t *buf, size_t size,
> +       u8_u8_vsnprintf (uint8_t * restrict buf, size_t size,
>                          const uint8_t *format, va_list ap);
>  extern int
>         u8_u8_vasprintf (uint8_t **resultp,
>                          const uint8_t *format, va_list ap);
>  extern uint8_t *
> -       u8_u8_vasnprintf (uint8_t *resultbuf, size_t *lengthp,
> +       u8_u8_vasnprintf (uint8_t * restrict resultbuf, size_t *lengthp,
>                           const uint8_t *format, va_list ap);
>  
>  /* ASCII format string, result in UTF-16 format.  */
> @@ -165,28 +165,28 @@ extern uint16_t *
>  
>  /* UTF-16 format string, result in UTF-16 format.  */
>  extern int
> -       u16_u16_sprintf (uint16_t *buf,
> +       u16_u16_sprintf (uint16_t * restrict buf,
>                          const uint16_t *format, ...);
>  extern int
> -       u16_u16_snprintf (uint16_t *buf, size_t size,
> +       u16_u16_snprintf (uint16_t * restrict buf, size_t size,
>                           const uint16_t *format, ...);
>  extern int
>         u16_u16_asprintf (uint16_t **resultp,
>                           const uint16_t *format, ...);
>  extern uint16_t *
> -       u16_u16_asnprintf (uint16_t *resultbuf, size_t *lengthp,
> +       u16_u16_asnprintf (uint16_t * restrict resultbuf, size_t *lengthp,
>                            const uint16_t *format, ...);
>  extern int
> -       u16_u16_vsprintf (uint16_t *buf,
> +       u16_u16_vsprintf (uint16_t * restrict buf,
>                           const uint16_t *format, va_list ap);
>  extern int
> -       u16_u16_vsnprintf (uint16_t *buf, size_t size,
> +       u16_u16_vsnprintf (uint16_t * restrict buf, size_t size,
>                            const uint16_t *format, va_list ap);
>  extern int
>         u16_u16_vasprintf (uint16_t **resultp,
>                            const uint16_t *format, va_list ap);
>  extern uint16_t *
> -       u16_u16_vasnprintf (uint16_t *resultbuf, size_t *lengthp,
> +       u16_u16_vasnprintf (uint16_t * restrict resultbuf, size_t *lengthp,
>                             const uint16_t *format, va_list ap);
>  
>  /* ASCII format string, result in UTF-32 format.  */
> @@ -217,28 +217,28 @@ extern uint32_t *
>  
>  /* UTF-32 format string, result in UTF-32 format.  */
>  extern int
> -       u32_u32_sprintf (uint32_t *buf,
> +       u32_u32_sprintf (uint32_t * restrict buf,
>                          const uint32_t *format, ...);
>  extern int
> -       u32_u32_snprintf (uint32_t *buf, size_t size,
> +       u32_u32_snprintf (uint32_t * restrict buf, size_t size,
>                           const uint32_t *format, ...);
>  extern int
>         u32_u32_asprintf (uint32_t **resultp,
>                           const uint32_t *format, ...);
>  extern uint32_t *
> -       u32_u32_asnprintf (uint32_t *resultbuf, size_t *lengthp,
> +       u32_u32_asnprintf (uint32_t * restrict resultbuf, size_t *lengthp,
>                            const uint32_t *format, ...);
>  extern int
> -       u32_u32_vsprintf (uint32_t *buf,
> +       u32_u32_vsprintf (uint32_t * restrict buf,
>                           const uint32_t *format, va_list ap);
>  extern int
> -       u32_u32_vsnprintf (uint32_t *buf, size_t size,
> +       u32_u32_vsnprintf (uint32_t * restrict buf, size_t size,
>                            const uint32_t *format, va_list ap);
>  extern int
>         u32_u32_vasprintf (uint32_t **resultp,
>                            const uint32_t *format, va_list ap);
>  extern uint32_t *
> -       u32_u32_vasnprintf (uint32_t *resultbuf, size_t *lengthp,
> +       u32_u32_vasnprintf (uint32_t * restrict resultbuf, size_t *lengthp,
>                             const uint32_t *format, va_list ap);
>  
>  /* ASCII format string, output to FILE in locale dependent encoding.  */
> diff --git a/lib/unistr.in.h b/lib/unistr.in.h
> index bc0d237..c580774 100644
> --- a/lib/unistr.in.h
> +++ b/lib/unistr.in.h
> @@ -373,11 +373,11 @@ u32_uctomb (uint32_t *s, ucs4_t uc, int n)
>  /* Copy N units from SRC to DEST.  */
>  /* Similar to memcpy().  */
>  extern uint8_t *
> -       u8_cpy (uint8_t *dest, const uint8_t *src, size_t n);
> +       u8_cpy (uint8_t * restrict dest, const uint8_t *src, size_t n);
>  extern uint16_t *
> -       u16_cpy (uint16_t *dest, const uint16_t *src, size_t n);
> +       u16_cpy (uint16_t * restrict dest, const uint16_t *src, size_t n);
>  extern uint32_t *
> -       u32_cpy (uint32_t *dest, const uint32_t *src, size_t n);
> +       u32_cpy (uint32_t * restrict dest, const uint32_t *src, size_t n);
>  
>  /* Copy N units from SRC to DEST, guaranteeing correct behavior for
>     overlapping memory areas.  */
> @@ -528,57 +528,57 @@ extern size_t
>  /* Copy SRC to DEST.  */
>  /* Similar to strcpy(), wcscpy().  */
>  extern uint8_t *
> -       u8_strcpy (uint8_t *dest, const uint8_t *src);
> +       u8_strcpy (uint8_t * restrict dest, const uint8_t *src);
>  extern uint16_t *
> -       u16_strcpy (uint16_t *dest, const uint16_t *src);
> +       u16_strcpy (uint16_t * restrict dest, const uint16_t *src);
>  extern uint32_t *
> -       u32_strcpy (uint32_t *dest, const uint32_t *src);
> +       u32_strcpy (uint32_t * restrict dest, const uint32_t *src);
>  
>  /* Copy SRC to DEST, returning the address of the terminating NUL in DEST.  */
>  /* Similar to stpcpy().  */
>  extern uint8_t *
> -       u8_stpcpy (uint8_t *dest, const uint8_t *src);
> +       u8_stpcpy (uint8_t * restrict dest, const uint8_t *src);
>  extern uint16_t *
> -       u16_stpcpy (uint16_t *dest, const uint16_t *src);
> +       u16_stpcpy (uint16_t * restrict dest, const uint16_t *src);
>  extern uint32_t *
> -       u32_stpcpy (uint32_t *dest, const uint32_t *src);
> +       u32_stpcpy (uint32_t * restrict dest, const uint32_t *src);
>  
>  /* Copy no more than N units of SRC to DEST.  */
>  /* Similar to strncpy(), wcsncpy().  */
>  extern uint8_t *
> -       u8_strncpy (uint8_t *dest, const uint8_t *src, size_t n);
> +       u8_strncpy (uint8_t * restrict dest, const uint8_t *src, size_t n);
>  extern uint16_t *
> -       u16_strncpy (uint16_t *dest, const uint16_t *src, size_t n);
> +       u16_strncpy (uint16_t * restrict dest, const uint16_t *src, size_t n);
>  extern uint32_t *
> -       u32_strncpy (uint32_t *dest, const uint32_t *src, size_t n);
> +       u32_strncpy (uint32_t * restrict dest, const uint32_t *src, size_t n);
>  
>  /* Copy no more than N units of SRC to DEST.  Return a pointer past the last
>     non-NUL unit written into DEST.  */
>  /* Similar to stpncpy().  */
>  extern uint8_t *
> -       u8_stpncpy (uint8_t *dest, const uint8_t *src, size_t n);
> +       u8_stpncpy (uint8_t * restrict dest, const uint8_t *src, size_t n);
>  extern uint16_t *
> -       u16_stpncpy (uint16_t *dest, const uint16_t *src, size_t n);
> +       u16_stpncpy (uint16_t * restrict dest, const uint16_t *src, size_t n);
>  extern uint32_t *
> -       u32_stpncpy (uint32_t *dest, const uint32_t *src, size_t n);
> +       u32_stpncpy (uint32_t * restrict dest, const uint32_t *src, size_t n);
>  
>  /* Append SRC onto DEST.  */
>  /* Similar to strcat(), wcscat().  */
>  extern uint8_t *
> -       u8_strcat (uint8_t *dest, const uint8_t *src);
> +       u8_strcat (uint8_t * restrict dest, const uint8_t *src);
>  extern uint16_t *
> -       u16_strcat (uint16_t *dest, const uint16_t *src);
> +       u16_strcat (uint16_t * restrict dest, const uint16_t *src);
>  extern uint32_t *
> -       u32_strcat (uint32_t *dest, const uint32_t *src);
> +       u32_strcat (uint32_t * restrict dest, const uint32_t *src);
>  
>  /* Append no more than N units of SRC onto DEST.  */
>  /* Similar to strncat(), wcsncat().  */
>  extern uint8_t *
> -       u8_strncat (uint8_t *dest, const uint8_t *src, size_t n);
> +       u8_strncat (uint8_t * restrict dest, const uint8_t *src, size_t n);
>  extern uint16_t *
> -       u16_strncat (uint16_t *dest, const uint16_t *src, size_t n);
> +       u16_strncat (uint16_t * restrict dest, const uint16_t *src, size_t n);
>  extern uint32_t *
> -       u32_strncat (uint32_t *dest, const uint32_t *src, size_t n);
> +       u32_strncat (uint32_t * restrict dest, const uint32_t *src, size_t n);
>  
>  /* Compare S1 and S2.  */
>  /* Similar to strcmp(), wcscmp().  */
> @@ -732,11 +732,14 @@ extern bool
>     This interface is actually more similar to wcstok than to strtok.  */
>  /* Similar to strtok_r(), wcstok().  */
>  extern uint8_t *
> -       u8_strtok (uint8_t *str, const uint8_t *delim, uint8_t **ptr);
> +       u8_strtok (uint8_t * restrict str, const uint8_t *delim,
> +                  uint8_t **ptr);
>  extern uint16_t *
> -       u16_strtok (uint16_t *str, const uint16_t *delim, uint16_t **ptr);
> +       u16_strtok (uint16_t * restrict str, const uint16_t *delim,
> +                   uint16_t **ptr);
>  extern uint32_t *
> -       u32_strtok (uint32_t *str, const uint32_t *delim, uint32_t **ptr);
> +       u32_strtok (uint32_t * restrict str, const uint32_t *delim,
> +                   uint32_t **ptr);
>  
>  
>  #ifdef __cplusplus
> diff --git a/lib/uniwbrk.in.h b/lib/uniwbrk.in.h
> index 1407644..940ae7d 100644
> --- a/lib/uniwbrk.in.h
> +++ b/lib/uniwbrk.in.h
> @@ -81,7 +81,7 @@ extern void
>  extern void
>         u32_wordbreaks (const uint32_t *s, size_t n, char *p);
>  extern void
> -       ulc_wordbreaks (const char *s, size_t n, char *p);
> +       ulc_wordbreaks (const char *s, size_t n, char * restrict p);
>  
>  /* ========================================================================= */
>  
> diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h
> index 345e6a8..58b9912 100644
> --- a/lib/vasnprintf.h
> +++ b/lib/vasnprintf.h
> @@ -67,9 +67,11 @@ extern "C" {
>  # define asnprintf rpl_asnprintf
>  # define vasnprintf rpl_vasnprintf
>  #endif
> -extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
> +extern char * asnprintf (char * restrict resultbuf, size_t *lengthp,
> +                         const char *format, ...)
>         _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
> -extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
> +extern char * vasnprintf (char * restrict resultbuf, size_t *lengthp,
> +                          const char *format, va_list args)
>         _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
>  
>  #ifdef __cplusplus
> diff --git a/lib/wchar.in.h b/lib/wchar.in.h
> index 74cd670..16f9d6c 100644
> --- a/lib/wchar.in.h
> +++ b/lib/wchar.in.h
> @@ -547,10 +547,10 @@ _GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - "
>  #if @GNULIB_WMEMCPY@
>  # if !@HAVE_WMEMCPY@
>  _GL_FUNCDECL_SYS (wmemcpy, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # endif
>  _GL_CXXALIAS_SYS (wmemcpy, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wmemcpy);
>  # endif
> @@ -640,9 +640,11 @@ _GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - "
>  /* Copy SRC to DEST.  */
>  #if @GNULIB_WCSCPY@
>  # if !@HAVE_WCSCPY@
> -_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
> +_GL_FUNCDECL_SYS (wcscpy, wchar_t *,
> +                  (wchar_t * restrict dest, const wchar_t *src));
>  # endif
> -_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
> +_GL_CXXALIAS_SYS (wcscpy, wchar_t *,
> +                  (wchar_t * restrict dest, const wchar_t *src));
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wcscpy);
>  # endif
> @@ -658,9 +660,11 @@ _GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - "
>  /* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST.  */
>  #if @GNULIB_WCPCPY@
>  # if !@HAVE_WCPCPY@
> -_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
> +_GL_FUNCDECL_SYS (wcpcpy, wchar_t *,
> +                  (wchar_t * restrict dest, const wchar_t *src));
>  # endif
> -_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
> +_GL_CXXALIAS_SYS (wcpcpy, wchar_t *,
> +                  (wchar_t * restrict dest, const wchar_t *src));
>  _GL_CXXALIASWARN (wcpcpy);
>  #elif defined GNULIB_POSIXCHECK
>  # undef wcpcpy
> @@ -675,10 +679,10 @@ _GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - "
>  #if @GNULIB_WCSNCPY@
>  # if !@HAVE_WCSNCPY@
>  _GL_FUNCDECL_SYS (wcsncpy, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # endif
>  _GL_CXXALIAS_SYS (wcsncpy, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wcsncpy);
>  # endif
> @@ -696,10 +700,10 @@ _GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - "
>  #if @GNULIB_WCPNCPY@
>  # if !@HAVE_WCPNCPY@
>  _GL_FUNCDECL_SYS (wcpncpy, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # endif
>  _GL_CXXALIAS_SYS (wcpncpy, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  _GL_CXXALIASWARN (wcpncpy);
>  #elif defined GNULIB_POSIXCHECK
>  # undef wcpncpy
> @@ -713,9 +717,11 @@ _GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - "
>  /* Append SRC onto DEST.  */
>  #if @GNULIB_WCSCAT@
>  # if !@HAVE_WCSCAT@
> -_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src));
> +_GL_FUNCDECL_SYS (wcscat, wchar_t *,
> +                  (wchar_t * restrict dest, const wchar_t *src));
>  # endif
> -_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src));
> +_GL_CXXALIAS_SYS (wcscat, wchar_t *,
> +                  (wchar_t * restrict dest, const wchar_t *src));
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wcscat);
>  # endif
> @@ -732,10 +738,10 @@ _GL_WARN_ON_USE (wcscat, "wcscat is unportable - "
>  #if @GNULIB_WCSNCAT@
>  # if !@HAVE_WCSNCAT@
>  _GL_FUNCDECL_SYS (wcsncat, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # endif
>  _GL_CXXALIAS_SYS (wcsncat, wchar_t *,
> -                  (wchar_t *dest, const wchar_t *src, size_t n));
> +                  (wchar_t * restrict dest, const wchar_t *src, size_t n));
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wcsncat);
>  # endif
> @@ -848,9 +854,11 @@ _GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - "
>     original strings.  */
>  #if @GNULIB_WCSXFRM@
>  # if !@HAVE_WCSXFRM@
> -_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n));
> +_GL_FUNCDECL_SYS (wcsxfrm, size_t,
> +                  (wchar_t * restrict s1, const wchar_t *s2, size_t n));
>  # endif
> -_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n));
> +_GL_CXXALIAS_SYS (wcsxfrm, size_t,
> +                  (wchar_t * restrict s1, const wchar_t *s2, size_t n));
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wcsxfrm);
>  # endif
> @@ -1053,16 +1061,20 @@ _GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - "
>  #   define wcstok rpl_wcstok
>  #  endif
>  _GL_FUNCDECL_RPL (wcstok, wchar_t *,
> -                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
> +                  (wchar_t * restrict wcs, const wchar_t *delim,
> +                   wchar_t **ptr));
>  _GL_CXXALIAS_RPL (wcstok, wchar_t *,
> -                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
> +                  (wchar_t * restrict wcs, const wchar_t *delim,
> +                   wchar_t **ptr));
>  # else
>  #  if !@HAVE_WCSTOK@
>  _GL_FUNCDECL_SYS (wcstok, wchar_t *,
> -                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
> +                  (wchar_t * restrict wcs, const wchar_t *delim,
> +                   wchar_t **ptr));
>  #  endif
>  _GL_CXXALIAS_SYS (wcstok, wchar_t *,
> -                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
> +                  (wchar_t * restrict wcs, const wchar_t *delim,
> +                   wchar_t **ptr));
>  # endif
>  # if __GLIBC__ >= 2
>  _GL_CXXALIASWARN (wcstok);
> @@ -1114,18 +1126,18 @@ _GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - "
>  #   undef wcsftime
>  #   define wcsftime rpl_wcsftime
>  #  endif
> -_GL_FUNCDECL_RPL (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
> +_GL_FUNCDECL_RPL (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
>                                       const wchar_t *__fmt, const struct tm *__tp)
>                                      _GL_ARG_NONNULL ((1, 3, 4)));
> -_GL_CXXALIAS_RPL (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
> +_GL_CXXALIAS_RPL (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
>                                       const wchar_t *__fmt, const struct tm *__tp));
>  # else
>  #  if !@HAVE_WCSFTIME@
> -_GL_FUNCDECL_SYS (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
> +_GL_FUNCDECL_SYS (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
>                                       const wchar_t *__fmt, const struct tm *__tp)
>                                      _GL_ARG_NONNULL ((1, 3, 4)));
>  #  endif
> -_GL_CXXALIAS_SYS (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
> +_GL_CXXALIAS_SYS (wcsftime, size_t, (wchar_t * restrict __buf, size_t __bufsize,
>                                       const wchar_t *__fmt, const struct tm *__tp));
>  # endif
>  # if __GLIBC__ >= 2
> diff --git a/lib/xmemcoll.h b/lib/xmemcoll.h
> index 4170b9b..ea546b8 100644
> --- a/lib/xmemcoll.h
> +++ b/lib/xmemcoll.h
> @@ -1,3 +1,3 @@
>  #include <stddef.h>
> -int xmemcoll (char *, size_t, char *, size_t);
> +int xmemcoll (char * restrict, size_t, char * restrict, size_t);
>  int xmemcoll0 (char const *, size_t, char const *, size_t);
> 
> 
> 


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-10  3:02   ` restrict Bruno Haible
  2020-02-10  8:39     ` restrict Jeffrey Walton
  2020-02-10 10:11     ` restrict Tim Rühsen
@ 2020-02-16 21:44     ` Paul Eggert
  2020-02-16 23:49       ` restrict Bruno Haible
  2020-02-17 21:19     ` restrict - summary Bruno Haible
  3 siblings, 1 reply; 20+ messages in thread
From: Paul Eggert @ 2020-02-16 21:44 UTC (permalink / raw)
  To: Bruno Haible, bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

On 2/9/20 7:02 PM, Bruno Haible wrote:

>    - If all pointer parameters point to different types, excluding 'void *',
>      ISO C forbids aliasing anyway, therefore 'restrict' is redundant.

The actual ISO C rule is a bit different, since it allows aliasing between 'char 
*', 'unsigned char *', 'signed char *', and the other types.  This means one 
must use 'restrict' when some pointers are 'char *' and others are not. For example:

   FILE *freopen(const char *restrict pathname, const char *restrict mode,
        FILE *restrict stream);

The same rule applies when a type *might* cause problems. For example:

   int readdir_r(DIR *restrict dirp, struct dirent *restrict entry,
        struct dirent **restrict result);

because DIR might be either 'char' or 'struct dirent' (weird, but allowable).

>   - If, among the parameters, there are N parameters of type
>       [const] TYPE *
>     adding the 'restrict' keyword to N-1 of them is equivalent to adding
>     the 'restrict' keyword to all N of them.

It won't be equivalent in general, because if the function accesses nonlocal 
variables the compiler can't be sure they won't alias with the Nth parameter. We 
should add 'restrict' to all N args, as POSIX does.

>      Example: void dfacomp (char const *, ptrdiff_t, struct dfa *, bool);
>      and https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html

In glob.html, 'glob' has 'restrict' on both data pointer args, so it's not an 
example of this principle. 'globfree' does not have 'restrict' for the same 
reason 'free' does not have 'restrict' - freers are not supposed to rely on 
noaliasing optimizations.

>    - If a function has an input parameter of type
>        const TYPE *
>      and an output parameter of type
>        TYPE *
>      then the 'restrict' keyword means that the implementation may write
>      the output before having finished reading all the input.
>      Example:
>        void arctwo_encrypt (arctwo_context *context, const char *inbuf,
>                             char * restrict outbuf, size_t length);
>      Whereas the absence of the 'restrict' keyword means that the
>      implementation will read all the input _before_ starting to store
>      the output.
>      Example:
>        int hmac_md5 (const void *key, size_t keylen,
>                      const void *buffer, size_t buflen, void *resbuf);

Yes and no. By "the implementation" do you mean the C code that implements these 
functions with the usual naive interpretation of that C code? or do you mean the 
optimized version of the C code? If the latter, I don't think I agree. If the 
former, I'm not sure -- but why focus on the former?

Anyway, for hmac_md5 I would think 'restrict' would also be appropriate, as we 
don't want to preclude an implementation that double-checks the result.

>    - 'restrict' should NOT be used for multiple output parameters of the
>      same type, when only a single word is written through each parameter.
>      Example: ssize_t copy_file_range (int ifd, off_t *ipos, int ofd, off_t *opos,
>                                        size_t len, unsigned flags);
>      Rationale: It is OK to have ipos and opos point to different elements
>      of the same off_t[] array.

Ouch, this is exactly the opposite of what I would have wanted, since I want 
'restrict' to tell the caller "these should not be aliases" and I want that to 
be true for *IPOS and *OPOS.  (I'm not sure what is meant by 'single word' here; 
surely it shouldn't matter whether the type is a struct....) Could you explain 
more where the 'same array' rule comes from?

> -extern char * astrxfrm (const char *s, char *resultbuf, size_t *lengthp);
> +extern char * astrxfrm (const char *s,
> +                        char * restrict resultbuf, size_t *lengthp);

I'd expect 'restrict' on all three pointer args. strxfrm has 'restrict' on both 
its args.

I didn't look at all the decls in details, but I expect you'll want more 
'restrict's in there.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-16 21:44     ` restrict Paul Eggert
@ 2020-02-16 23:49       ` Bruno Haible
  2020-02-17  0:14         ` restrict Bruno Haible
  2020-02-17 18:03         ` restrict Paul Eggert
  0 siblings, 2 replies; 20+ messages in thread
From: Bruno Haible @ 2020-02-16 23:49 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

Hi Paul,

Thanks a lot for your comments.

> >    - If all pointer parameters point to different types, excluding 'void *',
> >      ISO C forbids aliasing anyway, therefore 'restrict' is redundant.
> 
> The actual ISO C rule is a bit different, since it allows aliasing between 'char 
> *', 'unsigned char *', 'signed char *', and the other types.  This means one 
> must use 'restrict' when some pointers are 'char *' and others are not. For example:
> 
>    FILE *freopen(const char *restrict pathname, const char *restrict mode,
>         FILE *restrict stream);
> 
> The same rule applies when a type *might* cause problems. For example:
> 
>    int readdir_r(DIR *restrict dirp, struct dirent *restrict entry,
>         struct dirent **restrict result);
> 
> because DIR might be either 'char' or 'struct dirent' (weird, but allowable).

This is true, when someone wants to use 'restrict' for optimization, to save
a machine instruction here and there.

I'm after warnings that point to undefined behaviour, and since passing a
'char *' in place of an 'unsigned char *', 'FILE *', or similar already
generates a compiler warning, using 'restrict' here does not offer an
advantage.

Example:
================================
#include <stdio.h>
char *str;
int main ()
{
  freopen (str, "w", str);
}
================================
produces (with "gcc -Wall"):

foo.c: In function ‘main’:
foo.c:5:22: warning: passing argument 3 of ‘freopen’ from incompatible pointer type [-Wincompatible-pointer-types]

> >   - If, among the parameters, there are N parameters of type
> >       [const] TYPE *
> >     adding the 'restrict' keyword to N-1 of them is equivalent to adding
> >     the 'restrict' keyword to all N of them.
> 
> It won't be equivalent in general, because if the function accesses nonlocal 
> variables the compiler can't be sure they won't alias with the Nth parameter. We 
> should add 'restrict' to all N args, as POSIX does.

Again, this is true for optimization purposes, but not needed for warning
purposes. In functions with variadic arguments, for example

  int snprintf (char *str, size_t size, const char *format, ...);

we can express the fact the 4th, 5th, etc. arguments should not overlap
with the first argument *only* by adding 'restrict' to the first parameter.
And since 'restrict' on the first parameter is going to signal a warning
for overlaps with the 3rd, 4th, 5th, ... parameter, we don't need 'restrict'
on the 3rd parameter.

> >      Example: void dfacomp (char const *, ptrdiff_t, struct dfa *, bool);
> >      and https://pubs.opengroup.org/onlinepubs/9699919799/functions/glob.html
> 
> In glob.html, 'glob' has 'restrict' on both data pointer args, so it's not an 
> example of this principle.

But for the caller, it does not make a difference whether 'glob' is declared
as
      int glob (const char *restrict pattern, ..., glob_t *restrict pglob);
or as
      int glob (const char *         pattern, ..., glob_t *restrict pglob);

If the implementation of 'glob' is writing to a global variable, and I happen
to pass a pointer to this variable as the first argument - this is the case
which could produce undefined behaviour -, the compiler cannot give me a
warning about it because it's not written in the glob.h file which global
variables the function may access. So, for warning purposes, 'restrict'
on the first parameter is redundant.

> >    - If a function has an input parameter of type
> >        const TYPE *
> >      and an output parameter of type
> >        TYPE *
> >      then the 'restrict' keyword means that the implementation may write
> >      the output before having finished reading all the input.
> >      Example:
> >        void arctwo_encrypt (arctwo_context *context, const char *inbuf,
> >                             char * restrict outbuf, size_t length);
> >      Whereas the absence of the 'restrict' keyword means that the
> >      implementation will read all the input _before_ starting to store
> >      the output.
> >      Example:
> >        int hmac_md5 (const void *key, size_t keylen,
> >                      const void *buffer, size_t buflen, void *resbuf);
> 
> Yes and no. By "the implementation" do you mean the C code that implements these 
> functions with the usual naive interpretation of that C code? or do you mean the 
> optimized version of the C code? If the latter, I don't think I agree. If the 
> former, I'm not sure -- but why focus on the former?

I mean any possible implementation, compiled from the code we have in gnulib.
'restrict' is part of the contract between the caller of the function and the
implementation of the function. When the compiler optimizes the implementation,
it has to stick to the contract.

> Anyway, for hmac_md5 I would think 'restrict' would also be appropriate, as we 
> don't want to preclude an implementation that double-checks the result.

Excellent point! If a function is declared with 'restrict', the implementor
may add debugging code at the end, e.g. that prints the values of the arguments.
Whereas if a function is declared without 'restrict', the caller may pass
pointers to overlapping memory areas, thus such debugging code would not work.

> >    - 'restrict' should NOT be used for multiple output parameters of the
> >      same type, when only a single word is written through each parameter.
> >      Example: ssize_t copy_file_range (int ifd, off_t *ipos, int ofd, off_t *opos,
> >                                        size_t len, unsigned flags);
> >      Rationale: It is OK to have ipos and opos point to different elements
> >      of the same off_t[] array.
> 
> Ouch, this is exactly the opposite of what I would have wanted, since I want 
> 'restrict' to tell the caller "these should not be aliases" and I want that to 
> be true for *IPOS and *OPOS.  (I'm not sure what is meant by 'single word' here; 
> surely it shouldn't matter whether the type is a struct....) Could you explain 
> more where the 'same array' rule comes from?

The "same array" rule comes from what I understood from various explanations
of 'restrict' on the web [1], and from what I see in the glibc headers for
functions that have multiple output parameters of the same type:
  - splice in <bits/fcntl-linux.h>,
  - printf_arginfo_size_function in <printf.h>,
  - openpty in <pty.h>,
  - re_set_registers in <regex.h>,
  - copy_file_range in <unistd.h>.
But ecvt, fcvt in <stdlib.h> have 'restrict'. You may want to register a glibc
bug if you think these five functions should have 'restrict' :)

Bruno

[1] https://stackoverflow.com/questions/745870/realistic-usage-of-the-c99-restrict-keyword



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-16 23:49       ` restrict Bruno Haible
@ 2020-02-17  0:14         ` Bruno Haible
  2020-02-17  2:46           ` restrict Paul Eggert
  2020-02-17 18:03         ` restrict Paul Eggert
  1 sibling, 1 reply; 20+ messages in thread
From: Bruno Haible @ 2020-02-17  0:14 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

Addendum:
> > >    - 'restrict' should NOT be used for multiple output parameters of the
> > >      same type, when only a single word is written through each parameter.
> > >      Example: ssize_t copy_file_range (int ifd, off_t *ipos, int ofd, off_t *opos,
> > >                                        size_t len, unsigned flags);
> > >      Rationale: It is OK to have ipos and opos point to different elements
> > >      of the same off_t[] array.
> > 
> > Ouch, this is exactly the opposite of what I would have wanted, since I want 
> > 'restrict' to tell the caller "these should not be aliases" and I want that to 
> > be true for *IPOS and *OPOS.  (I'm not sure what is meant by 'single word' here; 
> > surely it shouldn't matter whether the type is a struct....) Could you explain 
> > more where the 'same array' rule comes from?
> 
> The "same array" rule comes from what I understood from various explanations
> of 'restrict' on the web [1], and from what I see in the glibc headers for
> functions that have multiple output parameters of the same type

Also, I thought that passing pointers to different elements of the same array
would produce warnings. But I was mistaken: This code does NOT produce warnings.

================================================================================
#include <stddef.h>
extern int copy_file_range (int, long *restrict, int, long *restrict, size_t, unsigned int);

int infd;
int outfd;
long offsets[2];

int copy_block (void)
{
  return copy_file_range (infd, &offsets[0], outfd, &offsets[1], 4096, 0);
}
================================================================================

Bruno



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-17  0:14         ` restrict Bruno Haible
@ 2020-02-17  2:46           ` Paul Eggert
  2020-02-17  3:53             ` restrict Bruno Haible
  0 siblings, 1 reply; 20+ messages in thread
From: Paul Eggert @ 2020-02-17  2:46 UTC (permalink / raw)
  To: Bruno Haible; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

On 2/16/20 4:14 PM, Bruno Haible wrote:
> I thought that passing pointers to different elements of the same array
> would produce warnings. But I was mistaken: This code does NOT produce warnings.

Yes, and I don't see why such code has undefined behavior, as long as the 
function doesn't actually access aliased elements in the same array. That is, if 
GCC generated warnings for that sort of thing, the warnings would be false alarms.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-17  2:46           ` restrict Paul Eggert
@ 2020-02-17  3:53             ` Bruno Haible
  2020-02-17  9:51               ` restrict Tim Rühsen
  0 siblings, 1 reply; 20+ messages in thread
From: Bruno Haible @ 2020-02-17  3:53 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

Paul Eggert wrote:
> if GCC generated warnings for that sort of thing, the warnings would be false
> alarms.

Yes, and this in turn means that the ability to produce useful warnings via
'restrict' is limited. In this example:
===================================================================
#include <string.h>
extern void memmcpy (void *restrict, const void *restrict, size_t);

void shuffle (char array[10])
{
  memmcpy (array + 2, array, 8);
  memcpy (array + 2, array, 8);
}
===================================================================
gcc gives no warning about 'memmcpy' - because it does not know
how many elements the function will access. gcc does give a warning
about 'memcpy' - apparently due to custom logic in the compiler.

Bruno



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-17  3:53             ` restrict Bruno Haible
@ 2020-02-17  9:51               ` Tim Rühsen
  2020-02-17 21:03                 ` restrict Bruno Haible
  0 siblings, 1 reply; 20+ messages in thread
From: Tim Rühsen @ 2020-02-17  9:51 UTC (permalink / raw)
  To: Bruno Haible, Paul Eggert; +Cc: Mats Erik Andersson, bug-gnulib


[-- Attachment #1.1: Type: text/plain, Size: 1536 bytes --]

On 2/17/20 4:53 AM, Bruno Haible wrote:
> Paul Eggert wrote:
>> if GCC generated warnings for that sort of thing, the warnings would be false
>> alarms.
> 
> Yes, and this in turn means that the ability to produce useful warnings via
> 'restrict' is limited. In this example:
> ===================================================================
> #include <string.h>
> extern void memmcpy (void *restrict, const void *restrict, size_t);
> 
> void shuffle (char array[10])
> {
>   memmcpy (array + 2, array, 8);
>   memcpy (array + 2, array, 8);
> }
> ===================================================================
> gcc gives no warning about 'memmcpy' - because it does not know
> how many elements the function will access. gcc does give a warning
> about 'memcpy' - apparently due to custom logic in the compiler.

The following gives you a warning, with -O2 / -O3 and -Wall:

===================================================================
#include <string.h>
void memmcpy (void *restrict d, void *restrict s, size_t n)
{
  memcpy(d, s, n);
}

void shuffle ()
{
  char array[] = "abcdefg", *array2 = array + 2;

  memmcpy (array, array2 - 2, 8);
}
===================================================================

$ gcc-8 -O2 -Wall x.c
In function ‘memmcpy’,
    inlined from ‘shuffle’ at x.c:11:3:
x.c:4:3: warning: ‘memcpy’ accessing 8 bytes at offsets 0 and 0 overlaps
8 bytes at offset 0 [-Wrestrict]
   memcpy(d, s, n);
   ^~~~~~~~~~~~~~~

Regards, Tim


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-16 23:49       ` restrict Bruno Haible
  2020-02-17  0:14         ` restrict Bruno Haible
@ 2020-02-17 18:03         ` Paul Eggert
  2020-02-17 20:55           ` restrict Bruno Haible
  1 sibling, 1 reply; 20+ messages in thread
From: Paul Eggert @ 2020-02-17 18:03 UTC (permalink / raw)
  To: Bruno Haible; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

On 2/16/20 3:49 PM, Bruno Haible wrote:

> I'm after warnings that point to undefined behaviour, and since passing a
> 'char *' in place of an 'unsigned char *', 'FILE *', or similar already
> generates a compiler warning, using 'restrict' here does not offer an
> advantage.

It can still offer an advantage, since GCC doesn't necessarily generate a 
compiler warning without the 'restrict'. For example, in the following code GCC 
complains about the call to f but not the call to g:

   void f (char *restrict, int *restrict);
   void g (char *, int *);

   int
   main (void)
   {
     int	a[] = {0, 0, 0};
     void *p = a;
     f (p, p);
     g (p, p);
   }

More generally, the role of 'restrict' for optimizations can't be easily 
separated from its role for warnings. Using 'restrict' to save machine 
instructions also means that it's better for GCC to generate warnings when the 
behavior would otherwise be undefined; conversely, typically when GCC generates 
warnings it's free to optimize more. Because of this close connection, when in 
doubt it's better to use 'restrict' in a way that benefits optimization as well 
as warning.

>    int snprintf (char *str, size_t size, const char *format, ...);
> ... since 'restrict' on the first parameter is going to signal a warning
> for overlaps with the 3rd, 4th, 5th, ... parameter, we don't need 'restrict'
> on the 3rd parameter.

If we omit 'restrict' from the 3rd parameter, GCC won't warn when the 3rd 
parameter overlaps with the 4th. That's a minus.

> I mean any possible implementation, compiled from the code we have in gnulib.
> 'restrict' is part of the contract between the caller of the function and the
> implementation of the function. When the compiler optimizes the implementation,
> it has to stick to the contract.

This sounds backwards. Ordinarily (without restrict) there is a contract that 
prevents the compiler from optimizing the implementation in certain ways. With 
restrict, that part of the contract goes away. From the programmer's point of 
view, 'restrict' places additional restrictions on the caller, not on the 
callee. And appropriate use of 'restrict' signals to programmers what the callee 
can do. This signal to humans is useful regardless of whether tools like GCC use 
the signal to generate warnings or optimizations.
> The "same array" rule comes from what I understood from various explanations
> of 'restrict' on the web [1], and from what I see in the glibc headers for
> functions that have multiple output parameters of the same type:
>    - splice in <bits/fcntl-linux.h>,
>    - printf_arginfo_size_function in <printf.h>,
>    - openpty in <pty.h>,
>    - re_set_registers in <regex.h>,
>    - copy_file_range in <unistd.h>.

That stackoverflow explanation is full of confusing answers and none of them are 
particularly good. And the glibc headers evidently were not written by people 
who cared about proper use of 'restrict' (possibly because they wrote the 
headers before 'restrict' existed or was widely supported).

> But ecvt, fcvt in <stdlib.h> have 'restrict'. You may want to register a glibc
> bug if you think these five functions should have 'restrict' :)

It's not a bug. It's required by POSIX (which uses 'restrict' more carefully) in 
its older editions. See:

https://pubs.opengroup.org/onlinepubs/009695399/functions/ecvt.html

The functions in questions have been withdrawn from POSIX; if they had not been, 
the 'restrict's would still be there.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-17 18:03         ` restrict Paul Eggert
@ 2020-02-17 20:55           ` Bruno Haible
  2020-02-17 22:28             ` restrict Paul Eggert
  0 siblings, 1 reply; 20+ messages in thread
From: Bruno Haible @ 2020-02-17 20:55 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

Hi Paul,

> > I'm after warnings that point to undefined behaviour, and since passing a
> > 'char *' in place of an 'unsigned char *', 'FILE *', or similar already
> > generates a compiler warning, using 'restrict' here does not offer an
> > advantage.
> 
> It can still offer an advantage, since GCC doesn't necessarily generate a 
> compiler warning without the 'restrict'. For example, in the following code GCC 
> complains about the call to f but not the call to g:
> 
>    void f (char *restrict, int *restrict);
>    void g (char *, int *);
> 
>    int
>    main (void)
>    {
>      int	a[] = {0, 0, 0};
>      void *p = a;
>      f (p, p);
>      g (p, p);
>    }

True. But it's pretty rare that people use 'void *' pointers and cast them
to pointers of different types.

Also, even a small variation of this code does not produce a warning any more:

   void f (char *restrict, int *restrict);
   void g (char *, int *);

   int
   main (void)
   {
     int        a[] = {0, 0, 0};
     void *p = a;
     f (p, a);    // no warning!
     g (p, a);
   }

> More generally, the role of 'restrict' for optimizations can't be easily 
> separated from its role for warnings. Using 'restrict' to save machine 
> instructions also means that it's better for GCC to generate warnings when the 
> behavior would otherwise be undefined; conversely, typically when GCC generates 
> warnings it's free to optimize more. Because of this close connection, when in 
> doubt it's better to use 'restrict' in a way that benefits optimization as well 
> as warning.

It needs to be weighed against the desire not to produce warnings for valid
uses. For example here:

> >    int snprintf (char *str, size_t size, const char *format, ...);
> > ... since 'restrict' on the first parameter is going to signal a warning
> > for overlaps with the 3rd, 4th, 5th, ... parameter, we don't need 'restrict'
> > on the 3rd parameter.
> 
> If we omit 'restrict' from the 3rd parameter, GCC won't warn when the 3rd 
> parameter overlaps with the 4th. That's a minus.

Actually, GCC doesn't warn here, even with 'restrict', because the 3rd argument
is a const-pointer and the 4th argument, being variadic, is treated like a
const-pointer as well. Test case (enable one of the declarations):

#include <stddef.h>
//extern int smprintf (char *restrict, size_t, char *, ...);                                // no warning
//extern int smprintf (char *restrict, size_t, char *restrict, ...);                        // warning
//extern int smprintf (char *restrict, size_t, const char *, ...);                          // no warning
//extern int smprintf (char *restrict, size_t, const char *restrict, ...);                  // no warning
//extern int smprintf (char *restrict, size_t, const char *restrict, char *restrict);       // warning
//extern int smprintf (char *restrict, size_t, const char *restrict, const char *restrict); // no warning

char buf[10];
int main ()
{
  char fmt[] = "%s";
  smprintf (buf, sizeof buf, fmt, fmt);
}

> This sounds backwards. Ordinarily (without restrict) there is a contract that 
> prevents the compiler from optimizing the implementation in certain ways. With 
> restrict, that part of the contract goes away. From the programmer's point of 
> view, 'restrict' places additional restrictions on the caller, not on the 
> callee. And appropriate use of 'restrict' signals to programmers what the callee 
> can do.

I agree.

> This signal to humans is useful regardless of whether tools like GCC use 
> the signal to generate warnings or optimizations.

I disagree. Given the confusion around what 'restrict' is actually about,
the "signal to humans" is fuzzy. As it stands, GCC >= 8 is the best bet for
a programmer to understand 'restrict'.

> > The "same array" rule comes from what I understood from various explanations
> > of 'restrict' on the web [1], and from what I see in the glibc headers for
> > functions that have multiple output parameters of the same type:
> >    - splice in <bits/fcntl-linux.h>,
> >    - printf_arginfo_size_function in <printf.h>,
> >    - openpty in <pty.h>,
> >    - re_set_registers in <regex.h>,
> >    - copy_file_range in <unistd.h>.
> 
> That stackoverflow explanation is full of confusing answers and none of them are 
> particularly good. And the glibc headers evidently were not written by people 
> who cared about proper use of 'restrict' (possibly because they wrote the 
> headers before 'restrict' existed or was widely supported).

... possibly also because ISO C 99 § 6.7.3.1 is impenetrable.
... possibly also because GCC 8 was not around to teach the programmers.

> > But ecvt, fcvt in <stdlib.h> have 'restrict'. You may want to register a glibc
> > bug if you think these five functions should have 'restrict' :)
> 
> It's not a bug. It's required by POSIX (which uses 'restrict' more carefully) in 
> its older editions. See:
> 
> https://pubs.opengroup.org/onlinepubs/009695399/functions/ecvt.html

I meant the "glibc bug" the other way around: Someone could tell the glibc people
that it makes sense to _add_ 'restrict' to the declarations of splice,
printf_arginfo_size_function, openpty, re_set_registers, copy_file_range.

Bruno



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-17  9:51               ` restrict Tim Rühsen
@ 2020-02-17 21:03                 ` Bruno Haible
  0 siblings, 0 replies; 20+ messages in thread
From: Bruno Haible @ 2020-02-17 21:03 UTC (permalink / raw)
  To: Tim Rühsen; +Cc: Paul Eggert, bug-gnulib, Mats Erik Andersson

Hi Tim,

> > Yes, and this in turn means that the ability to produce useful warnings via
> > 'restrict' is limited. In this example:
> > ===================================================================
> > #include <string.h>
> > extern void memmcpy (void *restrict, const void *restrict, size_t);
> > 
> > void shuffle (char array[10])
> > {
> >   memmcpy (array + 2, array, 8);
> >   memcpy (array + 2, array, 8);
> > }
> > ===================================================================
> > gcc gives no warning about 'memmcpy' - because it does not know
> > how many elements the function will access. gcc does give a warning
> > about 'memcpy' - apparently due to custom logic in the compiler.
> 
> The following gives you a warning, with -O2 / -O3 and -Wall:
> 
> ===================================================================
> #include <string.h>
> void memmcpy (void *restrict d, void *restrict s, size_t n)
> {
>   memcpy(d, s, n);
> }
> 
> void shuffle ()
> {
>   char array[] = "abcdefg", *array2 = array + 2;
> 
>   memmcpy (array, array2 - 2, 8);
> }
> ===================================================================

That's precisely my point: GCC can not and will not give you warnings
about overlapping array slices, unless the function is one of the
predefined functions (memcpy in this case).

'restrict' for optimization is designed for accesses to array (cf.
the many examples regarding loops that iterate over an array). But
the warnings emitted by GCC can only recognize the special case of
two pointers being equal.

Bruno



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict - summary
  2020-02-10  3:02   ` restrict Bruno Haible
                       ` (2 preceding siblings ...)
  2020-02-16 21:44     ` restrict Paul Eggert
@ 2020-02-17 21:19     ` Bruno Haible
  2020-02-22 22:51       ` Bruno Haible
                         ` (2 more replies)
  3 siblings, 3 replies; 20+ messages in thread
From: Bruno Haible @ 2020-02-17 21:19 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

Thanks to Paul and all for the enlightening discussion about what 'restrict'
actually means.

What I intend to do it gnulib is:

  * In the function *definitions*, do not use 'restrict' at all.

    Rationale:
      - Gnulib code is not time-critical. 'restrict' enables micro-
        optimizations, at the price of undefined behaviour for some
        callers.
      - Humans have a poor understanding of what 'restrict' means,
        and the GCC warnings cover only a subset of the undefined
        behaviour situations (namely, GCC can only warn about equal
        pointers, but not about overlapping array slices).

  * In the function *declarations* for POSIX functions, I will use
    'restrict' exactly as written in POSIX.

    Rationale:
      - 'restrict' modifies the contract between the caller and the
        implementor of a function. Whatever 'restrict' precisely means,
        the contract that programmers will look at is the POSIX standard.

  * In the function *declarations* for non-POSIX functions, I will use
    'restrict' when there is a significant benefit, and only on non-const
    pointer parameters.

    Rationale:
      - I want to see useful warnings from GCC. "Useful" means: with
        the normal programming style; passing 'void *' arguments to
        functions that expect 'char *', 'FILE *', etc. is not the
        normal programming style I want to care about.
      - The semantics of 'restrict' is a bit confusing, and the semantics
        of 'restrict' on const pointer parameters is additionally confusing.
      - It is typically sufficient - both for warnings and optimization -
        to put 'restrict' on the non-const pointer parameters only.

Bruno



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict
  2020-02-17 20:55           ` restrict Bruno Haible
@ 2020-02-17 22:28             ` Paul Eggert
  0 siblings, 0 replies; 20+ messages in thread
From: Paul Eggert @ 2020-02-17 22:28 UTC (permalink / raw)
  To: Bruno Haible; +Cc: Tim Rühsen, bug-gnulib, Mats Erik Andersson

On 2/17/20 12:55 PM, Bruno Haible wrote:

> it's pretty rare that people use 'void *' pointers and cast them
> to pointers of different types.

It's not rare in some of the code I write. :-) Plus, my example had no casts.

> Also, even a small variation of this code does not produce a warning any more:

Interesting. I don't see why GCC doesn't warn there.

GCC's heuristics for generating warnings must be even trickier than what's in 
the C standard about 'restrict' - which is another reason not to base code off 
when exactly GCC warns.

> Actually, GCC doesn't warn here, even with 'restrict', because the 3rd argument
> is a const-pointer and the 4th argument, being variadic, is treated like a
> const-pointer as well.

Fair enough, but there are similar examples where 'restrict' will still be 
useful, such as if the 3rd argument is not a const-pointer.

>  Given the confusion around what 'restrict' is actually about,
> the "signal to humans" is fuzzy.

Using 'restrict' in a nonstandard way will make that signal even fuzzier. It's 
better to be systematic about it, and to use the same system that the C standard 
and POSIX do.

Like Dennis Ritchie and 'noalias'[1], I'm not a big fan of 'restrict'. But we 
have it and it's standardized and it's better to use it as intended rather than 
invent a not-quite-the-same use for it.

> I meant the "glibc bug" the other way around: Someone could tell the glibc people
> that it makes sense to _add_ 'restrict' to the declarations of splice,
> printf_arginfo_size_function, openpty, re_set_registers, copy_file_range.

Yes, that would be worth doing.

[1] https://www.lysator.liu.se/c/dmr-on-noalias.html


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: restrict - summary
  2020-02-17 21:19     ` restrict - summary Bruno Haible
@ 2020-02-22 22:51       ` Bruno Haible
  2020-02-24 19:17         ` Eric Blake
  2020-02-23 12:39       ` Bruno Haible
  2020-02-23 13:30       ` Bruno Haible
  2 siblings, 1 reply; 20+ messages in thread
From: Bruno Haible @ 2020-02-22 22:51 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

Here comes the first part: the 'restrict' in the POSIX function declarations.

Note that the POSIX declarations of posix_spawn and posix_spawnp [1] are
incorrect: They lack a 'restrict' for the file_actions argument.

[1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html


2020-02-22  Bruno Haible  <bruno@clisp.org>

	Use 'restrict' in all POSIX function declarations.
	* lib/iconv.in.h (iconv): Use 'restrict'.
	* lib/inttypes.in.h (strtoimax, strtoumax): Likewise.
	* lib/monetary.in.h (strfmon_l): Likewise.
	* lib/pthread.in.h (pthread_create, pthread_mutex_init,
	pthread_mutexattr_gettype, pthread_mutexattr_getrobust,
	pthread_mutex_timedlock, pthread_rwlock_init,
	pthread_rwlock_timedrdlock, pthread_rwlock_timedwrlock,
	pthread_cond_init, pthread_cond_wait, pthread_cond_timedwait): Likewise.
	* lib/search.in.h (tdelete): Likewise.
	* lib/signal.in.h (pthread_sigmask, sigprocmask): Likewise.
	* lib/stdio.in.h (dprintf, fgets, fopen, fprintf, fputs, fread, freopen,
	fscanf, fwrite, getdelim, getline, printf, scanf, snprintf, sprintf,
	vdprintf, vfprintf, vfscanf, vprintf, vscanf, vsnprintf, vsprintf):
	Likewise.
	* lib/stdlib.in.h (mbtowc, realpath, strtod, strtold, strtoll,
	strtoull): Likewise.
	* lib/string.in.h (strncat): Likewise.
	* lib/sys_socket.in.h (accept, getpeername, getsockname, getsockopt,
	recvfrom): Likewise.
	* lib/sys_stat.in.h (fstatat, lstat, stat): Likewise.
	* lib/time.in.h (strftime): Likewise.
	* lib/unistd.in.h (readlink, readlinkat): Likewise.
	* lib/wchar.in.h (mbrtowc, mbrlen, mbsrtowcs, mbsnrtowcs, wcrtomb,
	wcsrtombs, wcsnrtombs, wmemcpy, wcscpy, wcpcpy, wcsncpy, wcpncpy,
	wcscat, wcsncat, wcsxfrm, wcsstr, wcstok, wcsftime): Likewise.
	* m4/iconv_h.m4 (gl_ICONV_H): Require AC_C_RESTRICT.
	* m4/inttypes.m4 (gl_INTTYPES_INCOMPLETE): Likewise.
	* m4/monetary_h.m4 (gl_MONETARY_H): Likewise.
	* m4/search_h.m4 (gl_SEARCH_H): Likewise.
	* m4/signal_h.m4 (gl_SIGNAL_H): Likewise.
	* m4/stdio_h.m4 (gl_STDIO_H): Likewise.
	* m4/stdlib_h.m4 (gl_STDLIB_H): Likewise.
	* m4/sys_socket_h.m4 (gl_HEADER_SYS_SOCKET): Likewise.
	* m4/sys_stat_h.m4 (gl_HEADER_SYS_STAT_H): Likewise.
	* m4/unistd_h.m4 (gl_UNISTD_H): Likewise.
	* m4/wchar_h.m4 (gl_WCHAR_H): Likewise.
	* m4/string_h.m4 (gl_HEADER_STRING_H_BODY): Make consistent with the
	other *_h.m4 files.
	* m4/time_h.m4 (gl_HEADER_TIME_H): Likewise.

diff --git a/lib/iconv.in.h b/lib/iconv.in.h
index 125fa37..904e8f6 100644
--- a/lib/iconv.in.h
+++ b/lib/iconv.in.h
@@ -80,19 +80,22 @@ _GL_WARN_ON_USE (iconv_open, "iconv_open is not working correctly everywhere - "
 #  endif
 _GL_FUNCDECL_RPL (iconv, size_t,
                   (iconv_t cd,
-                   @ICONV_CONST@ char **inbuf, size_t *inbytesleft,
-                   char **outbuf, size_t *outbytesleft));
+                   @ICONV_CONST@ char **restrict inbuf,
+                   size_t *restrict inbytesleft,
+                   char **restrict outbuf, size_t *restrict outbytesleft));
 _GL_CXXALIAS_RPL (iconv, size_t,
                   (iconv_t cd,
-                   @ICONV_CONST@ char **inbuf, size_t *inbytesleft,
-                   char **outbuf, size_t *outbytesleft));
+                   @ICONV_CONST@ char **restrict inbuf,
+                   size_t *restrict inbytesleft,
+                   char **restrict outbuf, size_t *restrict outbytesleft));
 # else
 /* Need to cast, because on some versions of Solaris, ICONV_CONST does
    not have the right value for C++.  */
 _GL_CXXALIAS_SYS_CAST (iconv, size_t,
                        (iconv_t cd,
-                        @ICONV_CONST@ char **inbuf, size_t *inbytesleft,
-                        char **outbuf, size_t *outbytesleft));
+                        @ICONV_CONST@ char **restrict inbuf,
+                        size_t *restrict inbytesleft,
+                        char **restrict outbuf, size_t *restrict outbytesleft));
 # endif
 _GL_CXXALIASWARN (iconv);
 # ifndef ICONV_CONST
diff --git a/lib/inttypes.in.h b/lib/inttypes.in.h
index d6efc7e..9f04a6c 100644
--- a/lib/inttypes.in.h
+++ b/lib/inttypes.in.h
@@ -1093,15 +1093,19 @@ _GL_WARN_ON_USE (imaxdiv, "imaxdiv is unportable - "
 #   define strtoimax rpl_strtoimax
 #  endif
 _GL_FUNCDECL_RPL (strtoimax, intmax_t,
-                  (const char *, char **, int) _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (strtoimax, intmax_t, (const char *, char **, int));
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoimax, intmax_t,
+                  (const char *restrict, char **restrict, int));
 # else
 #  if !@HAVE_DECL_STRTOIMAX@
 #   undef strtoimax
 _GL_FUNCDECL_SYS (strtoimax, intmax_t,
-                  (const char *, char **, int) _GL_ARG_NONNULL ((1)));
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_SYS (strtoimax, intmax_t, (const char *, char **, int));
+_GL_CXXALIAS_SYS (strtoimax, intmax_t,
+                  (const char *restrict, char **restrict, int));
 # endif
 _GL_CXXALIASWARN (strtoimax);
 #elif defined GNULIB_POSIXCHECK
@@ -1119,15 +1123,19 @@ _GL_WARN_ON_USE (strtoimax, "strtoimax is unportable - "
 #   define strtoumax rpl_strtoumax
 #  endif
 _GL_FUNCDECL_RPL (strtoumax, uintmax_t,
-                  (const char *, char **, int) _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (strtoumax, uintmax_t, (const char *, char **, int));
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtoumax, uintmax_t,
+                  (const char *restrict, char **restrict, int));
 # else
 #  if !@HAVE_DECL_STRTOUMAX@
 #   undef strtoumax
 _GL_FUNCDECL_SYS (strtoumax, uintmax_t,
-                  (const char *, char **, int) _GL_ARG_NONNULL ((1)));
+                  (const char *restrict, char **restrict, int)
+                  _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_SYS (strtoumax, uintmax_t, (const char *, char **, int));
+_GL_CXXALIAS_SYS (strtoumax, uintmax_t,
+                  (const char *restrict, char **restrict, int));
 # endif
 _GL_CXXALIASWARN (strtoumax);
 #elif defined GNULIB_POSIXCHECK
diff --git a/lib/monetary.in.h b/lib/monetary.in.h
index ab17917..456a153 100644
--- a/lib/monetary.in.h
+++ b/lib/monetary.in.h
@@ -79,16 +79,19 @@ extern "C" {
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define strfmon_l rpl_strfmon_l
 #  endif
-_GL_FUNCDECL_RPL (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
-                                       const char *format, ...)
-                                      _GL_ATTRIBUTE_FORMAT_STRFMON (4, 5)
-                                      _GL_ARG_NONNULL ((4)));
-_GL_CXXALIAS_RPL (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
-                                       const char *format, ...));
+_GL_FUNCDECL_RPL (strfmon_l, ssize_t,
+                  (char *restrict s, size_t maxsize, locale_t locale,
+                   const char *restrict format, ...)
+                  _GL_ATTRIBUTE_FORMAT_STRFMON (4, 5)
+                  _GL_ARG_NONNULL ((4)));
+_GL_CXXALIAS_RPL (strfmon_l, ssize_t,
+                  (char *restrict s, size_t maxsize, locale_t locale,
+                   const char *restrict format, ...));
 # else
 #  if @HAVE_STRFMON_L@
-_GL_CXXALIAS_SYS (strfmon_l, ssize_t, (char *s, size_t maxsize, locale_t locale,
-                                       const char *format, ...));
+_GL_CXXALIAS_SYS (strfmon_l, ssize_t,
+                  (char *restrict s, size_t maxsize, locale_t locale,
+                   const char *restrict format, ...));
 #  endif
 # endif
 # if __GLIBC__ >= 2
diff --git a/lib/pthread.in.h b/lib/pthread.in.h
index 8f1f13c..0f743ca 100644
--- a/lib/pthread.in.h
+++ b/lib/pthread.in.h
@@ -449,28 +449,34 @@ typedef unsigned int pthread_barrierattr_t;
 /* =========== Thread functions =========== */
 
 #if @GNULIB_PTHREAD_THREAD@
+/* The 'restrict' qualifier on ARG is nonsense, but POSIX specifies it this way.
+   Sigh.  */
 # if @REPLACE_PTHREAD_CREATE@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef pthread_create
 #   define pthread_create rpl_pthread_create
 #  endif
 _GL_FUNCDECL_RPL (pthread_create, int,
-                  (pthread_t *threadp, const pthread_attr_t *attr,
-                   void * (*mainfunc) (void *), void *arg)
+                  (pthread_t *restrict threadp,
+                   const pthread_attr_t *restrict attr,
+                   void * (*mainfunc) (void *), void *restrict arg)
                   _GL_ARG_NONNULL ((1, 3)));
 _GL_CXXALIAS_RPL (pthread_create, int,
-                  (pthread_t *threadp, const pthread_attr_t *attr,
-                   void * (*mainfunc) (void *), void *arg));
+                  (pthread_t *restrict threadp,
+                   const pthread_attr_t *restrict attr,
+                   void * (*mainfunc) (void *), void *restrict arg));
 # else
 #  if !@HAVE_PTHREAD_CREATE@
 _GL_FUNCDECL_SYS (pthread_create, int,
-                  (pthread_t *threadp, const pthread_attr_t *attr,
-                   void * (*mainfunc) (void *), void *arg)
+                  (pthread_t *restrict threadp,
+                   const pthread_attr_t *restrict attr,
+                   void * (*mainfunc) (void *), void *restrict arg)
                   _GL_ARG_NONNULL ((1, 3)));
 #  endif
 _GL_CXXALIAS_SYS_CAST (pthread_create, int,
-                       (pthread_t *threadp, const pthread_attr_t *attr,
-                        void * (*mainfunc) (void *), void *arg));
+                       (pthread_t *restrict threadp,
+                        const pthread_attr_t *restrict attr,
+                        void * (*mainfunc) (void *), void *restrict arg));
 # endif
 _GL_CXXALIASWARN (pthread_create);
 #elif defined GNULIB_POSIXCHECK
@@ -746,18 +752,22 @@ _GL_WARN_ON_USE (pthread_once, "pthread_once is not portable - "
 #   define pthread_mutex_init rpl_pthread_mutex_init
 #  endif
 _GL_FUNCDECL_RPL (pthread_mutex_init, int,
-                  (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+                  (pthread_mutex_t *restrict mutex,
+                   const pthread_mutexattr_t *restrict attr)
                   _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (pthread_mutex_init, int,
-                  (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr));
+                  (pthread_mutex_t *restrict mutex,
+                   const pthread_mutexattr_t *restrict attr));
 # else
 #  if !@HAVE_PTHREAD_MUTEX_INIT@
 _GL_FUNCDECL_SYS (pthread_mutex_init, int,
-                  (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
+                  (pthread_mutex_t *restrict mutex,
+                   const pthread_mutexattr_t *restrict attr)
                   _GL_ARG_NONNULL ((1)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_mutex_init, int,
-                  (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr));
+                  (pthread_mutex_t *restrict mutex,
+                   const pthread_mutexattr_t *restrict attr));
 # endif
 _GL_CXXALIASWARN (pthread_mutex_init);
 #elif defined GNULIB_POSIXCHECK
@@ -800,20 +810,24 @@ _GL_WARN_ON_USE (pthread_mutexattr_init, "pthread_mutexattr_init is not portable
 #   define pthread_mutexattr_gettype rpl_pthread_mutexattr_gettype
 #  endif
 _GL_FUNCDECL_RPL (pthread_mutexattr_gettype, int,
-                  (const pthread_mutexattr_t *attr, int *typep)
+                  (const pthread_mutexattr_t *restrict attr,
+                   int *restrict typep)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (pthread_mutexattr_gettype, int,
-                  (const pthread_mutexattr_t *attr, int *typep));
+                  (const pthread_mutexattr_t *restrict attr,
+                   int *restrict typep));
 # else
 #  if !@HAVE_PTHREAD_MUTEXATTR_GETTYPE@
 _GL_FUNCDECL_SYS (pthread_mutexattr_gettype, int,
-                  (const pthread_mutexattr_t *attr, int *typep)
+                  (const pthread_mutexattr_t *restrict attr,
+                   int *restrict typep)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 /* Need to cast, because on FreeBSD the first parameter is
                         pthread_mutexattr_t *attr.  */
 _GL_CXXALIAS_SYS_CAST (pthread_mutexattr_gettype, int,
-                       (const pthread_mutexattr_t *attr, int *typep));
+                       (const pthread_mutexattr_t *restrict attr,
+                        int *restrict typep));
 # endif
 _GL_CXXALIASWARN (pthread_mutexattr_gettype);
 #elif defined GNULIB_POSIXCHECK
@@ -858,20 +872,24 @@ _GL_WARN_ON_USE (pthread_mutexattr_settype, "pthread_mutexattr_settype is not po
 #   define pthread_mutexattr_getrobust rpl_pthread_mutexattr_getrobust
 #  endif
 _GL_FUNCDECL_RPL (pthread_mutexattr_getrobust, int,
-                  (const pthread_mutexattr_t *attr, int *robustp)
+                  (const pthread_mutexattr_t *restrict attr,
+                   int *restrict robustp)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (pthread_mutexattr_getrobust, int,
-                  (const pthread_mutexattr_t *attr, int *robustp));
+                  (const pthread_mutexattr_t *restrict attr,
+                   int *restrict robustp));
 # else
 #  if !@HAVE_PTHREAD_MUTEXATTR_GETROBUST@
 _GL_FUNCDECL_SYS (pthread_mutexattr_getrobust, int,
-                  (const pthread_mutexattr_t *attr, int *robustp)
+                  (const pthread_mutexattr_t *restrict attr,
+                   int *restrict robustp)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 /* Need to cast, because on FreeBSD the first parameter is
                         pthread_mutexattr_t *attr.  */
 _GL_CXXALIAS_SYS_CAST (pthread_mutexattr_getrobust, int,
-                       (const pthread_mutexattr_t *attr, int *robustp));
+                       (const pthread_mutexattr_t *restrict attr,
+                        int *restrict robustp));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (pthread_mutexattr_getrobust);
@@ -999,18 +1017,22 @@ _GL_WARN_ON_USE (pthread_mutex_trylock, "pthread_mutex_trylock is not portable -
 #   define pthread_mutex_timedlock rpl_pthread_mutex_timedlock
 #  endif
 _GL_FUNCDECL_RPL (pthread_mutex_timedlock, int,
-                  (pthread_mutex_t *mutex, const struct timespec *abstime)
+                  (pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (pthread_mutex_timedlock, int,
-                  (pthread_mutex_t *mutex, const struct timespec *abstime));
+                  (pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime));
 # else
 #  if !@HAVE_PTHREAD_MUTEX_TIMEDLOCK@
 _GL_FUNCDECL_SYS (pthread_mutex_timedlock, int,
-                  (pthread_mutex_t *mutex, const struct timespec *abstime)
+                  (pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_mutex_timedlock, int,
-                  (pthread_mutex_t *mutex, const struct timespec *abstime));
+                  (pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime));
 # endif
 _GL_CXXALIASWARN (pthread_mutex_timedlock);
 #elif defined GNULIB_POSIXCHECK
@@ -1080,18 +1102,22 @@ _GL_WARN_ON_USE (pthread_mutex_destroy, "pthread_mutex_destroy is not portable -
 #   define pthread_rwlock_init rpl_pthread_rwlock_init
 #  endif
 _GL_FUNCDECL_RPL (pthread_rwlock_init, int,
-                  (pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr)
+                  (pthread_rwlock_t *restrict lock,
+                   const pthread_rwlockattr_t *restrict attr)
                   _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (pthread_rwlock_init, int,
-                  (pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr));
+                  (pthread_rwlock_t *restrict lock,
+                   const pthread_rwlockattr_t *restrict attr));
 # else
 #  if !@HAVE_PTHREAD_RWLOCK_INIT@
 _GL_FUNCDECL_SYS (pthread_rwlock_init, int,
-                  (pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr)
+                  (pthread_rwlock_t *restrict lock,
+                   const pthread_rwlockattr_t *restrict attr)
                   _GL_ARG_NONNULL ((1)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_rwlock_init, int,
-                  (pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr));
+                  (pthread_rwlock_t *restrict lock,
+                   const pthread_rwlockattr_t *restrict attr));
 # endif
 _GL_CXXALIASWARN (pthread_rwlock_init);
 #elif defined GNULIB_POSIXCHECK
@@ -1261,18 +1287,22 @@ _GL_WARN_ON_USE (pthread_rwlock_trywrlock, "pthread_rwlock_trywrlock is not port
 #   define pthread_rwlock_timedrdlock rpl_pthread_rwlock_timedrdlock
 #  endif
 _GL_FUNCDECL_RPL (pthread_rwlock_timedrdlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime)
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (pthread_rwlock_timedrdlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime));
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime));
 # else
 #  if !@HAVE_PTHREAD_RWLOCK_TIMEDRDLOCK@
 _GL_FUNCDECL_SYS (pthread_rwlock_timedrdlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime)
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_rwlock_timedrdlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime));
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime));
 # endif
 _GL_CXXALIASWARN (pthread_rwlock_timedrdlock);
 #elif defined GNULIB_POSIXCHECK
@@ -1290,18 +1320,22 @@ _GL_WARN_ON_USE (pthread_rwlock_timedrdlock, "pthread_rwlock_timedrdlock is not
 #   define pthread_rwlock_timedwrlock rpl_pthread_rwlock_timedwrlock
 #  endif
 _GL_FUNCDECL_RPL (pthread_rwlock_timedwrlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime)
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (pthread_rwlock_timedwrlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime));
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime));
 # else
 #  if !@HAVE_PTHREAD_RWLOCK_TIMEDWRLOCK@
 _GL_FUNCDECL_SYS (pthread_rwlock_timedwrlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime)
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_rwlock_timedwrlock, int,
-                  (pthread_rwlock_t *lock, const struct timespec *abstime));
+                  (pthread_rwlock_t *restrict lock,
+                   const struct timespec *restrict abstime));
 # endif
 _GL_CXXALIASWARN (pthread_rwlock_timedwrlock);
 #elif defined GNULIB_POSIXCHECK
@@ -1371,18 +1405,22 @@ _GL_WARN_ON_USE (pthread_rwlock_destroy, "pthread_rwlock_destroy is not portable
 #   define pthread_cond_init rpl_pthread_cond_init
 #  endif
 _GL_FUNCDECL_RPL (pthread_cond_init, int,
-                  (pthread_cond_t *cond, const pthread_condattr_t *attr)
+                  (pthread_cond_t *restrict cond,
+                   const pthread_condattr_t *restrict attr)
                   _GL_ARG_NONNULL ((1)));
 _GL_CXXALIAS_RPL (pthread_cond_init, int,
-                  (pthread_cond_t *cond, const pthread_condattr_t *attr));
+                  (pthread_cond_t *restrict cond,
+                   const pthread_condattr_t *restrict attr));
 # else
 #  if !@HAVE_PTHREAD_COND_INIT@
 _GL_FUNCDECL_SYS (pthread_cond_init, int,
-                  (pthread_cond_t *cond, const pthread_condattr_t *attr)
+                  (pthread_cond_t *restrict cond,
+                   const pthread_condattr_t *restrict attr)
                   _GL_ARG_NONNULL ((1)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_cond_init, int,
-                  (pthread_cond_t *cond, const pthread_condattr_t *attr));
+                  (pthread_cond_t *restrict cond,
+                   const pthread_condattr_t *restrict attr));
 # endif
 _GL_CXXALIASWARN (pthread_cond_init);
 #elif defined GNULIB_POSIXCHECK
@@ -1450,18 +1488,22 @@ _GL_WARN_ON_USE (pthread_condattr_destroy, "pthread_condattr_destroy is not port
 #   define pthread_cond_wait rpl_pthread_cond_wait
 #  endif
 _GL_FUNCDECL_RPL (pthread_cond_wait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex)
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (pthread_cond_wait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex));
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex));
 # else
 #  if !@HAVE_PTHREAD_COND_WAIT@
 _GL_FUNCDECL_SYS (pthread_cond_wait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex)
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_cond_wait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex));
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex));
 # endif
 _GL_CXXALIASWARN (pthread_cond_wait);
 #elif defined GNULIB_POSIXCHECK
@@ -1479,22 +1521,26 @@ _GL_WARN_ON_USE (pthread_cond_wait, "pthread_cond_wait is not portable - "
 #   define pthread_cond_timedwait rpl_pthread_cond_timedwait
 #  endif
 _GL_FUNCDECL_RPL (pthread_cond_timedwait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex,
-                   const struct timespec *abstime)
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2, 3)));
 _GL_CXXALIAS_RPL (pthread_cond_timedwait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex,
-                   const struct timespec *abstime));
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime));
 # else
 #  if !@HAVE_PTHREAD_COND_TIMEDWAIT@
 _GL_FUNCDECL_SYS (pthread_cond_timedwait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex,
-                   const struct timespec *abstime)
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime)
                   _GL_ARG_NONNULL ((1, 2, 3)));
 #  endif
 _GL_CXXALIAS_SYS (pthread_cond_timedwait, int,
-                  (pthread_cond_t *cond, pthread_mutex_t *mutex,
-                   const struct timespec *abstime));
+                  (pthread_cond_t *restrict cond,
+                   pthread_mutex_t *restrict mutex,
+                   const struct timespec *restrict abstime));
 # endif
 _GL_CXXALIASWARN (pthread_cond_timedwait);
 #elif defined GNULIB_POSIXCHECK
diff --git a/lib/search.in.h b/lib/search.in.h
index b2a9fa9..61116ed 100644
--- a/lib/search.in.h
+++ b/lib/search.in.h
@@ -132,21 +132,21 @@ _GL_CXXALIASWARN (tfind);
    returned.  Otherwise, NULL is returned.  */
 # if @REPLACE_TSEARCH@
 _GL_FUNCDECL_RPL (tdelete, void *,
-                  (const void *key, void **vrootp,
+                  (const void *restrict key, void **restrict vrootp,
                    _gl_search_compar_fn compar)
                   _GL_ARG_NONNULL ((1, 2, 3)));
 _GL_CXXALIAS_RPL (tdelete, void *,
-                  (const void *key, void **vrootp,
+                  (const void *restrict key, void **restrict vrootp,
                    _gl_search_compar_fn compar));
 # else
 #  if !@HAVE_TSEARCH@
 _GL_FUNCDECL_SYS (tdelete, void *,
-                  (const void *key, void **vrootp,
+                  (const void *restrict key, void **restrict vrootp,
                    _gl_search_compar_fn compar)
                   _GL_ARG_NONNULL ((1, 2, 3)));
 #  endif
 _GL_CXXALIAS_SYS (tdelete, void *,
-                  (const void *key, void **vrootp,
+                  (const void *restrict key, void **restrict vrootp,
                    _gl_search_compar_fn compar));
 # endif
 _GL_CXXALIASWARN (tdelete);
diff --git a/lib/signal.in.h b/lib/signal.in.h
index 9fe9f60..c94b053 100644
--- a/lib/signal.in.h
+++ b/lib/signal.in.h
@@ -133,16 +133,24 @@ typedef void (*sighandler_t) (int);
 #   define pthread_sigmask rpl_pthread_sigmask
 #  endif
 _GL_FUNCDECL_RPL (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how,
+                   const sigset_t *restrict new_mask,
+                   sigset_t *restrict old_mask));
 _GL_CXXALIAS_RPL (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how,
+                   const sigset_t *restrict new_mask,
+                   sigset_t *restrict old_mask));
 # else
 #  if !(@HAVE_PTHREAD_SIGMASK@ || defined pthread_sigmask)
 _GL_FUNCDECL_SYS (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how,
+                   const sigset_t *restrict new_mask,
+                   sigset_t *restrict old_mask));
 #  endif
 _GL_CXXALIAS_SYS (pthread_sigmask, int,
-                  (int how, const sigset_t *new_mask, sigset_t *old_mask));
+                  (int how,
+                   const sigset_t *restrict new_mask,
+                   sigset_t *restrict old_mask));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (pthread_sigmask);
@@ -295,10 +303,14 @@ _GL_CXXALIASWARN (sigpending);
 #  define SIG_SETMASK 1  /* blocked_set = *set; */
 #  define SIG_UNBLOCK 2  /* blocked_set = blocked_set & ~*set; */
 _GL_FUNCDECL_SYS (sigprocmask, int,
-                  (int operation, const sigset_t *set, sigset_t *old_set));
+                  (int operation,
+                   const sigset_t *restrict set,
+                   sigset_t *restrict old_set));
 # endif
 _GL_CXXALIAS_SYS (sigprocmask, int,
-                  (int operation, const sigset_t *set, sigset_t *old_set));
+                  (int operation,
+                   const sigset_t *restrict set,
+                   sigset_t *restrict old_set));
 _GL_CXXALIASWARN (sigprocmask);
 
 /* Install the handler FUNC for signal SIG, and return the previous
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index 388565d..839a14b 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -171,17 +171,17 @@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define dprintf rpl_dprintf
 #  endif
-_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *format, ...)
+_GL_FUNCDECL_RPL (dprintf, int, (int fd, const char *restrict format, ...)
                                 _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
                                 _GL_ARG_NONNULL ((2)));
-_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *format, ...));
+_GL_CXXALIAS_RPL (dprintf, int, (int fd, const char *restrict format, ...));
 # else
 #  if !@HAVE_DPRINTF@
-_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *format, ...)
+_GL_FUNCDECL_SYS (dprintf, int, (int fd, const char *restrict format, ...)
                                 _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
                                 _GL_ARG_NONNULL ((2)));
 #  endif
-_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *format, ...));
+_GL_CXXALIAS_SYS (dprintf, int, (int fd, const char *restrict format, ...));
 # endif
 _GL_CXXALIASWARN (dprintf);
 #elif defined GNULIB_POSIXCHECK
@@ -281,11 +281,14 @@ _GL_CXXALIASWARN (fgetc);
 #   undef fgets
 #   define fgets rpl_fgets
 #  endif
-_GL_FUNCDECL_RPL (fgets, char *, (char *s, int n, FILE *stream)
-                                 _GL_ARG_NONNULL ((1, 3)));
-_GL_CXXALIAS_RPL (fgets, char *, (char *s, int n, FILE *stream));
+_GL_FUNCDECL_RPL (fgets, char *,
+                  (char *restrict s, int n, FILE *restrict stream)
+                  _GL_ARG_NONNULL ((1, 3)));
+_GL_CXXALIAS_RPL (fgets, char *,
+                  (char *restrict s, int n, FILE *restrict stream));
 # else
-_GL_CXXALIAS_SYS (fgets, char *, (char *s, int n, FILE *stream));
+_GL_CXXALIAS_SYS (fgets, char *,
+                  (char *restrict s, int n, FILE *restrict stream));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fgets);
@@ -298,11 +301,14 @@ _GL_CXXALIASWARN (fgets);
 #   undef fopen
 #   define fopen rpl_fopen
 #  endif
-_GL_FUNCDECL_RPL (fopen, FILE *, (const char *filename, const char *mode)
-                                 _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (fopen, FILE *, (const char *filename, const char *mode));
+_GL_FUNCDECL_RPL (fopen, FILE *,
+                  (const char *restrict filename, const char *restrict mode)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (fopen, FILE *,
+                  (const char *restrict filename, const char *restrict mode));
 # else
-_GL_CXXALIAS_SYS (fopen, FILE *, (const char *filename, const char *mode));
+_GL_CXXALIAS_SYS (fopen, FILE *,
+                  (const char *restrict filename, const char *restrict mode));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fopen);
@@ -322,17 +328,21 @@ _GL_WARN_ON_USE (fopen, "fopen on native Windows platforms is not POSIX complian
 #  endif
 #  define GNULIB_overrides_fprintf 1
 #  if @GNULIB_FPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@
-_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...)
-                                _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
-                                _GL_ARG_NONNULL ((1, 2)));
+_GL_FUNCDECL_RPL (fprintf, int,
+                  (FILE *restrict fp, const char *restrict format, ...)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
+                  _GL_ARG_NONNULL ((1, 2)));
 #  else
-_GL_FUNCDECL_RPL (fprintf, int, (FILE *fp, const char *format, ...)
-                                _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3)
-                                _GL_ARG_NONNULL ((1, 2)));
+_GL_FUNCDECL_RPL (fprintf, int,
+                  (FILE *restrict fp, const char *restrict format, ...)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 3)
+                  _GL_ARG_NONNULL ((1, 2)));
 #  endif
-_GL_CXXALIAS_RPL (fprintf, int, (FILE *fp, const char *format, ...));
+_GL_CXXALIAS_RPL (fprintf, int,
+                  (FILE *restrict fp, const char *restrict format, ...));
 # else
-_GL_CXXALIAS_SYS (fprintf, int, (FILE *fp, const char *format, ...));
+_GL_CXXALIAS_SYS (fprintf, int,
+                  (FILE *restrict fp, const char *restrict format, ...));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fprintf);
@@ -398,11 +408,14 @@ _GL_CXXALIASWARN (fputc);
 #   undef fputs
 #   define fputs rpl_fputs
 #  endif
-_GL_FUNCDECL_RPL (fputs, int, (const char *string, FILE *stream)
-                              _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (fputs, int, (const char *string, FILE *stream));
+_GL_FUNCDECL_RPL (fputs, int,
+                  (const char *restrict string, FILE *restrict stream)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (fputs, int,
+                  (const char *restrict string, FILE *restrict stream));
 # else
-_GL_CXXALIAS_SYS (fputs, int, (const char *string, FILE *stream));
+_GL_CXXALIAS_SYS (fputs, int,
+                  (const char *restrict string, FILE *restrict stream));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fputs);
@@ -415,11 +428,17 @@ _GL_CXXALIASWARN (fputs);
 #   undef fread
 #   define fread rpl_fread
 #  endif
-_GL_FUNCDECL_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream)
-                                 _GL_ARG_NONNULL ((4)));
-_GL_CXXALIAS_RPL (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream));
+_GL_FUNCDECL_RPL (fread, size_t,
+                  (void *restrict ptr, size_t s, size_t n,
+                   FILE *restrict stream)
+                  _GL_ARG_NONNULL ((4)));
+_GL_CXXALIAS_RPL (fread, size_t,
+                  (void *restrict ptr, size_t s, size_t n,
+                   FILE *restrict stream));
 # else
-_GL_CXXALIAS_SYS (fread, size_t, (void *ptr, size_t s, size_t n, FILE *stream));
+_GL_CXXALIAS_SYS (fread, size_t,
+                  (void *restrict ptr, size_t s, size_t n,
+                   FILE *restrict stream));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fread);
@@ -433,13 +452,16 @@ _GL_CXXALIASWARN (fread);
 #   define freopen rpl_freopen
 #  endif
 _GL_FUNCDECL_RPL (freopen, FILE *,
-                  (const char *filename, const char *mode, FILE *stream)
+                  (const char *restrict filename, const char *restrict mode,
+                   FILE *restrict stream)
                   _GL_ARG_NONNULL ((2, 3)));
 _GL_CXXALIAS_RPL (freopen, FILE *,
-                  (const char *filename, const char *mode, FILE *stream));
+                  (const char *restrict filename, const char *restrict mode,
+                   FILE *restrict stream));
 # else
 _GL_CXXALIAS_SYS (freopen, FILE *,
-                  (const char *filename, const char *mode, FILE *stream));
+                  (const char *restrict filename, const char *restrict mode,
+                   FILE *restrict stream));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (freopen);
@@ -458,12 +480,15 @@ _GL_WARN_ON_USE (freopen,
 #   undef fscanf
 #   define fscanf rpl_fscanf
 #  endif
-_GL_FUNCDECL_RPL (fscanf, int, (FILE *stream, const char *format, ...)
-                               _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3)
-                               _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (fscanf, int, (FILE *stream, const char *format, ...));
+_GL_FUNCDECL_RPL (fscanf, int,
+                  (FILE *restrict stream, const char *restrict format, ...)
+                  _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 3)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (fscanf, int,
+                  (FILE *restrict stream, const char *restrict format, ...));
 # else
-_GL_CXXALIAS_SYS (fscanf, int, (FILE *stream, const char *format, ...));
+_GL_CXXALIAS_SYS (fscanf, int,
+                  (FILE *restrict stream, const char *restrict format, ...));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (fscanf);
@@ -634,13 +659,16 @@ _GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB "
 #   define fwrite rpl_fwrite
 #  endif
 _GL_FUNCDECL_RPL (fwrite, size_t,
-                  (const void *ptr, size_t s, size_t n, FILE *stream)
+                  (const void *restrict ptr, size_t s, size_t n,
+                   FILE *restrict stream)
                   _GL_ARG_NONNULL ((1, 4)));
 _GL_CXXALIAS_RPL (fwrite, size_t,
-                  (const void *ptr, size_t s, size_t n, FILE *stream));
+                  (const void *restrict ptr, size_t s, size_t n,
+                   FILE *restrict stream));
 # else
 _GL_CXXALIAS_SYS (fwrite, size_t,
-                  (const void *ptr, size_t s, size_t n, FILE *stream));
+                  (const void *restrict ptr, size_t s, size_t n,
+                   FILE *restrict stream));
 
 /* Work around bug 11959 when fortifying glibc 2.4 through 2.15
    <https://sourceware.org/bugzilla/show_bug.cgi?id=11959>,
@@ -715,22 +743,26 @@ _GL_CXXALIASWARN (getchar);
 #   define getdelim rpl_getdelim
 #  endif
 _GL_FUNCDECL_RPL (getdelim, ssize_t,
-                  (char **lineptr, size_t *linesize, int delimiter,
-                   FILE *stream)
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   int delimiter,
+                   FILE *restrict stream)
                   _GL_ARG_NONNULL ((1, 2, 4)));
 _GL_CXXALIAS_RPL (getdelim, ssize_t,
-                  (char **lineptr, size_t *linesize, int delimiter,
-                   FILE *stream));
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   int delimiter,
+                   FILE *restrict stream));
 # else
 #  if !@HAVE_DECL_GETDELIM@
 _GL_FUNCDECL_SYS (getdelim, ssize_t,
-                  (char **lineptr, size_t *linesize, int delimiter,
-                   FILE *stream)
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   int delimiter,
+                   FILE *restrict stream)
                   _GL_ARG_NONNULL ((1, 2, 4)));
 #  endif
 _GL_CXXALIAS_SYS (getdelim, ssize_t,
-                  (char **lineptr, size_t *linesize, int delimiter,
-                   FILE *stream));
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   int delimiter,
+                   FILE *restrict stream));
 # endif
 _GL_CXXALIASWARN (getdelim);
 #elif defined GNULIB_POSIXCHECK
@@ -754,18 +786,22 @@ _GL_WARN_ON_USE (getdelim, "getdelim is unportable - "
 #   define getline rpl_getline
 #  endif
 _GL_FUNCDECL_RPL (getline, ssize_t,
-                  (char **lineptr, size_t *linesize, FILE *stream)
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   FILE *restrict stream)
                   _GL_ARG_NONNULL ((1, 2, 3)));
 _GL_CXXALIAS_RPL (getline, ssize_t,
-                  (char **lineptr, size_t *linesize, FILE *stream));
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   FILE *restrict stream));
 # else
 #  if !@HAVE_DECL_GETLINE@
 _GL_FUNCDECL_SYS (getline, ssize_t,
-                  (char **lineptr, size_t *linesize, FILE *stream)
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   FILE *restrict stream)
                   _GL_ARG_NONNULL ((1, 2, 3)));
 #  endif
 _GL_CXXALIAS_SYS (getline, ssize_t,
-                  (char **lineptr, size_t *linesize, FILE *stream));
+                  (char **restrict lineptr, size_t *restrict linesize,
+                   FILE *restrict stream));
 # endif
 # if @HAVE_DECL_GETLINE@
 _GL_CXXALIASWARN (getline);
@@ -909,14 +945,14 @@ _GL_WARN_ON_USE (popen, "popen is buggy on some platforms - "
 #   endif
 #   if @GNULIB_PRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@
 _GL_FUNCDECL_RPL_1 (__printf__, int,
-                    (const char *format, ...)
+                    (const char *restrict format, ...)
                     __asm__ (@ASM_SYMBOL_PREFIX@
                              _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf))
                     _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2)
                     _GL_ARG_NONNULL ((1)));
 #   else
 _GL_FUNCDECL_RPL_1 (__printf__, int,
-                    (const char *format, ...)
+                    (const char *restrict format, ...)
                     __asm__ (@ASM_SYMBOL_PREFIX@
                              _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_printf))
                     _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 2)
@@ -928,14 +964,14 @@ _GL_CXXALIAS_RPL_1 (printf, __printf__, int, (const char *format, ...));
 #    define printf rpl_printf
 #   endif
 _GL_FUNCDECL_RPL (printf, int,
-                  (const char *format, ...)
+                  (const char *restrict format, ...)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (1, 2)
                   _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (printf, int, (const char *format, ...));
+_GL_CXXALIAS_RPL (printf, int, (const char *restrict format, ...));
 #  endif
 #  define GNULIB_overrides_printf 1
 # else
-_GL_CXXALIAS_SYS (printf, int, (const char *format, ...));
+_GL_CXXALIAS_SYS (printf, int, (const char *restrict format, ...));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (printf);
@@ -1083,24 +1119,24 @@ _GL_WARN_ON_USE (renameat, "renameat is not portable - "
 #    define scanf __scanf__
 #   endif
 _GL_FUNCDECL_RPL_1 (__scanf__, int,
-                    (const char *format, ...)
+                    (const char *restrict format, ...)
                     __asm__ (@ASM_SYMBOL_PREFIX@
                              _GL_STDIO_MACROEXPAND_AND_STRINGIZE(rpl_scanf))
                     _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2)
                     _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *format, ...));
+_GL_CXXALIAS_RPL_1 (scanf, __scanf__, int, (const char *restrict format, ...));
 #  else
 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #    undef scanf
 #    define scanf rpl_scanf
 #   endif
-_GL_FUNCDECL_RPL (scanf, int, (const char *format, ...)
+_GL_FUNCDECL_RPL (scanf, int, (const char *restrict format, ...)
                               _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 2)
                               _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (scanf, int, (const char *format, ...));
+_GL_CXXALIAS_RPL (scanf, int, (const char *restrict format, ...));
 #  endif
 # else
-_GL_CXXALIAS_SYS (scanf, int, (const char *format, ...));
+_GL_CXXALIAS_SYS (scanf, int, (const char *restrict format, ...));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (scanf);
@@ -1113,20 +1149,24 @@ _GL_CXXALIASWARN (scanf);
 #   define snprintf rpl_snprintf
 #  endif
 _GL_FUNCDECL_RPL (snprintf, int,
-                  (char *str, size_t size, const char *format, ...)
+                  (char *restrict str, size_t size,
+                   const char *restrict format, ...)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4)
                   _GL_ARG_NONNULL ((3)));
 _GL_CXXALIAS_RPL (snprintf, int,
-                  (char *str, size_t size, const char *format, ...));
+                  (char *restrict str, size_t size,
+                   const char *restrict format, ...));
 # else
 #  if !@HAVE_DECL_SNPRINTF@
 _GL_FUNCDECL_SYS (snprintf, int,
-                  (char *str, size_t size, const char *format, ...)
+                  (char *restrict str, size_t size,
+                   const char *restrict format, ...)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 4)
                   _GL_ARG_NONNULL ((3)));
 #  endif
 _GL_CXXALIAS_SYS (snprintf, int,
-                  (char *str, size_t size, const char *format, ...));
+                  (char *restrict str, size_t size,
+                   const char *restrict format, ...));
 # endif
 _GL_CXXALIASWARN (snprintf);
 #elif defined GNULIB_POSIXCHECK
@@ -1151,12 +1191,15 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define sprintf rpl_sprintf
 #  endif
-_GL_FUNCDECL_RPL (sprintf, int, (char *str, const char *format, ...)
-                                _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
-                                _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (sprintf, int, (char *str, const char *format, ...));
+_GL_FUNCDECL_RPL (sprintf, int,
+                  (char *restrict str, const char *restrict format, ...)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF (2, 3)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (sprintf, int,
+                  (char *restrict str, const char *restrict format, ...));
 # else
-_GL_CXXALIAS_SYS (sprintf, int, (char *str, const char *format, ...));
+_GL_CXXALIAS_SYS (sprintf, int,
+                  (char *restrict str, const char *restrict format, ...));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (sprintf);
@@ -1244,20 +1287,23 @@ _GL_CXXALIASWARN (vasprintf);
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define vdprintf rpl_vdprintf
 #  endif
-_GL_FUNCDECL_RPL (vdprintf, int, (int fd, const char *format, va_list args)
-                                 _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
-                                 _GL_ARG_NONNULL ((2)));
-_GL_CXXALIAS_RPL (vdprintf, int, (int fd, const char *format, va_list args));
+_GL_FUNCDECL_RPL (vdprintf, int,
+                  (int fd, const char *restrict format, va_list args)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (vdprintf, int,
+                  (int fd, const char *restrict format, va_list args));
 # else
 #  if !@HAVE_VDPRINTF@
-_GL_FUNCDECL_SYS (vdprintf, int, (int fd, const char *format, va_list args)
-                                 _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
-                                 _GL_ARG_NONNULL ((2)));
+_GL_FUNCDECL_SYS (vdprintf, int,
+                  (int fd, const char *restrict format, va_list args)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
+                  _GL_ARG_NONNULL ((2)));
 #  endif
 /* Need to cast, because on Solaris, the third parameter will likely be
                                                     __va_list args.  */
 _GL_CXXALIAS_SYS_CAST (vdprintf, int,
-                       (int fd, const char *format, va_list args));
+                       (int fd, const char *restrict format, va_list args));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vdprintf);
@@ -1278,21 +1324,28 @@ _GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - "
 #  endif
 #  define GNULIB_overrides_vfprintf 1
 #  if @GNULIB_VFPRINTF_POSIX@
-_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)
-                                 _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
-                                 _GL_ARG_NONNULL ((1, 2)));
+_GL_FUNCDECL_RPL (vfprintf, int,
+                  (FILE *restrict fp,
+                   const char *restrict format, va_list args)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
+                  _GL_ARG_NONNULL ((1, 2)));
 #  else
-_GL_FUNCDECL_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args)
-                                 _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0)
-                                 _GL_ARG_NONNULL ((1, 2)));
+_GL_FUNCDECL_RPL (vfprintf, int,
+                  (FILE *restrict fp,
+                   const char *restrict format, va_list args)
+                  _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (2, 0)
+                  _GL_ARG_NONNULL ((1, 2)));
 #  endif
-_GL_CXXALIAS_RPL (vfprintf, int, (FILE *fp, const char *format, va_list args));
+_GL_CXXALIAS_RPL (vfprintf, int,
+                  (FILE *restrict fp,
+                   const char *restrict format, va_list args));
 # else
 /* Need to cast, because on Solaris, the third parameter is
                                                       __va_list args
    and GCC's fixincludes did not change this to __gnuc_va_list.  */
 _GL_CXXALIAS_SYS_CAST (vfprintf, int,
-                       (FILE *fp, const char *format, va_list args));
+                       (FILE *restrict fp,
+                        const char *restrict format, va_list args));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vfprintf);
@@ -1315,14 +1368,17 @@ _GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - "
 #   define vfscanf rpl_vfscanf
 #  endif
 _GL_FUNCDECL_RPL (vfscanf, int,
-                  (FILE *stream, const char *format, va_list args)
+                  (FILE *restrict stream,
+                   const char *restrict format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (2, 0)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (vfscanf, int,
-                  (FILE *stream, const char *format, va_list args));
+                  (FILE *restrict stream,
+                   const char *restrict format, va_list args));
 # else
 _GL_CXXALIAS_SYS (vfscanf, int,
-                  (FILE *stream, const char *format, va_list args));
+                  (FILE *restrict stream,
+                   const char *restrict format, va_list args));
 # endif
 _GL_CXXALIASWARN (vfscanf);
 #endif
@@ -1335,20 +1391,21 @@ _GL_CXXALIASWARN (vfscanf);
 #  endif
 #  define GNULIB_overrides_vprintf 1
 #  if @GNULIB_VPRINTF_POSIX@ || @GNULIB_VFPRINTF_POSIX@
-_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args)
+_GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args)
                                 _GL_ATTRIBUTE_FORMAT_PRINTF (1, 0)
                                 _GL_ARG_NONNULL ((1)));
 #  else
-_GL_FUNCDECL_RPL (vprintf, int, (const char *format, va_list args)
+_GL_FUNCDECL_RPL (vprintf, int, (const char *restrict format, va_list args)
                                 _GL_ATTRIBUTE_FORMAT_PRINTF_SYSTEM (1, 0)
                                 _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_RPL (vprintf, int, (const char *format, va_list args));
+_GL_CXXALIAS_RPL (vprintf, int, (const char *restrict format, va_list args));
 # else
 /* Need to cast, because on Solaris, the second parameter is
                                                           __va_list args
    and GCC's fixincludes did not change this to __gnuc_va_list.  */
-_GL_CXXALIAS_SYS_CAST (vprintf, int, (const char *format, va_list args));
+_GL_CXXALIAS_SYS_CAST (vprintf, int,
+                       (const char *restrict format, va_list args));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vprintf);
@@ -1370,12 +1427,12 @@ _GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - "
 #   undef vscanf
 #   define vscanf rpl_vscanf
 #  endif
-_GL_FUNCDECL_RPL (vscanf, int, (const char *format, va_list args)
+_GL_FUNCDECL_RPL (vscanf, int, (const char *restrict format, va_list args)
                                _GL_ATTRIBUTE_FORMAT_SCANF_SYSTEM (1, 0)
                                _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (vscanf, int, (const char *format, va_list args));
+_GL_CXXALIAS_RPL (vscanf, int, (const char *restrict format, va_list args));
 # else
-_GL_CXXALIAS_SYS (vscanf, int, (const char *format, va_list args));
+_GL_CXXALIAS_SYS (vscanf, int, (const char *restrict format, va_list args));
 # endif
 _GL_CXXALIASWARN (vscanf);
 #endif
@@ -1386,20 +1443,24 @@ _GL_CXXALIASWARN (vscanf);
 #   define vsnprintf rpl_vsnprintf
 #  endif
 _GL_FUNCDECL_RPL (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args)
+                  (char *restrict str, size_t size,
+                   const char *restrict format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0)
                   _GL_ARG_NONNULL ((3)));
 _GL_CXXALIAS_RPL (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args));
+                  (char *restrict str, size_t size,
+                   const char *restrict format, va_list args));
 # else
 #  if !@HAVE_DECL_VSNPRINTF@
 _GL_FUNCDECL_SYS (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args)
+                  (char *restrict str, size_t size,
+                   const char *restrict format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (3, 0)
                   _GL_ARG_NONNULL ((3)));
 #  endif
 _GL_CXXALIAS_SYS (vsnprintf, int,
-                  (char *str, size_t size, const char *format, va_list args));
+                  (char *restrict str, size_t size,
+                   const char *restrict format, va_list args));
 # endif
 _GL_CXXALIASWARN (vsnprintf);
 #elif defined GNULIB_POSIXCHECK
@@ -1416,17 +1477,20 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - "
 #   define vsprintf rpl_vsprintf
 #  endif
 _GL_FUNCDECL_RPL (vsprintf, int,
-                  (char *str, const char *format, va_list args)
+                  (char *restrict str,
+                   const char *restrict format, va_list args)
                   _GL_ATTRIBUTE_FORMAT_PRINTF (2, 0)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (vsprintf, int,
-                  (char *str, const char *format, va_list args));
+                  (char *restrict str,
+                   const char *restrict format, va_list args));
 # else
 /* Need to cast, because on Solaris, the third parameter is
                                                        __va_list args
    and GCC's fixincludes did not change this to __gnuc_va_list.  */
 _GL_CXXALIAS_SYS_CAST (vsprintf, int,
-                       (char *str, const char *format, va_list args));
+                       (char *restrict str,
+                        const char *restrict format, va_list args));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (vsprintf);
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 49bbf6f..ec5f124 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -311,13 +311,17 @@ _GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
 #   undef mbtowc
 #   define mbtowc rpl_mbtowc
 #  endif
-_GL_FUNCDECL_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
-_GL_CXXALIAS_RPL (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+_GL_FUNCDECL_RPL (mbtowc, int,
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n));
+_GL_CXXALIAS_RPL (mbtowc, int,
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n));
 # else
 #  if !@HAVE_MBTOWC@
-_GL_FUNCDECL_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+_GL_FUNCDECL_SYS (mbtowc, int,
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n));
 #  endif
-_GL_CXXALIAS_SYS (mbtowc, int, (wchar_t *pwc, const char *s, size_t n));
+_GL_CXXALIAS_SYS (mbtowc, int,
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (mbtowc);
@@ -866,15 +870,19 @@ _GL_WARN_ON_USE (reallocarray, "reallocarray is not portable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define realpath rpl_realpath
 #  endif
-_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved)
-                                    _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved));
+_GL_FUNCDECL_RPL (realpath, char *,
+                  (const char *restrict name, char *restrict resolved)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (realpath, char *,
+                  (const char *restrict name, char *restrict resolved));
 # else
 #  if !@HAVE_REALPATH@
-_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved)
-                                    _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_SYS (realpath, char *,
+                  (const char *restrict name, char *restrict resolved)
+                  _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved));
+_GL_CXXALIAS_SYS (realpath, char *,
+                  (const char *restrict name, char *restrict resolved));
 # endif
 _GL_CXXALIASWARN (realpath);
 #elif defined GNULIB_POSIXCHECK
@@ -957,15 +965,19 @@ _GL_WARN_ON_USE (setenv, "setenv is unportable - "
 #   define strtod rpl_strtod
 #  endif
 #  define GNULIB_defined_strtod_function 1
-_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp)
-                                  _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp));
+_GL_FUNCDECL_RPL (strtod, double,
+                  (const char *restrict str, char **restrict endp)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtod, double,
+                  (const char *restrict str, char **restrict endp));
 # else
 #  if !@HAVE_STRTOD@
-_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp)
-                                  _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_SYS (strtod, double,
+                  (const char *restrict str, char **restrict endp)
+                  _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp));
+_GL_CXXALIAS_SYS (strtod, double,
+                  (const char *restrict str, char **restrict endp));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (strtod);
@@ -985,15 +997,19 @@ _GL_WARN_ON_USE (strtod, "strtod is unportable - "
 #   define strtold rpl_strtold
 #  endif
 #  define GNULIB_defined_strtold_function 1
-_GL_FUNCDECL_RPL (strtold, long double, (const char *str, char **endp)
-                                        _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (strtold, long double, (const char *str, char **endp));
+_GL_FUNCDECL_RPL (strtold, long double,
+                  (const char *restrict str, char **restrict endp)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtold, long double,
+                  (const char *restrict str, char **restrict endp));
 # else
 #  if !@HAVE_STRTOLD@
-_GL_FUNCDECL_SYS (strtold, long double, (const char *str, char **endp)
-                                        _GL_ARG_NONNULL ((1)));
+_GL_FUNCDECL_SYS (strtold, long double,
+                  (const char *restrict str, char **restrict endp)
+                  _GL_ARG_NONNULL ((1)));
 #  endif
-_GL_CXXALIAS_SYS (strtold, long double, (const char *str, char **endp));
+_GL_CXXALIAS_SYS (strtold, long double,
+                  (const char *restrict str, char **restrict endp));
 # endif
 _GL_CXXALIASWARN (strtold);
 #elif defined GNULIB_POSIXCHECK
@@ -1015,11 +1031,13 @@ _GL_WARN_ON_USE (strtold, "strtold is unportable - "
    to ERANGE.  */
 # if !@HAVE_STRTOLL@
 _GL_FUNCDECL_SYS (strtoll, long long,
-                  (const char *string, char **endptr, int base)
+                  (const char *restrict string, char **restrict endptr,
+                   int base)
                   _GL_ARG_NONNULL ((1)));
 # endif
 _GL_CXXALIAS_SYS (strtoll, long long,
-                  (const char *string, char **endptr, int base));
+                  (const char *restrict string, char **restrict endptr,
+                   int base));
 _GL_CXXALIASWARN (strtoll);
 #elif defined GNULIB_POSIXCHECK
 # undef strtoll
@@ -1040,11 +1058,13 @@ _GL_WARN_ON_USE (strtoll, "strtoll is unportable - "
    ERANGE.  */
 # if !@HAVE_STRTOULL@
 _GL_FUNCDECL_SYS (strtoull, unsigned long long,
-                  (const char *string, char **endptr, int base)
+                  (const char *restrict string, char **restrict endptr,
+                   int base)
                   _GL_ARG_NONNULL ((1)));
 # endif
 _GL_CXXALIAS_SYS (strtoull, unsigned long long,
-                  (const char *string, char **endptr, int base));
+                  (const char *restrict string, char **restrict endptr,
+                   int base));
 _GL_CXXALIASWARN (strtoull);
 #elif defined GNULIB_POSIXCHECK
 # undef strtoull
diff --git a/lib/string.in.h b/lib/string.in.h
index 2be474d..625d608 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -411,11 +411,14 @@ _GL_WARN_ON_USE (strdup, "strdup is unportable - "
 #   undef strncat
 #   define strncat rpl_strncat
 #  endif
-_GL_FUNCDECL_RPL (strncat, char *, (char *dest, const char *src, size_t n)
-                                   _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (strncat, char *, (char *dest, const char *src, size_t n));
+_GL_FUNCDECL_RPL (strncat, char *,
+                  (char *restrict dest, const char *restrict src, size_t n)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (strncat, char *,
+                  (char *restrict dest, const char *restrict src, size_t n));
 # else
-_GL_CXXALIAS_SYS (strncat, char *, (char *dest, const char *src, size_t n));
+_GL_CXXALIAS_SYS (strncat, char *,
+                  (char *restrict dest, const char *restrict src, size_t n));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (strncat);
diff --git a/lib/sys_socket.in.h b/lib/sys_socket.in.h
index 8e013e6..948d689 100644
--- a/lib/sys_socket.in.h
+++ b/lib/sys_socket.in.h
@@ -346,14 +346,20 @@ _GL_WARN_ON_USE (connect, "connect is not always POSIX compliant - "
 #   define accept rpl_accept
 #  endif
 _GL_FUNCDECL_RPL (accept, int,
-                  (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                  (int fd,
+                   struct sockaddr *restrict addr,
+                   socklen_t *restrict addrlen));
 _GL_CXXALIAS_RPL (accept, int,
-                  (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                  (int fd,
+                   struct sockaddr *restrict addr,
+                   socklen_t *restrict addrlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the third parameter is
-                                                       void *addrlen.  */
+                        void *addrlen.  */
 _GL_CXXALIAS_SYS_CAST (accept, int,
-                       (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                       (int fd,
+                        struct sockaddr *restrict addr,
+                        socklen_t *restrict addrlen));
 # endif
 _GL_CXXALIASWARN (accept);
 #elif @HAVE_WINSOCK2_H@
@@ -404,15 +410,18 @@ _GL_WARN_ON_USE (bind, "bind is not always POSIX compliant - "
 #   define getpeername rpl_getpeername
 #  endif
 _GL_FUNCDECL_RPL (getpeername, int,
-                  (int fd, struct sockaddr *addr, socklen_t *addrlen)
+                  (int fd, struct sockaddr *restrict addr,
+                   socklen_t *restrict addrlen)
                   _GL_ARG_NONNULL ((2, 3)));
 _GL_CXXALIAS_RPL (getpeername, int,
-                  (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                  (int fd, struct sockaddr *restrict addr,
+                   socklen_t *restrict addrlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the third parameter is
-                                                       void *addrlen.  */
+                        void *addrlen.  */
 _GL_CXXALIAS_SYS_CAST (getpeername, int,
-                       (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                       (int fd, struct sockaddr *restrict addr,
+                        socklen_t *restrict addrlen));
 # endif
 _GL_CXXALIASWARN (getpeername);
 #elif @HAVE_WINSOCK2_H@
@@ -433,15 +442,18 @@ _GL_WARN_ON_USE (getpeername, "getpeername is not always POSIX compliant - "
 #   define getsockname rpl_getsockname
 #  endif
 _GL_FUNCDECL_RPL (getsockname, int,
-                  (int fd, struct sockaddr *addr, socklen_t *addrlen)
+                  (int fd, struct sockaddr *restrict addr,
+                   socklen_t *restrict addrlen)
                   _GL_ARG_NONNULL ((2, 3)));
 _GL_CXXALIAS_RPL (getsockname, int,
-                  (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                  (int fd, struct sockaddr *restrict addr,
+                   socklen_t *restrict addrlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the third parameter is
-                                                       void *addrlen.  */
+                        void *addrlen.  */
 _GL_CXXALIAS_SYS_CAST (getsockname, int,
-                       (int fd, struct sockaddr *addr, socklen_t *addrlen));
+                       (int fd, struct sockaddr *restrict addr,
+                        socklen_t *restrict addrlen));
 # endif
 _GL_CXXALIASWARN (getsockname);
 #elif @HAVE_WINSOCK2_H@
@@ -461,16 +473,19 @@ _GL_WARN_ON_USE (getsockname, "getsockname is not always POSIX compliant - "
 #   undef getsockopt
 #   define getsockopt rpl_getsockopt
 #  endif
-_GL_FUNCDECL_RPL (getsockopt, int, (int fd, int level, int optname,
-                                    void *optval, socklen_t *optlen)
-                                   _GL_ARG_NONNULL ((4, 5)));
-_GL_CXXALIAS_RPL (getsockopt, int, (int fd, int level, int optname,
-                                    void *optval, socklen_t *optlen));
+_GL_FUNCDECL_RPL (getsockopt, int,
+                  (int fd, int level, int optname,
+                   void *restrict optval, socklen_t *restrict optlen)
+                  _GL_ARG_NONNULL ((4, 5)));
+_GL_CXXALIAS_RPL (getsockopt, int,
+                  (int fd, int level, int optname,
+                   void *restrict optval, socklen_t *restrict optlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the fifth parameter is
                                                        void *optlen.  */
-_GL_CXXALIAS_SYS_CAST (getsockopt, int, (int fd, int level, int optname,
-                                         void *optval, socklen_t *optlen));
+_GL_CXXALIAS_SYS_CAST (getsockopt, int,
+                       (int fd, int level, int optname,
+                        void *restrict optval, socklen_t *restrict optlen));
 # endif
 _GL_CXXALIASWARN (getsockopt);
 #elif @HAVE_WINSOCK2_H@
@@ -571,18 +586,21 @@ _GL_WARN_ON_USE (send, "send is not always POSIX compliant - "
 #   define recvfrom rpl_recvfrom
 #  endif
 _GL_FUNCDECL_RPL (recvfrom, ssize_t,
-                  (int fd, void *buf, size_t len, int flags,
-                   struct sockaddr *from, socklen_t *fromlen)
+                  (int fd, void *restrict buf, size_t len, int flags,
+                   struct sockaddr *restrict from,
+                   socklen_t *restrict fromlen)
                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (recvfrom, ssize_t,
-                  (int fd, void *buf, size_t len, int flags,
-                   struct sockaddr *from, socklen_t *fromlen));
+                  (int fd, void *restrict buf, size_t len, int flags,
+                   struct sockaddr *restrict from,
+                   socklen_t *restrict fromlen));
 # else
 /* Need to cast, because on Solaris 10 systems, the sixth parameter is
                                                void *fromlen.  */
 _GL_CXXALIAS_SYS_CAST (recvfrom, ssize_t,
-                       (int fd, void *buf, size_t len, int flags,
-                        struct sockaddr *from, socklen_t *fromlen));
+                       (int fd, void *restrict buf, size_t len, int flags,
+                        struct sockaddr *restrict from,
+                        socklen_t *restrict fromlen));
 # endif
 _GL_CXXALIASWARN (recvfrom);
 #elif @HAVE_WINSOCK2_H@
diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h
index 65661f4..a27a79a 100644
--- a/lib/sys_stat.in.h
+++ b/lib/sys_stat.in.h
@@ -455,18 +455,22 @@ _GL_WARN_ON_USE (fstat, "fstat has portability problems - "
 #   define fstatat rpl_fstatat
 #  endif
 _GL_FUNCDECL_RPL (fstatat, int,
-                  (int fd, char const *name, struct stat *st, int flags)
+                  (int fd, char const *restrict name, struct stat *restrict st,
+                   int flags)
                   _GL_ARG_NONNULL ((2, 3)));
 _GL_CXXALIAS_RPL (fstatat, int,
-                  (int fd, char const *name, struct stat *st, int flags));
+                  (int fd, char const *restrict name, struct stat *restrict st,
+                   int flags));
 # else
 #  if !@HAVE_FSTATAT@
 _GL_FUNCDECL_SYS (fstatat, int,
-                  (int fd, char const *name, struct stat *st, int flags)
+                  (int fd, char const *restrict name, struct stat *restrict st,
+                   int flags)
                   _GL_ARG_NONNULL ((2, 3)));
 #  endif
 _GL_CXXALIAS_SYS (fstatat, int,
-                  (int fd, char const *name, struct stat *st, int flags));
+                  (int fd, char const *restrict name, struct stat *restrict st,
+                   int flags));
 # endif
 _GL_CXXALIASWARN (fstatat);
 #elif @GNULIB_OVERRIDES_STRUCT_STAT@
@@ -548,17 +552,21 @@ _GL_WARN_ON_USE (lchmod, "lchmod is unportable - "
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   define lstat stat
 #  endif
-_GL_CXXALIAS_RPL_1 (lstat, stat, int, (const char *name, struct stat *buf));
+_GL_CXXALIAS_RPL_1 (lstat, stat, int,
+                    (const char *restrict name, struct stat *restrict buf));
 # elif @REPLACE_LSTAT@
 #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #   undef lstat
 #   define lstat rpl_lstat
 #  endif
-_GL_FUNCDECL_RPL (lstat, int, (const char *name, struct stat *buf)
-                              _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (lstat, int, (const char *name, struct stat *buf));
+_GL_FUNCDECL_RPL (lstat, int,
+                  (const char *restrict name, struct stat *restrict buf)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (lstat, int,
+                  (const char *restrict name, struct stat *restrict buf));
 # else
-_GL_CXXALIAS_SYS (lstat, int, (const char *name, struct stat *buf));
+_GL_CXXALIAS_SYS (lstat, int,
+                  (const char *restrict name, struct stat *restrict buf));
 # endif
 # if @HAVE_LSTAT@
 _GL_CXXALIASWARN (lstat);
@@ -771,7 +779,7 @@ _GL_WARN_ON_USE (mknodat, "mknodat is not portable - "
 #    define stat(name, st) rpl_stat (name, st)
 #   endif /* !_LARGE_FILES */
 #  endif /* !@GNULIB_OVERRIDES_STRUCT_STAT@ */
-_GL_EXTERN_C int stat (const char *name, struct stat *buf)
+_GL_EXTERN_C int stat (const char *restrict name, struct stat *restrict buf)
                       _GL_ARG_NONNULL ((1, 2));
 # endif
 #elif @GNULIB_OVERRIDES_STRUCT_STAT@
diff --git a/lib/time.in.h b/lib/time.in.h
index 7304668..e10e90c 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -286,14 +286,17 @@ _GL_CXXALIASWARN (ctime);
 #   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 #    define strftime rpl_strftime
 #   endif
-_GL_FUNCDECL_RPL (strftime, size_t, (char *__buf, size_t __bufsize,
-                                     const char *__fmt, const struct tm *__tp)
-                                    _GL_ARG_NONNULL ((1, 3, 4)));
-_GL_CXXALIAS_RPL (strftime, size_t, (char *__buf, size_t __bufsize,
-                                     const char *__fmt, const struct tm *__tp));
+_GL_FUNCDECL_RPL (strftime, size_t,
+                  (char *restrict __buf, size_t __bufsize,
+                   const char *restrict __fmt, const struct tm *restrict __tp)
+                  _GL_ARG_NONNULL ((1, 3, 4)));
+_GL_CXXALIAS_RPL (strftime, size_t,
+                  (char *restrict __buf, size_t __bufsize,
+                   const char *restrict __fmt, const struct tm *restrict __tp));
 #  else
-_GL_CXXALIAS_SYS (strftime, size_t, (char *__buf, size_t __bufsize,
-                                     const char *__fmt, const struct tm *__tp));
+_GL_CXXALIAS_SYS (strftime, size_t,
+                  (char *restrict __buf, size_t __bufsize,
+                   const char *restrict __fmt, const struct tm *restrict __tp));
 #  endif
 #  if __GLIBC__ >= 2
 _GL_CXXALIASWARN (strftime);
diff --git a/lib/unistd.in.h b/lib/unistd.in.h
index 6db7ff2..1454d7e 100644
--- a/lib/unistd.in.h
+++ b/lib/unistd.in.h
@@ -1370,18 +1370,22 @@ _GL_CXXALIASWARN (read);
 #   define readlink rpl_readlink
 #  endif
 _GL_FUNCDECL_RPL (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize)
+                  (const char *restrict file,
+                   char *restrict buf, size_t bufsize)
                   _GL_ARG_NONNULL ((1, 2)));
 _GL_CXXALIAS_RPL (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize));
+                  (const char *restrict file,
+                   char *restrict buf, size_t bufsize));
 # else
 #  if !@HAVE_READLINK@
 _GL_FUNCDECL_SYS (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize)
+                  (const char *restrict file,
+                   char *restrict buf, size_t bufsize)
                   _GL_ARG_NONNULL ((1, 2)));
 #  endif
 _GL_CXXALIAS_SYS (readlink, ssize_t,
-                  (const char *file, char *buf, size_t bufsize));
+                  (const char *restrict file,
+                   char *restrict buf, size_t bufsize));
 # endif
 _GL_CXXALIASWARN (readlink);
 #elif defined GNULIB_POSIXCHECK
@@ -1399,18 +1403,22 @@ _GL_WARN_ON_USE (readlink, "readlink is unportable - "
 #   define readlinkat rpl_readlinkat
 #  endif
 _GL_FUNCDECL_RPL (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len)
+                  (int fd, char const *restrict file,
+                   char *restrict buf, size_t len)
                   _GL_ARG_NONNULL ((2, 3)));
 _GL_CXXALIAS_RPL (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len));
+                  (int fd, char const *restrict file,
+                   char *restrict buf, size_t len));
 # else
 #  if !@HAVE_READLINKAT@
 _GL_FUNCDECL_SYS (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len)
+                  (int fd, char const *restrict file,
+                   char *restrict buf, size_t len)
                   _GL_ARG_NONNULL ((2, 3)));
 #  endif
 _GL_CXXALIAS_SYS (readlinkat, ssize_t,
-                  (int fd, char const *file, char *buf, size_t len));
+                  (int fd, char const *restrict file,
+                   char *restrict buf, size_t len));
 # endif
 _GL_CXXALIASWARN (readlinkat);
 #elif defined GNULIB_POSIXCHECK
diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index 74cd670..040065a 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -244,16 +244,20 @@ _GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - "
 #   define mbrtowc rpl_mbrtowc
 #  endif
 _GL_FUNCDECL_RPL (mbrtowc, size_t,
-                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n,
+                   mbstate_t *restrict ps));
 _GL_CXXALIAS_RPL (mbrtowc, size_t,
-                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n,
+                   mbstate_t *restrict ps));
 # else
 #  if !@HAVE_MBRTOWC@
 _GL_FUNCDECL_SYS (mbrtowc, size_t,
-                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n,
+                   mbstate_t *restrict ps));
 #  endif
 _GL_CXXALIAS_SYS (mbrtowc, size_t,
-                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+                  (wchar_t *restrict pwc, const char *restrict s, size_t n,
+                   mbstate_t *restrict ps));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (mbrtowc);
@@ -274,13 +278,17 @@ _GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - "
 #   undef mbrlen
 #   define mbrlen rpl_mbrlen
 #  endif
-_GL_FUNCDECL_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
-_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+_GL_FUNCDECL_RPL (mbrlen, size_t,
+                  (const char *restrict s, size_t n, mbstate_t *restrict ps));
+_GL_CXXALIAS_RPL (mbrlen, size_t,
+                  (const char *restrict s, size_t n, mbstate_t *restrict ps));
 # else
 #  if !@HAVE_MBRLEN@
-_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+_GL_FUNCDECL_SYS (mbrlen, size_t,
+                  (const char *restrict s, size_t n, mbstate_t *restrict ps));
 #  endif
-_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+_GL_CXXALIAS_SYS (mbrlen, size_t,
+                  (const char *restrict s, size_t n, mbstate_t *restrict ps));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (mbrlen);
@@ -302,20 +310,26 @@ _GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - "
 #   define mbsrtowcs rpl_mbsrtowcs
 #  endif
 _GL_FUNCDECL_RPL (mbsrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps)
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (mbsrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t len,
-                   mbstate_t *ps));
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t len,
+                   mbstate_t *restrict ps));
 # else
 #  if !@HAVE_MBSRTOWCS@
 _GL_FUNCDECL_SYS (mbsrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps)
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 #  endif
 _GL_CXXALIAS_SYS (mbsrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t len,
-                   mbstate_t *ps));
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t len,
+                   mbstate_t *restrict ps));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (mbsrtowcs);
@@ -337,22 +351,26 @@ _GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - "
 #   define mbsnrtowcs rpl_mbsnrtowcs
 #  endif
 _GL_FUNCDECL_RPL (mbsnrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps)
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t srclen, size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (mbsnrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps));
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t srclen, size_t len,
+                   mbstate_t *restrict ps));
 # else
 #  if !@HAVE_MBSNRTOWCS@
 _GL_FUNCDECL_SYS (mbsnrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps)
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t srclen, size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 #  endif
 _GL_CXXALIAS_SYS (mbsnrtowcs, size_t,
-                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps));
+                  (wchar_t *restrict dest,
+                   const char **restrict srcp, size_t srclen, size_t len,
+                   mbstate_t *restrict ps));
 # endif
 _GL_CXXALIASWARN (mbsnrtowcs);
 #elif defined GNULIB_POSIXCHECK
@@ -371,13 +389,17 @@ _GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - "
 #   undef wcrtomb
 #   define wcrtomb rpl_wcrtomb
 #  endif
-_GL_FUNCDECL_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
-_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+_GL_FUNCDECL_RPL (wcrtomb, size_t,
+                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));
+_GL_CXXALIAS_RPL (wcrtomb, size_t,
+                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));
 # else
 #  if !@HAVE_WCRTOMB@
-_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+_GL_FUNCDECL_SYS (wcrtomb, size_t,
+                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));
 #  endif
-_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+_GL_CXXALIAS_SYS (wcrtomb, size_t,
+                  (char *restrict s, wchar_t wc, mbstate_t *restrict ps));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcrtomb);
@@ -399,20 +421,26 @@ _GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - "
 #   define wcsrtombs rpl_wcsrtombs
 #  endif
 _GL_FUNCDECL_RPL (wcsrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps)
+                  (char *restrict dest, const wchar_t **restrict srcp,
+                   size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (wcsrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t len,
-                   mbstate_t *ps));
+                  (char *restrict dest, const wchar_t **restrict srcp,
+                   size_t len,
+                   mbstate_t *restrict ps));
 # else
 #  if !@HAVE_WCSRTOMBS@
 _GL_FUNCDECL_SYS (wcsrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps)
+                  (char *restrict dest, const wchar_t **restrict srcp,
+                   size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 #  endif
 _GL_CXXALIAS_SYS (wcsrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t len,
-                   mbstate_t *ps));
+                  (char *restrict dest, const wchar_t **restrict srcp,
+                   size_t len,
+                   mbstate_t *restrict ps));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsrtombs);
@@ -434,22 +462,30 @@ _GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - "
 #   define wcsnrtombs rpl_wcsnrtombs
 #  endif
 _GL_FUNCDECL_RPL (wcsnrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps)
+                  (char *restrict dest,
+                   const wchar_t **restrict srcp, size_t srclen,
+                   size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 _GL_CXXALIAS_RPL (wcsnrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps));
+                  (char *restrict dest,
+                   const wchar_t **restrict srcp, size_t srclen,
+                   size_t len,
+                   mbstate_t *restrict ps));
 # else
 #  if !@HAVE_WCSNRTOMBS@ || (defined __cplusplus && defined __sun)
 _GL_FUNCDECL_SYS (wcsnrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps)
+                  (char *restrict dest,
+                   const wchar_t **restrict srcp, size_t srclen,
+                   size_t len,
+                   mbstate_t *restrict ps)
                   _GL_ARG_NONNULL ((2)));
 #  endif
 _GL_CXXALIAS_SYS (wcsnrtombs, size_t,
-                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
-                   mbstate_t *ps));
+                  (char *restrict dest,
+                   const wchar_t **restrict srcp, size_t srclen,
+                   size_t len,
+                   mbstate_t *restrict ps));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsnrtombs);
@@ -547,10 +583,12 @@ _GL_WARN_ON_USE (wmemcmp, "wmemcmp is unportable - "
 #if @GNULIB_WMEMCPY@
 # if !@HAVE_WMEMCPY@
 _GL_FUNCDECL_SYS (wmemcpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest,
+                   const wchar_t *restrict src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wmemcpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest,
+                   const wchar_t *restrict src, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wmemcpy);
 # endif
@@ -640,9 +678,11 @@ _GL_WARN_ON_USE (wcsnlen, "wcsnlen is unportable - "
 /* Copy SRC to DEST.  */
 #if @GNULIB_WCSCPY@
 # if !@HAVE_WCSCPY@
-_GL_FUNCDECL_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_FUNCDECL_SYS (wcscpy, wchar_t *,
+                  (wchar_t *restrict dest, const wchar_t *restrict src));
 # endif
-_GL_CXXALIAS_SYS (wcscpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_CXXALIAS_SYS (wcscpy, wchar_t *,
+                  (wchar_t *restrict dest, const wchar_t *restrict src));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcscpy);
 # endif
@@ -658,9 +698,11 @@ _GL_WARN_ON_USE (wcscpy, "wcscpy is unportable - "
 /* Copy SRC to DEST, returning the address of the terminating L'\0' in DEST.  */
 #if @GNULIB_WCPCPY@
 # if !@HAVE_WCPCPY@
-_GL_FUNCDECL_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_FUNCDECL_SYS (wcpcpy, wchar_t *,
+                  (wchar_t *restrict dest, const wchar_t *restrict src));
 # endif
-_GL_CXXALIAS_SYS (wcpcpy, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_CXXALIAS_SYS (wcpcpy, wchar_t *,
+                  (wchar_t *restrict dest, const wchar_t *restrict src));
 _GL_CXXALIASWARN (wcpcpy);
 #elif defined GNULIB_POSIXCHECK
 # undef wcpcpy
@@ -675,10 +717,12 @@ _GL_WARN_ON_USE (wcpcpy, "wcpcpy is unportable - "
 #if @GNULIB_WCSNCPY@
 # if !@HAVE_WCSNCPY@
 _GL_FUNCDECL_SYS (wcsncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest,
+                   const wchar_t *restrict src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wcsncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest,
+                   const wchar_t *restrict src, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsncpy);
 # endif
@@ -696,10 +740,12 @@ _GL_WARN_ON_USE (wcsncpy, "wcsncpy is unportable - "
 #if @GNULIB_WCPNCPY@
 # if !@HAVE_WCPNCPY@
 _GL_FUNCDECL_SYS (wcpncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest,
+                   const wchar_t *restrict src, size_t n));
 # endif
 _GL_CXXALIAS_SYS (wcpncpy, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest,
+                   const wchar_t *restrict src, size_t n));
 _GL_CXXALIASWARN (wcpncpy);
 #elif defined GNULIB_POSIXCHECK
 # undef wcpncpy
@@ -713,9 +759,11 @@ _GL_WARN_ON_USE (wcpncpy, "wcpncpy is unportable - "
 /* Append SRC onto DEST.  */
 #if @GNULIB_WCSCAT@
 # if !@HAVE_WCSCAT@
-_GL_FUNCDECL_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_FUNCDECL_SYS (wcscat, wchar_t *,
+                  (wchar_t *restrict dest, const wchar_t *restrict src));
 # endif
-_GL_CXXALIAS_SYS (wcscat, wchar_t *, (wchar_t *dest, const wchar_t *src));
+_GL_CXXALIAS_SYS (wcscat, wchar_t *,
+                  (wchar_t *restrict dest, const wchar_t *restrict src));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcscat);
 # endif
@@ -732,10 +780,12 @@ _GL_WARN_ON_USE (wcscat, "wcscat is unportable - "
 #if @GNULIB_WCSNCAT@
 # if !@HAVE_WCSNCAT@
 _GL_FUNCDECL_SYS (wcsncat, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest, const wchar_t *restrict src,
+                   size_t n));
 # endif
 _GL_CXXALIAS_SYS (wcsncat, wchar_t *,
-                  (wchar_t *dest, const wchar_t *src, size_t n));
+                  (wchar_t *restrict dest, const wchar_t *restrict src,
+                   size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsncat);
 # endif
@@ -848,9 +898,11 @@ _GL_WARN_ON_USE (wcscoll, "wcscoll is unportable - "
    original strings.  */
 #if @GNULIB_WCSXFRM@
 # if !@HAVE_WCSXFRM@
-_GL_FUNCDECL_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n));
+_GL_FUNCDECL_SYS (wcsxfrm, size_t,
+                  (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n));
 # endif
-_GL_CXXALIAS_SYS (wcsxfrm, size_t, (wchar_t *s1, const wchar_t *s2, size_t n));
+_GL_CXXALIAS_SYS (wcsxfrm, size_t,
+                  (wchar_t *restrict s1, const wchar_t *restrict s2, size_t n));
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsxfrm);
 # endif
@@ -1016,7 +1068,8 @@ _GL_WARN_ON_USE (wcspbrk, "wcspbrk is unportable - "
 #if @GNULIB_WCSSTR@
 # if !@HAVE_WCSSTR@
 _GL_FUNCDECL_SYS (wcsstr, wchar_t *,
-                  (const wchar_t *haystack, const wchar_t *needle)
+                  (const wchar_t *restrict haystack,
+                   const wchar_t *restrict needle)
                   _GL_ATTRIBUTE_PURE);
 # endif
   /* On some systems, this function is defined as an overloaded function:
@@ -1025,14 +1078,18 @@ _GL_FUNCDECL_SYS (wcsstr, wchar_t *,
          wchar_t * std::wcsstr (wchar_t *, const wchar_t *);
        }  */
 _GL_CXXALIAS_SYS_CAST2 (wcsstr,
-                        wchar_t *, (const wchar_t *, const wchar_t *),
-                        const wchar_t *, (const wchar_t *, const wchar_t *));
+                        wchar_t *,
+                        (const wchar_t *restrict, const wchar_t *restrict),
+                        const wchar_t *,
+                        (const wchar_t *restrict, const wchar_t *restrict));
 # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 10) && !defined __UCLIBC__) \
      && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
 _GL_CXXALIASWARN1 (wcsstr, wchar_t *,
-                   (wchar_t *haystack, const wchar_t *needle));
+                   (wchar_t *restrict haystack,
+                    const wchar_t *restrict needle));
 _GL_CXXALIASWARN1 (wcsstr, const wchar_t *,
-                   (const wchar_t *haystack, const wchar_t *needle));
+                   (const wchar_t *restrict haystack,
+                    const wchar_t *restrict needle));
 # elif __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsstr);
 # endif
@@ -1053,16 +1110,20 @@ _GL_WARN_ON_USE (wcsstr, "wcsstr is unportable - "
 #   define wcstok rpl_wcstok
 #  endif
 _GL_FUNCDECL_RPL (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t *restrict wcs, const wchar_t *restrict delim,
+                   wchar_t **restrict ptr));
 _GL_CXXALIAS_RPL (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t *restrict wcs, const wchar_t *restrict delim,
+                   wchar_t **restrict ptr));
 # else
 #  if !@HAVE_WCSTOK@
 _GL_FUNCDECL_SYS (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t *restrict wcs, const wchar_t *restrict delim,
+                   wchar_t **restrict ptr));
 #  endif
 _GL_CXXALIAS_SYS (wcstok, wchar_t *,
-                  (wchar_t *wcs, const wchar_t *delim, wchar_t **ptr));
+                  (wchar_t *restrict wcs, const wchar_t *restrict delim,
+                   wchar_t **restrict ptr));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcstok);
@@ -1114,19 +1175,27 @@ _GL_WARN_ON_USE (wcswidth, "wcswidth is unportable - "
 #   undef wcsftime
 #   define wcsftime rpl_wcsftime
 #  endif
-_GL_FUNCDECL_RPL (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
-                                     const wchar_t *__fmt, const struct tm *__tp)
-                                    _GL_ARG_NONNULL ((1, 3, 4)));
-_GL_CXXALIAS_RPL (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
-                                     const wchar_t *__fmt, const struct tm *__tp));
+_GL_FUNCDECL_RPL (wcsftime, size_t,
+                  (wchar_t *restrict __buf, size_t __bufsize,
+                   const wchar_t *restrict __fmt,
+                   const struct tm *restrict __tp)
+                  _GL_ARG_NONNULL ((1, 3, 4)));
+_GL_CXXALIAS_RPL (wcsftime, size_t,
+                  (wchar_t *restrict __buf, size_t __bufsize,
+                   const wchar_t *restrict __fmt,
+                   const struct tm *restrict __tp));
 # else
 #  if !@HAVE_WCSFTIME@
-_GL_FUNCDECL_SYS (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
-                                     const wchar_t *__fmt, const struct tm *__tp)
-                                    _GL_ARG_NONNULL ((1, 3, 4)));
+_GL_FUNCDECL_SYS (wcsftime, size_t,
+                  (wchar_t *restrict __buf, size_t __bufsize,
+                   const wchar_t *restrict __fmt,
+                   const struct tm *restrict __tp)
+                  _GL_ARG_NONNULL ((1, 3, 4)));
 #  endif
-_GL_CXXALIAS_SYS (wcsftime, size_t, (wchar_t *__buf, size_t __bufsize,
-                                     const wchar_t *__fmt, const struct tm *__tp));
+_GL_CXXALIAS_SYS (wcsftime, size_t,
+                  (wchar_t *restrict __buf, size_t __bufsize,
+                   const wchar_t *restrict __fmt,
+                   const struct tm *restrict __tp));
 # endif
 # if __GLIBC__ >= 2
 _GL_CXXALIASWARN (wcsftime);
diff --git a/m4/iconv_h.m4 b/m4/iconv_h.m4
index 0c0164c..23d41c9 100644
--- a/m4/iconv_h.m4
+++ b/m4/iconv_h.m4
@@ -1,4 +1,4 @@
-# iconv_h.m4 serial 11
+# iconv_h.m4 serial 12
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -17,6 +17,8 @@ AC_DEFUN([gl_ICONV_H],
   dnl guaranteed by C89.
   gl_WARN_ON_USE_PREPARE([[#include <iconv.h>
     ]], [iconv iconv_open])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 dnl Unconditionally enables the replacement of <iconv.h>.
diff --git a/m4/inttypes.m4 b/m4/inttypes.m4
index d0487d6..224d0cd 100644
--- a/m4/inttypes.m4
+++ b/m4/inttypes.m4
@@ -1,4 +1,4 @@
-# inttypes.m4 serial 28
+# inttypes.m4 serial 29
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -28,6 +28,8 @@ AC_DEFUN_ONCE([gl_INTTYPES_INCOMPLETE],
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[#include <inttypes.h>
     ]], [imaxabs imaxdiv strtoimax strtoumax])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 # Ensure that the PRI* and SCN* macros are defined appropriately.
diff --git a/m4/monetary_h.m4 b/m4/monetary_h.m4
index 0b3c7c7..556a265 100644
--- a/m4/monetary_h.m4
+++ b/m4/monetary_h.m4
@@ -1,4 +1,4 @@
-# monetary_h.m4 serial 4
+# monetary_h.m4 serial 5
 dnl Copyright (C) 2017-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -38,6 +38,8 @@ AC_DEFUN_ONCE([gl_MONETARY_H],
     gl_WARN_ON_USE_PREPARE([[
       #include <monetary.h>
       ]], [strfmon_l])
+
+    AC_REQUIRE([AC_C_RESTRICT])
   else
     MONETARY_H=''
   fi
diff --git a/m4/search_h.m4 b/m4/search_h.m4
index 10d608f..f21e7cc 100644
--- a/m4/search_h.m4
+++ b/m4/search_h.m4
@@ -1,4 +1,4 @@
-# search_h.m4 serial 10
+# search_h.m4 serial 11
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -40,6 +40,8 @@ AC_DEFUN([gl_SEARCH_H],
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[#include <search.h>
     ]], [tdelete tfind tsearch twalk])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_SEARCH_MODULE_INDICATOR],
diff --git a/m4/signal_h.m4 b/m4/signal_h.m4
index 0868438..b262980 100644
--- a/m4/signal_h.m4
+++ b/m4/signal_h.m4
@@ -1,4 +1,4 @@
-# signal_h.m4 serial 18
+# signal_h.m4 serial 19
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -34,6 +34,8 @@ AC_DEFUN([gl_SIGNAL_H],
     ]], [pthread_sigmask sigaction
     sigaddset sigdelset sigemptyset sigfillset sigismember
     sigpending sigprocmask])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_CHECK_TYPE_SIGSET_T],
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index c603b51..5f968bc 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,4 +1,4 @@
-# stdio_h.m4 serial 49
+# stdio_h.m4 serial 50
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -107,6 +107,8 @@ AC_DEFUN([gl_STDIO_H],
   gl_WARN_ON_USE_PREPARE([[#include <stdio.h>
     ]], [dprintf fpurge fseeko ftello getdelim getline gets pclose popen
     renameat snprintf tmpfile vdprintf vsnprintf])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_STDIO_MODULE_INDICATOR],
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 61a3e31..743066a 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 48
+# stdlib_h.m4 serial 49
 dnl Copyright (C) 2007-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -27,6 +27,8 @@ AC_DEFUN([gl_STDLIB_H],
     posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
     realpath rpmatch secure_getenv setenv setstate setstate_r srandom
     srandom_r strtod strtold strtoll strtoull unlockpt unsetenv])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
diff --git a/m4/string_h.m4 b/m4/string_h.m4
index 4c1f685..cc51337 100644
--- a/m4/string_h.m4
+++ b/m4/string_h.m4
@@ -5,7 +5,7 @@
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
 
-# serial 22
+# serial 23
 
 # Written by Paul Eggert.
 
@@ -18,7 +18,6 @@ AC_DEFUN([gl_HEADER_STRING_H],
 
 AC_DEFUN([gl_HEADER_STRING_H_BODY],
 [
-  AC_REQUIRE([AC_C_RESTRICT])
   AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
   gl_NEXT_HEADERS([string.h])
 
@@ -30,6 +29,8 @@ AC_DEFUN([gl_HEADER_STRING_H_BODY],
     [ffsl ffsll memmem mempcpy memrchr rawmemchr stpcpy stpncpy strchrnul
      strdup strncat strndup strnlen strpbrk strsep strcasestr strtok_r
      strerror_r strsignal strverscmp])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_STRING_MODULE_INDICATOR],
diff --git a/m4/sys_socket_h.m4 b/m4/sys_socket_h.m4
index 1471aea..bf902f0 100644
--- a/m4/sys_socket_h.m4
+++ b/m4/sys_socket_h.m4
@@ -1,4 +1,4 @@
-# sys_socket_h.m4 serial 24
+# sys_socket_h.m4 serial 25
 dnl Copyright (C) 2005-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -95,6 +95,8 @@ AC_DEFUN([gl_HEADER_SYS_SOCKET],
 #include <sys/socket.h>
     ]], [socket connect accept bind getpeername getsockname getsockopt
     listen recv send recvfrom sendto setsockopt shutdown accept4])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_PREREQ_SYS_H_SOCKET],
diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4
index a5f35d4..30d60d9 100644
--- a/m4/sys_stat_h.m4
+++ b/m4/sys_stat_h.m4
@@ -1,4 +1,4 @@
-# sys_stat_h.m4 serial 32   -*- Autoconf -*-
+# sys_stat_h.m4 serial 33   -*- Autoconf -*-
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -48,7 +48,9 @@ AC_DEFUN([gl_HEADER_SYS_STAT_H],
   gl_WARN_ON_USE_PREPARE([[#include <sys/stat.h>
     ]], [fchmodat fstat fstatat futimens lchmod lstat mkdirat mkfifo mkfifoat
     mknod mknodat stat utimensat])
-]) # gl_HEADER_SYS_STAT_H
+
+  AC_REQUIRE([AC_C_RESTRICT])
+])
 
 AC_DEFUN([gl_SYS_STAT_MODULE_INDICATOR],
 [
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index aae0ae2..d0f8932 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -2,7 +2,7 @@
 
 # Copyright (C) 2000-2001, 2003-2007, 2009-2020 Free Software Foundation, Inc.
 
-# serial 11
+# serial 12
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -19,10 +19,12 @@ AC_DEFUN([gl_HEADER_TIME_H],
 
 AC_DEFUN([gl_HEADER_TIME_H_BODY],
 [
-  AC_REQUIRE([AC_C_RESTRICT])
   AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
+
   gl_NEXT_HEADERS([time.h])
   AC_REQUIRE([gl_CHECK_TYPE_STRUCT_TIMESPEC])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 dnl Check whether 'struct timespec' is declared
diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4
index ea2bb01..e776f3b 100644
--- a/m4/unistd_h.m4
+++ b/m4/unistd_h.m4
@@ -1,4 +1,4 @@
-# unistd_h.m4 serial 77
+# unistd_h.m4 serial 78
 dnl Copyright (C) 2006-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -48,6 +48,8 @@ AC_DEFUN([gl_UNISTD_H],
     group_member isatty lchown link linkat lseek pipe pipe2 pread pwrite
     readlink readlinkat rmdir sethostname sleep symlink symlinkat
     truncate ttyname_r unlink unlinkat usleep])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 AC_DEFUN([gl_UNISTD_MODULE_INDICATOR],
diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4
index d1b7228..be09020 100644
--- a/m4/wchar_h.m4
+++ b/m4/wchar_h.m4
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.
 
 dnl Written by Eric Blake.
 
-# wchar_h.m4 serial 44
+# wchar_h.m4 serial 45
 
 AC_DEFUN([gl_WCHAR_H],
 [
@@ -57,6 +57,8 @@ AC_DEFUN([gl_WCHAR_H],
      wcsncmp wcscasecmp wcsncasecmp wcscoll wcsxfrm wcsdup wcschr wcsrchr
      wcscspn wcsspn wcspbrk wcsstr wcstok wcswidth wcsftime
     ])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
 
 dnl Check whether <wchar.h> is usable at all.



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: restrict - summary
  2020-02-17 21:19     ` restrict - summary Bruno Haible
  2020-02-22 22:51       ` Bruno Haible
@ 2020-02-23 12:39       ` Bruno Haible
  2020-02-23 13:30       ` Bruno Haible
  2 siblings, 0 replies; 20+ messages in thread
From: Bruno Haible @ 2020-02-23 12:39 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

[-- Attachment #1: Type: text/plain, Size: 4975 bytes --]

Here comes the second part: Use of 'restrict' in non-POSIX function
declarations, excluding libunistring code.


2020-02-23  Bruno Haible  <bruno@clisp.org>

	crypto/gc: Use 'restrict'.
	* lib/gc.h (gc_pbkdf2_hmac, gc_pbkdf2_sha1): Use 'restrict'.
	* m4/gc.m4 (gl_GC): Require AC_C_RESTRICT.

	crypto/hmac-*: Use 'restrict'.
	* lib/hmac.h (hmac_md5, hmac_sha1, hmac_sha256, hmac_sha512): Use
	'restrict'.
	* modules/crypto/hmac-md5 (configure.ac): Require AC_C_RESTRICT.
	* modules/crypto/hmac-sha1 (configure.ac): Likewise.
	* modules/crypto/hmac-sha256 (configure.ac): Likewise.
	* modules/crypto/hmac-sha512 (configure.ac): Likewise.

	crypto/sm3: Use 'restrict'.
	* lib/sm3.h (sm3_finish_ctx, sm3_read_ctx, sm3_buffer): Use 'restrict'.
	* m4/sm3.m4 (gl_SM3): Require AC_C_RESTRICT.

	crypto/*-buffer: Use 'restrict'.
	* lib/gl_openssl.h (GL_CRYPTO_FN (_finish_ctx), GL_CRYPTO_FN (_buffer),
	GL_CRYPTO_FN (_read_ctx)): Use 'restrict'.

	crypto/sha512-buffer: Use 'restrict'.
	* lib/sha512.h (sha512_finish_ctx, sha384_finish_ctx, sha512_read_ctx,
	sha384_read_ctx, sha512_buffer, sha384_buffer): Use 'restrict'.
	* modules/crypto/sha512-buffer (configure.ac): Require AC_C_RESTRICT.

	crypto/sha256-buffer: Use 'restrict'.
	* lib/sha256.h (sha256_finish_ctx, sha224_finish_ctx, sha256_read_ctx,
	sha224_read_ctx, sha256_buffer, sha224_buffer): Use 'restrict'.
	* modules/crypto/sha256-buffer (configure.ac): Require AC_C_RESTRICT.

	crypto/sha1-buffer: Use 'restrict'.
	* lib/sha1.h (sha1_finish_ctx, sha1_read_ctx, sha1_buffer): Use
	'restrict'.
	* modules/crypto/sha1-buffer (configure.ac): Require AC_C_RESTRICT.

	crypto/md5-buffer: Use 'restrict'.
	* lib/md5.h (__md5_finish_ctx, __md5_read_ctx, __md5_buffer): Use
	'restrict'.
	* modules/crypto/md5-buffer (configure.ac): Require AC_C_RESTRICT.

	crypto/md4: Use 'restrict'.
	* lib/md4.h (md4_finish_ctx, md4_read_ctx, md4_buffer): Use 'restrict'.
	* modules/crypto/md4 (configure.ac): Require AC_C_RESTRICT.

	crypto/md2: Use 'restrict'.
	* lib/md2.h (md2_finish_ctx, md2_read_ctx, md2_buffer): Use 'restrict'.
	* modules/crypto/md2 (configure.ac): Require AC_C_RESTRICT.

	crypto/rijndael: Use 'restrict'.
	* lib/rijndael-api-fst.h (rijndaelBlockEncrypt, rijndaelPadEncrypt,
	rijndaelBlockDecrypt, rijndaelPadDecrypt): Use 'restrict'.
	* modules/crypto/rijndael (configure.ac): Require AC_C_RESTRICT.

	crypto/arctwo: Use 'restrict'.
	* lib/arctwo.h (arctwo_encrypt, arctwo_decrypt): Use 'restrict'.
	* modules/crypto/arctwo (configure.ac): Require AC_C_RESTRICT.

	crypto/arcfour: Use 'restrict'.
	* lib/arcfour.h (arcfour_stream): Use 'restrict'.
	* modules/crypto/arcfour (configure.ac): Require AC_C_RESTRICT.

	careadlinkat: Use 'restrict'.
	* lib/careadlinkat.h (careadlinkat): Use 'restrict'.
	* modules/careadlinkat (configure.ac): Require AC_C_RESTRICT.
	* modules/relocatable-prog-wrapper (configure.ac): Likewise.

	regex-quote: Use 'restrict'.
	* lib/regex-quote.h (regex_quote_copy): Use 'restrict'.
	* modules/regex-quote (configure.ac): Require AC_C_RESTRICT.

	system-quote: Use 'restrict'.
	* lib/system-quote.h (system_quote_copy): Use 'restrict'.
	* modules/system-quote (configure.ac): Require AC_C_RESTRICT.

	sh-quote: Use 'restrict'.
	* lib/sh-quote.h (shell_quote_copy): Use 'restrict'.
	* modules/sh-quote (configure.ac): Require AC_C_RESTRICT.

	quotearg: Use 'restrict'.
	* lib/quotearg.h (quotearg_buffer): Use 'restrict'.
	* m4/quotearg.m4 (gl_QUOTEARG): Require AC_C_RESTRICT.

	parse-datetime: Use 'restrict'.
	* lib/parse-datetime.h (parse_datetime, parse_datetime2): Use
	'restrict'.
	* m4/parse-datetime.m4 (gl_PARSE_DATETIME): Require AC_C_RESTRICT.

	nstrftime: Use 'restrict'.
	* lib/strftime.h (nstrftime): Use 'restrict'.
	* m4/nstrftime.m4 (gl_FUNC_GNU_STRFTIME): Require AC_C_RESTRICT.

	mbstok_r: Use 'restrict'.
	* lib/string.in.h (mbstok_r): Use 'restrict'.

	xmemcoll: Use 'restrict'.
	* lib/xmemcoll.h (xmemcoll): Use 'restrict'.
	* modules/xmemcoll (configure.ac): Require AC_C_RESTRICT.

	memcoll: Use 'restrict'.
	* lib/memcoll.h (memcoll): Use 'restrict'.
	* m4/memcoll.m4 (gl_MEMCOLL): Require AC_C_RESTRICT.

	vasnprintf: Use 'restrict'.
	* lib/vasnprintf.h (asnprintf, vasnprintf): Use 'restrict'.
	* modules/vasnprintf (configure.ac): Require AC_C_RESTRICT.

	c-vasnprintf: Use 'restrict'.
	* lib/c-vasnprintf.h (c_vasnprintf): Use 'restrict'.
	* modules/c-vasnprintf (configure.ac): Require AC_C_RESTRICT.

	c-vsnprintf: Use 'restrict'.
	* lib/c-vsnprintf.h (c_vsnprintf): Use 'restrict'.
	* modules/c-vsnprintf (configure.ac): Require AC_C_RESTRICT.

	c-snprintf: Use 'restrict'.
	* lib/c-snprintf.h (c_snprintf): Use 'restrict'.
	* modules/c-snprintf (configure.ac): Require AC_C_RESTRICT.

	astrxfrm: Use 'restrict'.
	* lib/astrxfrm.h (astrxfrm): Use 'restrict'.
	* modules/astrxfrm (configure.ac): Require AC_C_RESTRICT.

	amemxfrm: Use 'restrict'.
	* lib/amemxfrm.h (amemxfrm): Use 'restrict'.
	* modules/amemxfrm (configure.ac): Require AC_C_RESTRICT.


[-- Attachment #2: 0001-amemxfrm-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1616 bytes --]

From a765a46c498f55ab1291737a3f6167a58e75d948 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:04:46 +0100
Subject: [PATCH 01/29] amemxfrm: Use 'restrict'.

* lib/amemxfrm.h (amemxfrm): Use 'restrict'.
* modules/amemxfrm (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog        | 6 ++++++
 lib/amemxfrm.h   | 3 ++-
 modules/amemxfrm | 1 +
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index c21e04d..563d770 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2020-02-23  Bruno Haible  <bruno@clisp.org>
+
+	amemxfrm: Use 'restrict'.
+	* lib/amemxfrm.h (amemxfrm): Use 'restrict'.
+	* modules/amemxfrm (configure.ac): Require AC_C_RESTRICT.
+
 2020-02-22  Paul Eggert  <eggert@cs.ucla.edu>
 
 	fchmodat, lchmod: simplify
diff --git a/lib/amemxfrm.h b/lib/amemxfrm.h
index 7cfc283..2c91388 100644
--- a/lib/amemxfrm.h
+++ b/lib/amemxfrm.h
@@ -38,7 +38,8 @@ extern "C" {
    freshly allocated string is returned.  In both cases, *lengthp is set to the
    length of the returned string.
    Upon failure, return NULL, with errno set.  */
-extern char * amemxfrm (char *s, size_t n, char *resultbuf, size_t *lengthp);
+extern char * amemxfrm (char *restrict s, size_t n,
+                        char *restrict resultbuf, size_t *lengthp);
 
 
 #ifdef __cplusplus
diff --git a/modules/amemxfrm b/modules/amemxfrm
index fe7e1a4..cf48753 100644
--- a/modules/amemxfrm
+++ b/modules/amemxfrm
@@ -8,6 +8,7 @@ lib/amemxfrm.c
 Depends-on:
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += amemxfrm.c
-- 
2.7.4


[-- Attachment #3: 0002-astrxfrm-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1654 bytes --]

From b9eae96869cc9cef3865505ab8dc356196f241e9 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:06:29 +0100
Subject: [PATCH 02/29] astrxfrm: Use 'restrict'.

* lib/astrxfrm.h (astrxfrm): Use 'restrict'.
* modules/astrxfrm (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog        | 4 ++++
 lib/astrxfrm.h   | 3 ++-
 modules/astrxfrm | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 563d770..80a90eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	astrxfrm: Use 'restrict'.
+	* lib/astrxfrm.h (astrxfrm): Use 'restrict'.
+	* modules/astrxfrm (configure.ac): Require AC_C_RESTRICT.
+
 	amemxfrm: Use 'restrict'.
 	* lib/amemxfrm.h (amemxfrm): Use 'restrict'.
 	* modules/amemxfrm (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/astrxfrm.h b/lib/astrxfrm.h
index a23ed70..211fe3b 100644
--- a/lib/astrxfrm.h
+++ b/lib/astrxfrm.h
@@ -37,7 +37,8 @@ extern "C" {
    freshly allocated string is returned.  In both cases, *lengthp is set to the
    length of the returned string.
    Upon failure, return NULL, with errno set.  */
-extern char * astrxfrm (const char *s, char *resultbuf, size_t *lengthp);
+extern char * astrxfrm (const char *s,
+                        char *restrict resultbuf, size_t *lengthp);
 
 
 #ifdef __cplusplus
diff --git a/modules/astrxfrm b/modules/astrxfrm
index e2edc42..0533403 100644
--- a/modules/astrxfrm
+++ b/modules/astrxfrm
@@ -8,6 +8,7 @@ lib/astrxfrm.c
 Depends-on:
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += astrxfrm.c
-- 
2.7.4


[-- Attachment #4: 0003-c-snprintf-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1573 bytes --]

From f2042e039a29fdab365929d776fee22bfeff15fb Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:12:09 +0100
Subject: [PATCH 03/29] c-snprintf: Use 'restrict'.

* lib/c-snprintf.h (c_snprintf): Use 'restrict'.
* modules/c-snprintf (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog          | 4 ++++
 lib/c-snprintf.h   | 3 ++-
 modules/c-snprintf | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 80a90eb..277b594 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	c-snprintf: Use 'restrict'.
+	* lib/c-snprintf.h (c_snprintf): Use 'restrict'.
+	* modules/c-snprintf (configure.ac): Require AC_C_RESTRICT.
+
 	astrxfrm: Use 'restrict'.
 	* lib/astrxfrm.h (astrxfrm): Use 'restrict'.
 	* modules/astrxfrm (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/c-snprintf.h b/lib/c-snprintf.h
index bfdc081..d82f354 100644
--- a/lib/c-snprintf.h
+++ b/lib/c-snprintf.h
@@ -36,7 +36,8 @@
 extern "C" {
 #endif
 
-int c_snprintf (char *str, size_t size, const char *format, ...)
+extern int c_snprintf (char *restrict str, size_t size,
+                       const char *format, ...)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
 
 #ifdef __cplusplus
diff --git a/modules/c-snprintf b/modules/c-snprintf
index edebe2b..2449b01 100644
--- a/modules/c-snprintf
+++ b/modules/c-snprintf
@@ -9,6 +9,7 @@ Depends-on:
 c-vasnprintf
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += c-snprintf.c
-- 
2.7.4


[-- Attachment #5: 0004-c-vsnprintf-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1624 bytes --]

From 69acbf9b8d4b8517eefa25be74e436f22b9b0428 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:13:40 +0100
Subject: [PATCH 04/29] c-vsnprintf: Use 'restrict'.

* lib/c-vsnprintf.h (c_vsnprintf): Use 'restrict'.
* modules/c-vsnprintf (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog           | 4 ++++
 lib/c-vsnprintf.h   | 3 ++-
 modules/c-vsnprintf | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 277b594..1bc838e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	c-vsnprintf: Use 'restrict'.
+	* lib/c-vsnprintf.h (c_vsnprintf): Use 'restrict'.
+	* modules/c-vsnprintf (configure.ac): Require AC_C_RESTRICT.
+
 	c-snprintf: Use 'restrict'.
 	* lib/c-snprintf.h (c_snprintf): Use 'restrict'.
 	* modules/c-snprintf (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/c-vsnprintf.h b/lib/c-vsnprintf.h
index 97a2816..e296871 100644
--- a/lib/c-vsnprintf.h
+++ b/lib/c-vsnprintf.h
@@ -39,7 +39,8 @@
 extern "C" {
 #endif
 
-int c_vsnprintf (char *str, size_t size, const char *format, va_list args)
+extern int c_vsnprintf (char *restrict str, size_t size,
+                        const char *format, va_list args)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
 
 #ifdef __cplusplus
diff --git a/modules/c-vsnprintf b/modules/c-vsnprintf
index 7846d9d..b227e92 100644
--- a/modules/c-vsnprintf
+++ b/modules/c-vsnprintf
@@ -10,6 +10,7 @@ Depends-on:
 c-vasnprintf
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += c-vsnprintf.c
-- 
2.7.4


[-- Attachment #6: 0005-c-vasnprintf-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1809 bytes --]

From fc00c78e289085063c1832a54d73fc784e9f9626 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:15:09 +0100
Subject: [PATCH 05/29] c-vasnprintf: Use 'restrict'.

* lib/c-vasnprintf.h (c_vasnprintf): Use 'restrict'.
* modules/c-vasnprintf (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog            | 4 ++++
 lib/c-vasnprintf.h   | 3 ++-
 modules/c-vasnprintf | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 1bc838e..9db6d8b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	c-vasnprintf: Use 'restrict'.
+	* lib/c-vasnprintf.h (c_vasnprintf): Use 'restrict'.
+	* modules/c-vasnprintf (configure.ac): Require AC_C_RESTRICT.
+
 	c-vsnprintf: Use 'restrict'.
 	* lib/c-vsnprintf.h (c_vsnprintf): Use 'restrict'.
 	* modules/c-vsnprintf (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/c-vasnprintf.h b/lib/c-vasnprintf.h
index 1a69e56..0f58fb8 100644
--- a/lib/c-vasnprintf.h
+++ b/lib/c-vasnprintf.h
@@ -66,7 +66,8 @@ extern "C" {
    Formatting takes place in the C locale, that is, the decimal point used in
    floating-point formatting directives is always '.'.
   */
-extern char *c_vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
+extern char *c_vasnprintf (char *restrict resultbuf, size_t *lengthp,
+                           const char *format, va_list args)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
 
 #ifdef __cplusplus
diff --git a/modules/c-vasnprintf b/modules/c-vasnprintf
index ae51ea9..391d964 100644
--- a/modules/c-vasnprintf
+++ b/modules/c-vasnprintf
@@ -39,6 +39,7 @@ multiarch
 verify
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_PREREQ_VASNPRINTF_WITH_EXTRAS
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #7: 0006-vasnprintf-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1974 bytes --]

From d5233651c987d7b605aff58c79538d1b5cc5ed1e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:17:44 +0100
Subject: [PATCH 06/29] vasnprintf: Use 'restrict'.

* lib/vasnprintf.h (asnprintf, vasnprintf): Use 'restrict'.
* modules/vasnprintf (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog          | 4 ++++
 lib/vasnprintf.h   | 6 ++++--
 modules/vasnprintf | 1 +
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9db6d8b..5154229 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	vasnprintf: Use 'restrict'.
+	* lib/vasnprintf.h (asnprintf, vasnprintf): Use 'restrict'.
+	* modules/vasnprintf (configure.ac): Require AC_C_RESTRICT.
+
 	c-vasnprintf: Use 'restrict'.
 	* lib/c-vasnprintf.h (c_vasnprintf): Use 'restrict'.
 	* modules/c-vasnprintf (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/vasnprintf.h b/lib/vasnprintf.h
index 345e6a8..37777c9 100644
--- a/lib/vasnprintf.h
+++ b/lib/vasnprintf.h
@@ -67,9 +67,11 @@ extern "C" {
 # define asnprintf rpl_asnprintf
 # define vasnprintf rpl_vasnprintf
 #endif
-extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
+extern char * asnprintf (char *restrict resultbuf, size_t *lengthp,
+                         const char *format, ...)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
-extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
+extern char * vasnprintf (char *restrict resultbuf, size_t *lengthp,
+                          const char *format, va_list args)
        _GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
 
 #ifdef __cplusplus
diff --git a/modules/vasnprintf b/modules/vasnprintf
index 671cb68..de8537a 100644
--- a/modules/vasnprintf
+++ b/modules/vasnprintf
@@ -31,6 +31,7 @@ verify
 wchar
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_FUNC_VASNPRINTF
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #8: 0007-memcoll-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1789 bytes --]

From 771be1d4d16c54578e9605c3d457290b822bcfa5 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:19:28 +0100
Subject: [PATCH 07/29] memcoll: Use 'restrict'.

* lib/memcoll.h (memcoll): Use 'restrict'.
* m4/memcoll.m4 (gl_MEMCOLL): Require AC_C_RESTRICT.
---
 ChangeLog     | 4 ++++
 lib/memcoll.h | 2 +-
 m4/memcoll.m4 | 8 ++++++--
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5154229..b1ffa89 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	memcoll: Use 'restrict'.
+	* lib/memcoll.h (memcoll): Use 'restrict'.
+	* m4/memcoll.m4 (gl_MEMCOLL): Require AC_C_RESTRICT.
+
 	vasnprintf: Use 'restrict'.
 	* lib/vasnprintf.h (asnprintf, vasnprintf): Use 'restrict'.
 	* modules/vasnprintf (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/memcoll.h b/lib/memcoll.h
index add0968..907ca1f 100644
--- a/lib/memcoll.h
+++ b/lib/memcoll.h
@@ -22,7 +22,7 @@
 
 # include <stddef.h>
 
-int memcoll (char *, size_t, char *, size_t);
+int memcoll (char *restrict, size_t, char *restrict, size_t);
 int memcoll0 (char const *, size_t, char const *, size_t);
 
 #endif /* MEMCOLL_H_ */
diff --git a/m4/memcoll.m4 b/m4/memcoll.m4
index d3d1132..e6eb77e 100644
--- a/m4/memcoll.m4
+++ b/m4/memcoll.m4
@@ -1,8 +1,12 @@
-# memcoll.m4 serial 10
+# memcoll.m4 serial 11
 dnl Copyright (C) 2002-2003, 2005-2006, 2009-2020 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
-AC_DEFUN([gl_MEMCOLL], [:])
+AC_DEFUN([gl_MEMCOLL],
+[
+  AC_REQUIRE([AC_C_RESTRICT])
+  :
+])
-- 
2.7.4


[-- Attachment #9: 0008-xmemcoll-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1453 bytes --]

From 11ff607ecad1b1f06b6f6966ee989db9d079cc9d Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:20:35 +0100
Subject: [PATCH 08/29] xmemcoll: Use 'restrict'.

* lib/xmemcoll.h (xmemcoll): Use 'restrict'.
* modules/xmemcoll (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog        | 4 ++++
 lib/xmemcoll.h   | 2 +-
 modules/xmemcoll | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index b1ffa89..161c3d6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	xmemcoll: Use 'restrict'.
+	* lib/xmemcoll.h (xmemcoll): Use 'restrict'.
+	* modules/xmemcoll (configure.ac): Require AC_C_RESTRICT.
+
 	memcoll: Use 'restrict'.
 	* lib/memcoll.h (memcoll): Use 'restrict'.
 	* m4/memcoll.m4 (gl_MEMCOLL): Require AC_C_RESTRICT.
diff --git a/lib/xmemcoll.h b/lib/xmemcoll.h
index 4170b9b..1ac2325 100644
--- a/lib/xmemcoll.h
+++ b/lib/xmemcoll.h
@@ -1,3 +1,3 @@
 #include <stddef.h>
-int xmemcoll (char *, size_t, char *, size_t);
+int xmemcoll (char *restrict, size_t, char *restrict, size_t);
 int xmemcoll0 (char const *, size_t, char const *, size_t);
diff --git a/modules/xmemcoll b/modules/xmemcoll
index 9724945..3ef5491 100644
--- a/modules/xmemcoll
+++ b/modules/xmemcoll
@@ -13,6 +13,7 @@ quotearg
 exitfail
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += xmemcoll.h xmemcoll.c
-- 
2.7.4


[-- Attachment #10: 0009-mbstok_r-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1269 bytes --]

From 6f6695eaf1c2dee0f2d11f107637405da1d6121e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:24:01 +0100
Subject: [PATCH 09/29] mbstok_r: Use 'restrict'.

* lib/string.in.h (mbstok_r): Use 'restrict'.
---
 ChangeLog       | 3 +++
 lib/string.in.h | 3 ++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 161c3d6..cf441ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	mbstok_r: Use 'restrict'.
+	* lib/string.in.h (mbstok_r): Use 'restrict'.
+
 	xmemcoll: Use 'restrict'.
 	* lib/xmemcoll.h (xmemcoll): Use 'restrict'.
 	* modules/xmemcoll (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/string.in.h b/lib/string.in.h
index 625d608..87155ca 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -969,7 +969,8 @@ _GL_EXTERN_C char * mbssep (char **stringp, const char *delim)
    Caveat: The identity of the delimiting character is lost.
 
    See also mbssep().  */
-_GL_EXTERN_C char * mbstok_r (char *string, const char *delim, char **save_ptr)
+_GL_EXTERN_C char * mbstok_r (char *restrict string, const char *delim,
+                              char **save_ptr)
      _GL_ARG_NONNULL ((2, 3));
 #endif
 
-- 
2.7.4


[-- Attachment #11: 0010-nstrftime-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1797 bytes --]

From bf19526c73eb07080946178390834c2ab8ddfb83 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:25:42 +0100
Subject: [PATCH 10/29] nstrftime: Use 'restrict'.

* lib/strftime.h (nstrftime): Use 'restrict'.
* m4/nstrftime.m4 (gl_FUNC_GNU_STRFTIME): Require AC_C_RESTRICT.
---
 ChangeLog       | 4 ++++
 lib/strftime.h  | 2 +-
 m4/nstrftime.m4 | 4 +++-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cf441ae..31cd227 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	nstrftime: Use 'restrict'.
+	* lib/strftime.h (nstrftime): Use 'restrict'.
+	* m4/nstrftime.m4 (gl_FUNC_GNU_STRFTIME): Require AC_C_RESTRICT.
+
 	mbstok_r: Use 'restrict'.
 	* lib/string.in.h (mbstok_r): Use 'restrict'.
 
diff --git a/lib/strftime.h b/lib/strftime.h
index 97a062c..e850163 100644
--- a/lib/strftime.h
+++ b/lib/strftime.h
@@ -25,7 +25,7 @@ extern "C" {
    POSIX requires that strftime use the local timezone information.
    Use the timezone __TZ instead.  Use __NS as the number of
    nanoseconds in the %N directive.  */
-size_t nstrftime (char *, size_t, char const *, struct tm const *,
+size_t nstrftime (char *restrict, size_t, char const *, struct tm const *,
                   timezone_t __tz, int __ns);
 
 #ifdef __cplusplus
diff --git a/m4/nstrftime.m4 b/m4/nstrftime.m4
index c15fab3..6f2762a 100644
--- a/m4/nstrftime.m4
+++ b/m4/nstrftime.m4
@@ -1,4 +1,4 @@
-# serial 34
+# serial 35
 
 # Copyright (C) 1996-1997, 1999-2007, 2009-2020 Free Software Foundation, Inc.
 #
@@ -10,6 +10,8 @@
 
 AC_DEFUN([gl_FUNC_GNU_STRFTIME],
 [
+ AC_REQUIRE([AC_C_RESTRICT])
+
  # This defines (or not) HAVE_TZNAME and HAVE_TM_ZONE.
  AC_REQUIRE([AC_STRUCT_TIMEZONE])
 
-- 
2.7.4


[-- Attachment #12: 0011-parse-datetime-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2480 bytes --]

From 5f56bf12b34a83ab90c9d7e3955aacb9c67cb8a2 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:27:58 +0100
Subject: [PATCH 11/29] parse-datetime: Use 'restrict'.

* lib/parse-datetime.h (parse_datetime, parse_datetime2): Use
'restrict'.
* m4/parse-datetime.m4 (gl_PARSE_DATETIME): Require AC_C_RESTRICT.
---
 ChangeLog            | 5 +++++
 lib/parse-datetime.h | 6 ++++--
 m4/parse-datetime.m4 | 3 ++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 31cd227..472ec01 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	parse-datetime: Use 'restrict'.
+	* lib/parse-datetime.h (parse_datetime, parse_datetime2): Use
+	'restrict'.
+	* m4/parse-datetime.m4 (gl_PARSE_DATETIME): Require AC_C_RESTRICT.
+
 	nstrftime: Use 'restrict'.
 	* lib/strftime.h (nstrftime): Use 'restrict'.
 	* m4/nstrftime.m4 (gl_FUNC_GNU_STRFTIME): Require AC_C_RESTRICT.
diff --git a/lib/parse-datetime.h b/lib/parse-datetime.h
index ab9b576..3836308 100644
--- a/lib/parse-datetime.h
+++ b/lib/parse-datetime.h
@@ -19,11 +19,13 @@
 #include <stdbool.h>
 #include <time.h>
 
-bool parse_datetime (struct timespec *, char const *, struct timespec const *);
+bool parse_datetime (struct timespec *restrict,
+                     char const *, struct timespec const *);
 
 /* parse_datetime2 flag: if set, print debug/progress information to STDERR */
 #define PARSE_DATETIME_DEBUG 1
 
 /* same as above, supporting additional flags */
-bool parse_datetime2 (struct timespec *, char const *, struct timespec const *,
+bool parse_datetime2 (struct timespec *restrict,
+                      char const *, struct timespec const *,
                       unsigned int flags, timezone_t, char const *);
diff --git a/m4/parse-datetime.m4 b/m4/parse-datetime.m4
index ebe9541..52a10aa 100644
--- a/m4/parse-datetime.m4
+++ b/m4/parse-datetime.m4
@@ -1,4 +1,4 @@
-# parse-datetime.m4 serial 23
+# parse-datetime.m4 serial 24
 dnl Copyright (C) 2002-2006, 2008-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -60,6 +60,7 @@ changequote([,])dnl
   dnl Prerequisites of lib/parse-datetime.h.
   AC_REQUIRE([AM_STDBOOL_H])
   AC_REQUIRE([gl_TIMESPEC])
+  AC_REQUIRE([AC_C_RESTRICT])
 
   dnl Prerequisites of lib/parse-datetime.y.
   AC_REQUIRE([gl_BISON])
-- 
2.7.4


[-- Attachment #13: 0012-quotearg-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2010 bytes --]

From 90106dbaf4b8881139bb3e567da8bbc1bad2055f Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:29:41 +0100
Subject: [PATCH 12/29] quotearg: Use 'restrict'.

* lib/quotearg.h (quotearg_buffer): Use 'restrict'.
* m4/quotearg.m4 (gl_QUOTEARG): Require AC_C_RESTRICT.
---
 ChangeLog      | 4 ++++
 lib/quotearg.h | 2 +-
 m4/quotearg.m4 | 3 ++-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 472ec01..8b87c6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	quotearg: Use 'restrict'.
+	* lib/quotearg.h (quotearg_buffer): Use 'restrict'.
+	* m4/quotearg.m4 (gl_QUOTEARG): Require AC_C_RESTRICT.
+
 	parse-datetime: Use 'restrict'.
 	* lib/parse-datetime.h (parse_datetime, parse_datetime2): Use
 	'restrict'.
diff --git a/lib/quotearg.h b/lib/quotearg.h
index d30fdd1..3bf149b 100644
--- a/lib/quotearg.h
+++ b/lib/quotearg.h
@@ -323,7 +323,7 @@ void set_custom_quoting (struct quoting_options *o,
    On output, BUFFER might contain embedded null bytes if ARGSIZE was
    not -1, the style of O does not use backslash escapes, and the
    flags of O do not request elision of null bytes.*/
-size_t quotearg_buffer (char *buffer, size_t buffersize,
+size_t quotearg_buffer (char *restrict buffer, size_t buffersize,
                         char const *arg, size_t argsize,
                         struct quoting_options const *o);
 
diff --git a/m4/quotearg.m4 b/m4/quotearg.m4
index b6eb16b..4038711 100644
--- a/m4/quotearg.m4
+++ b/m4/quotearg.m4
@@ -1,4 +1,4 @@
-# quotearg.m4 serial 9
+# quotearg.m4 serial 10
 dnl Copyright (C) 2002, 2004-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,5 +6,6 @@ dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_QUOTEARG],
 [
+  AC_REQUIRE([AC_C_RESTRICT])
   :
 ])
-- 
2.7.4


[-- Attachment #14: 0013-sh-quote-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1723 bytes --]

From a85a39de0293d492a6a087c356f4e3a26e0d1cee Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:31:00 +0100
Subject: [PATCH 13/29] sh-quote: Use 'restrict'.

* lib/sh-quote.h (shell_quote_copy): Use 'restrict'.
* modules/sh-quote (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog        | 4 ++++
 lib/sh-quote.h   | 2 +-
 modules/sh-quote | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 8b87c6b..a00c415 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	sh-quote: Use 'restrict'.
+	* lib/sh-quote.h (shell_quote_copy): Use 'restrict'.
+	* modules/sh-quote (configure.ac): Require AC_C_RESTRICT.
+
 	quotearg: Use 'restrict'.
 	* lib/quotearg.h (quotearg_buffer): Use 'restrict'.
 	* m4/quotearg.m4 (gl_QUOTEARG): Require AC_C_RESTRICT.
diff --git a/lib/sh-quote.h b/lib/sh-quote.h
index 9dcd4cf..8b06355 100644
--- a/lib/sh-quote.h
+++ b/lib/sh-quote.h
@@ -33,7 +33,7 @@ extern size_t shell_quote_length (const char *string);
 
 /* Copies the quoted string to p and returns the incremented p.
    There must be room for shell_quote_length (string) + 1 bytes at p.  */
-extern char * shell_quote_copy (char *p, const char *string);
+extern char * shell_quote_copy (char *restrict p, const char *string);
 
 /* Returns the freshly allocated quoted string.  */
 extern char * shell_quote (const char *string);
diff --git a/modules/sh-quote b/modules/sh-quote
index 83fa089..97378f8 100644
--- a/modules/sh-quote
+++ b/modules/sh-quote
@@ -10,6 +10,7 @@ quotearg
 xalloc
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += sh-quote.h sh-quote.c
-- 
2.7.4


[-- Attachment #15: 0014-system-quote-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1742 bytes --]

From 4c37dd4ab504ba644fbcfdb47375398bf0d97b4f Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:32:25 +0100
Subject: [PATCH 14/29] system-quote: Use 'restrict'.

* lib/system-quote.h (system_quote_copy): Use 'restrict'.
* modules/system-quote (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog            | 4 ++++
 lib/system-quote.h   | 2 +-
 modules/system-quote | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index a00c415..525ecdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	system-quote: Use 'restrict'.
+	* lib/system-quote.h (system_quote_copy): Use 'restrict'.
+	* modules/system-quote (configure.ac): Require AC_C_RESTRICT.
+
 	sh-quote: Use 'restrict'.
 	* lib/sh-quote.h (shell_quote_copy): Use 'restrict'.
 	* modules/sh-quote (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/system-quote.h b/lib/system-quote.h
index d31d47f..419d3b8 100644
--- a/lib/system-quote.h
+++ b/lib/system-quote.h
@@ -77,7 +77,7 @@ extern size_t
 /* Copies the quoted string to p and returns the incremented p.
    There must be room for system_quote_length (string) + 1 bytes at p.  */
 extern char *
-       system_quote_copy (char *p,
+       system_quote_copy (char *restrict p,
                           enum system_command_interpreter interpreter,
                           const char *string);
 
diff --git a/modules/system-quote b/modules/system-quote
index f34d58a..9af74dc 100644
--- a/modules/system-quote
+++ b/modules/system-quote
@@ -10,6 +10,7 @@ sh-quote
 xalloc
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += system-quote.h system-quote.c
-- 
2.7.4


[-- Attachment #16: 0015-regex-quote-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1739 bytes --]

From 0423ac9fe82acd56e3b4108738cb3426c6216d6e Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:33:37 +0100
Subject: [PATCH 15/29] regex-quote: Use 'restrict'.

* lib/regex-quote.h (regex_quote_copy): Use 'restrict'.
* modules/regex-quote (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog           | 4 ++++
 lib/regex-quote.h   | 2 +-
 modules/regex-quote | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 525ecdb..7f4db6a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	regex-quote: Use 'restrict'.
+	* lib/regex-quote.h (regex_quote_copy): Use 'restrict'.
+	* modules/regex-quote (configure.ac): Require AC_C_RESTRICT.
+
 	system-quote: Use 'restrict'.
 	* lib/system-quote.h (system_quote_copy): Use 'restrict'.
 	* modules/system-quote (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/regex-quote.h b/lib/regex-quote.h
index 185f9fe..b6b299f 100644
--- a/lib/regex-quote.h
+++ b/lib/regex-quote.h
@@ -77,7 +77,7 @@ extern size_t
 /* Copies the quoted string to p and returns the incremented p.
    There must be room for regex_quote_length (string, spec) + 1 bytes at p.  */
 extern char *
-       regex_quote_copy (char *p,
+       regex_quote_copy (char *restrict p,
                          const char *string, const struct regex_quote_spec *spec);
 
 /* Returns the freshly allocated quoted string.  */
diff --git a/modules/regex-quote b/modules/regex-quote
index 9b67ca2..4623339 100644
--- a/modules/regex-quote
+++ b/modules/regex-quote
@@ -11,6 +11,7 @@ xalloc
 mbuiter
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += regex-quote.c
-- 
2.7.4


[-- Attachment #17: 0016-careadlinkat-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2294 bytes --]

From 8aa4a92942b7bf1183878ea75e378de02046fdc4 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 12:35:14 +0100
Subject: [PATCH 16/29] careadlinkat: Use 'restrict'.

* lib/careadlinkat.h (careadlinkat): Use 'restrict'.
* modules/careadlinkat (configure.ac): Require AC_C_RESTRICT.
* modules/relocatable-prog-wrapper (configure.ac): Likewise.
---
 ChangeLog                        | 5 +++++
 lib/careadlinkat.h               | 2 +-
 modules/careadlinkat             | 1 +
 modules/relocatable-prog-wrapper | 1 +
 4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 7f4db6a..fc7190c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	careadlinkat: Use 'restrict'.
+	* lib/careadlinkat.h (careadlinkat): Use 'restrict'.
+	* modules/careadlinkat (configure.ac): Require AC_C_RESTRICT.
+	* modules/relocatable-prog-wrapper (configure.ac): Likewise.
+
 	regex-quote: Use 'restrict'.
 	* lib/regex-quote.h (regex_quote_copy): Use 'restrict'.
 	* modules/regex-quote (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/careadlinkat.h b/lib/careadlinkat.h
index 584cfe9..a4a37b2 100644
--- a/lib/careadlinkat.h
+++ b/lib/careadlinkat.h
@@ -47,7 +47,7 @@ struct allocator;
    set errno.  */
 
 char *careadlinkat (int fd, char const *filename,
-                    char *buffer, size_t buffer_size,
+                    char *restrict buffer, size_t buffer_size,
                     struct allocator const *alloc,
                     ssize_t (*preadlinkat) (int, char const *,
                                             char *, size_t));
diff --git a/modules/careadlinkat b/modules/careadlinkat
index 9dd7471..3f49aae 100644
--- a/modules/careadlinkat
+++ b/modules/careadlinkat
@@ -11,6 +11,7 @@ ssize_t
 unistd
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 AC_CHECK_FUNCS_ONCE([readlinkat])
 
 Makefile.am:
diff --git a/modules/relocatable-prog-wrapper b/modules/relocatable-prog-wrapper
index d70d63e..58af208 100644
--- a/modules/relocatable-prog-wrapper
+++ b/modules/relocatable-prog-wrapper
@@ -49,6 +49,7 @@ verify
 xalloc-oversized
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_FUNC_READLINK_SEPARATE
 gl_CANONICALIZE_LGPL_SEPARATE
 gl_MALLOCA
-- 
2.7.4


[-- Attachment #18: 0017-crypto-arcfour-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1731 bytes --]

From 8f6c42bf9ab0aed1caca1368e5a4dc4f6eef2842 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:04:13 +0100
Subject: [PATCH 17/29] crypto/arcfour: Use 'restrict'.

* lib/arcfour.h (arcfour_stream): Use 'restrict'.
* modules/crypto/arcfour (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog              | 4 ++++
 lib/arcfour.h          | 2 +-
 modules/crypto/arcfour | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index fc7190c..4da2852 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/arcfour: Use 'restrict'.
+	* lib/arcfour.h (arcfour_stream): Use 'restrict'.
+	* modules/crypto/arcfour (configure.ac): Require AC_C_RESTRICT.
+
 	careadlinkat: Use 'restrict'.
 	* lib/careadlinkat.h (careadlinkat): Use 'restrict'.
 	* modules/careadlinkat (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/arcfour.h b/lib/arcfour.h
index b77df1a..cc4e37d 100644
--- a/lib/arcfour.h
+++ b/lib/arcfour.h
@@ -37,7 +37,7 @@ typedef struct
    before this function is called. */
 extern void
 arcfour_stream (arcfour_context * context,
-                const char *inbuf, char *outbuf, size_t length);
+                const char *inbuf, char *restrict outbuf, size_t length);
 
 /* Initialize CONTEXT using encryption KEY of KEYLEN bytes.  KEY
    should be 40 bits (5 bytes) or longer.  The KEY cannot be zero
diff --git a/modules/crypto/arcfour b/modules/crypto/arcfour
index 43d1345..5e7736c 100644
--- a/modules/crypto/arcfour
+++ b/modules/crypto/arcfour
@@ -9,6 +9,7 @@ Depends-on:
 stdint
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += arcfour.c
-- 
2.7.4


[-- Attachment #19: 0018-crypto-arctwo-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2036 bytes --]

From 9ca102bfeada4694bc288754d71475cae91c6620 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:05:57 +0100
Subject: [PATCH 18/29] crypto/arctwo: Use 'restrict'.

* lib/arctwo.h (arctwo_encrypt, arctwo_decrypt): Use 'restrict'.
* modules/crypto/arctwo (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog             | 4 ++++
 lib/arctwo.h          | 4 ++--
 modules/crypto/arctwo | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4da2852..22933fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/arctwo: Use 'restrict'.
+	* lib/arctwo.h (arctwo_encrypt, arctwo_decrypt): Use 'restrict'.
+	* modules/crypto/arctwo (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/arcfour: Use 'restrict'.
 	* lib/arcfour.h (arcfour_stream): Use 'restrict'.
 	* modules/crypto/arcfour (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/arctwo.h b/lib/arctwo.h
index 91f725f..05929bf 100644
--- a/lib/arctwo.h
+++ b/lib/arctwo.h
@@ -48,7 +48,7 @@ arctwo_setkey_ekb (arctwo_context *context,
    arctwo_setkey_ekb. */
 extern void
 arctwo_encrypt (arctwo_context *context, const char *inbuf,
-                char *outbuf, size_t length);
+                char *restrict outbuf, size_t length);
 
 /* Decrypt INBUF of size LENGTH into OUTBUF.  LENGTH must be a
    multiple of ARCTWO_BLOCK_SIZE.  CONTEXT hold the decryption key,
@@ -56,6 +56,6 @@ arctwo_encrypt (arctwo_context *context, const char *inbuf,
    arctwo_setkey_ekb. */
 extern void
 arctwo_decrypt (arctwo_context *context, const char *inbuf,
-                char *outbuf, size_t length);
+                char *restrict outbuf, size_t length);
 
 #endif /* ARCTWO_H */
diff --git a/modules/crypto/arctwo b/modules/crypto/arctwo
index e0bbb90..d439701 100644
--- a/modules/crypto/arctwo
+++ b/modules/crypto/arctwo
@@ -11,6 +11,7 @@ stdint
 bitrotate
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_ARCTWO
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #20: 0019-crypto-rijndael-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 3180 bytes --]

From 555b03cc26011dbe6364a6eb4efef8fe4837ebc5 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:08:14 +0100
Subject: [PATCH 19/29] crypto/rijndael: Use 'restrict'.

* lib/rijndael-api-fst.h (rijndaelBlockEncrypt, rijndaelPadEncrypt,
rijndaelBlockDecrypt, rijndaelPadDecrypt): Use 'restrict'.
* modules/crypto/rijndael (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog               | 5 +++++
 lib/rijndael-api-fst.h  | 8 ++++----
 modules/crypto/rijndael | 1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 22933fc..2e51ac6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/rijndael: Use 'restrict'.
+	* lib/rijndael-api-fst.h (rijndaelBlockEncrypt, rijndaelPadEncrypt,
+	rijndaelBlockDecrypt, rijndaelPadDecrypt): Use 'restrict'.
+	* modules/crypto/rijndael (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/arctwo: Use 'restrict'.
 	* lib/arctwo.h (arctwo_encrypt, arctwo_decrypt): Use 'restrict'.
 	* modules/crypto/arctwo (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/rijndael-api-fst.h b/lib/rijndael-api-fst.h
index 0553acc..fa5f8d7 100644
--- a/lib/rijndael-api-fst.h
+++ b/lib/rijndael-api-fst.h
@@ -157,7 +157,7 @@ extern int
 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
                       const rijndaelKeyInstance *key,
                       const char *input, size_t inputLen,
-                      char *outBuffer);
+                      char *restrict outBuffer);
 
 /* Encrypt data in INPUT, of INPUTOCTETS bytes length, placing the
    output in the pre-allocated OUTBUFFER which must hold at least
@@ -172,7 +172,7 @@ extern int
 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
                     const rijndaelKeyInstance *key,
                     const char *input, size_t inputOctets,
-                    char *outBuffer);
+                    char *restrict outBuffer);
 
 /* Decrypt data in INPUT, of INPUTLEN/8 bytes length, placing the
    output in the pre-allocated OUTBUFFER which must hold at least
@@ -185,7 +185,7 @@ extern int
 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
                       const rijndaelKeyInstance *key,
                       const char *input, size_t inputLen,
-                      char *outBuffer);
+                      char *restrict outBuffer);
 
 /* Decrypt data in INPUT, of INPUTOCTETS bytes length, placing the
    output in the pre-allocated OUTBUFFER which must hold at least
@@ -200,6 +200,6 @@ extern int
 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
                     const rijndaelKeyInstance *key,
                     const char *input, size_t inputOctets,
-                    char *outBuffer);
+                    char *restrict outBuffer);
 
 #endif /* __RIJNDAEL_API_FST_H */
diff --git a/modules/crypto/rijndael b/modules/crypto/rijndael
index c5feae6..8dd0ae5 100644
--- a/modules/crypto/rijndael
+++ b/modules/crypto/rijndael
@@ -11,6 +11,7 @@ Depends-on:
 stdint
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += rijndael-alg-fst.c rijndael-api-fst.c
-- 
2.7.4


[-- Attachment #21: 0020-crypto-md2-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2619 bytes --]

From 67f3b5ba252ac2962276ddc8e3431d4897549cf1 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:12:16 +0100
Subject: [PATCH 20/29] crypto/md2: Use 'restrict'.

* lib/md2.h (md2_finish_ctx, md2_read_ctx, md2_buffer): Use 'restrict'.
* modules/crypto/md2 (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog          | 4 ++++
 lib/md2.h          | 7 ++++---
 modules/crypto/md2 | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2e51ac6..33a233e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/md2: Use 'restrict'.
+	* lib/md2.h (md2_finish_ctx, md2_read_ctx, md2_buffer): Use 'restrict'.
+	* modules/crypto/md2 (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/rijndael: Use 'restrict'.
 	* lib/rijndael-api-fst.h (rijndaelBlockEncrypt, rijndaelPadEncrypt,
 	rijndaelBlockDecrypt, rijndaelPadDecrypt): Use 'restrict'.
diff --git a/lib/md2.h b/lib/md2.h
index 8fa912f..6cb58a9 100644
--- a/lib/md2.h
+++ b/lib/md2.h
@@ -57,13 +57,13 @@ extern void md2_process_bytes (const void *buffer, size_t len,
    in first 16 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *md2_finish_ctx (struct md2_ctx *ctx, void *resbuf);
+extern void *md2_finish_ctx (struct md2_ctx *ctx, void *restrict resbuf);
 
 
 /* Put result from CTX in first 16 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *md2_read_ctx (const struct md2_ctx *ctx, void *resbuf);
+extern void *md2_read_ctx (const struct md2_ctx *ctx, void *restrict resbuf);
 
 
 /* Compute MD2 message digest for bytes read from STREAM.  The
@@ -75,7 +75,8 @@ extern int md2_stream (FILE *stream, void *resblock);
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
-extern void *md2_buffer (const char *buffer, size_t len, void *resblock);
+extern void *md2_buffer (const char *buffer, size_t len,
+                         void *restrict resblock);
 
 # ifdef __cplusplus
 }
diff --git a/modules/crypto/md2 b/modules/crypto/md2
index 0cc8499..d89eb95 100644
--- a/modules/crypto/md2
+++ b/modules/crypto/md2
@@ -9,6 +9,7 @@ Depends-on:
 minmax
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += md2.c
-- 
2.7.4


[-- Attachment #22: 0021-crypto-md4-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2605 bytes --]

From 1fa14c798c517aae775149ebcbe5577a73515dfc Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:13:38 +0100
Subject: [PATCH 21/29] crypto/md4: Use 'restrict'.

* lib/md4.h (md4_finish_ctx, md4_read_ctx, md4_buffer): Use 'restrict'.
* modules/crypto/md4 (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog          | 4 ++++
 lib/md4.h          | 7 ++++---
 modules/crypto/md4 | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 33a233e..bd40d1b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/md4: Use 'restrict'.
+	* lib/md4.h (md4_finish_ctx, md4_read_ctx, md4_buffer): Use 'restrict'.
+	* modules/crypto/md4 (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/md2: Use 'restrict'.
 	* lib/md2.h (md2_finish_ctx, md2_read_ctx, md2_buffer): Use 'restrict'.
 	* modules/crypto/md2 (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/md4.h b/lib/md4.h
index 4cb5aa0..37f3ff2 100644
--- a/lib/md4.h
+++ b/lib/md4.h
@@ -63,13 +63,13 @@ extern void md4_process_bytes (const void *buffer, size_t len,
    in first 16 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *md4_finish_ctx (struct md4_ctx *ctx, void *resbuf);
+extern void *md4_finish_ctx (struct md4_ctx *ctx, void *restrict resbuf);
 
 
 /* Put result from CTX in first 16 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *md4_read_ctx (const struct md4_ctx *ctx, void *resbuf);
+extern void *md4_read_ctx (const struct md4_ctx *ctx, void *restrict resbuf);
 
 
 /* Compute MD4 message digest for bytes read from STREAM.  The
@@ -81,7 +81,8 @@ extern int md4_stream (FILE * stream, void *resblock);
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
-extern void *md4_buffer (const char *buffer, size_t len, void *resblock);
+extern void *md4_buffer (const char *buffer, size_t len,
+                         void *restrict resblock);
 
 # ifdef __cplusplus
 }
diff --git a/modules/crypto/md4 b/modules/crypto/md4
index 03d28e9..f5a5f16 100644
--- a/modules/crypto/md4
+++ b/modules/crypto/md4
@@ -12,6 +12,7 @@ stdalign
 stdint
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_MD4
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #23: 0022-crypto-md5-buffer-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2753 bytes --]

From 94ff8af6bf3399c077cb907e56424d61fdea79d4 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:15:15 +0100
Subject: [PATCH 22/29] crypto/md5-buffer: Use 'restrict'.

* lib/md5.h (__md5_finish_ctx, __md5_read_ctx, __md5_buffer): Use
'restrict'.
* modules/crypto/md5-buffer (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog                 | 5 +++++
 lib/md5.h                 | 8 +++++---
 modules/crypto/md5-buffer | 1 +
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bd40d1b..2ed99c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/md5-buffer: Use 'restrict'.
+	* lib/md5.h (__md5_finish_ctx, __md5_read_ctx, __md5_buffer): Use
+	'restrict'.
+	* modules/crypto/md5-buffer (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/md4: Use 'restrict'.
 	* lib/md4.h (md4_finish_ctx, md4_read_ctx, md4_buffer): Use 'restrict'.
 	* modules/crypto/md4 (configure.ac): Require AC_C_RESTRICT.
diff --git a/lib/md5.h b/lib/md5.h
index 9e0c0fb..0c8b929 100644
--- a/lib/md5.h
+++ b/lib/md5.h
@@ -105,13 +105,15 @@ extern void __md5_process_bytes (const void *buffer, size_t len,
    in first 16 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW;
+extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *restrict resbuf)
+     __THROW;
 
 
 /* Put result from CTX in first 16 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW;
+extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *restrict resbuf)
+     __THROW;
 
 
 /* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
@@ -119,7 +121,7 @@ extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW;
    output yields to the wanted ASCII representation of the message
    digest.  */
 extern void *__md5_buffer (const char *buffer, size_t len,
-                           void *resblock) __THROW;
+                           void *restrict resblock) __THROW;
 
 # endif
 /* Compute MD5 message digest for bytes read from STREAM.
diff --git a/modules/crypto/md5-buffer b/modules/crypto/md5-buffer
index 006bc81..fb5763e 100644
--- a/modules/crypto/md5-buffer
+++ b/modules/crypto/md5-buffer
@@ -15,6 +15,7 @@ stdalign
 stdint
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_MD5
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #24: 0023-crypto-sha1-buffer-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2656 bytes --]

From 3b97754de802a01897a8ef4c09edf8487309705f Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:16:44 +0100
Subject: [PATCH 23/29] crypto/sha1-buffer: Use 'restrict'.

* lib/sha1.h (sha1_finish_ctx, sha1_read_ctx, sha1_buffer): Use
'restrict'.
* modules/crypto/sha1-buffer (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog                  | 5 +++++
 lib/sha1.h                 | 7 ++++---
 modules/crypto/sha1-buffer | 1 +
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2ed99c4..379083a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/sha1-buffer: Use 'restrict'.
+	* lib/sha1.h (sha1_finish_ctx, sha1_read_ctx, sha1_buffer): Use
+	'restrict'.
+	* modules/crypto/sha1-buffer (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/md5-buffer: Use 'restrict'.
 	* lib/md5.h (__md5_finish_ctx, __md5_read_ctx, __md5_buffer): Use
 	'restrict'.
diff --git a/lib/sha1.h b/lib/sha1.h
index 99c53da..51496a9 100644
--- a/lib/sha1.h
+++ b/lib/sha1.h
@@ -71,20 +71,21 @@ extern void sha1_process_bytes (const void *buffer, size_t len,
    in first 20 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
+extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *restrict resbuf);
 
 
 /* Put result from CTX in first 20 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
+extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *restrict resbuf);
 
 
 /* Compute SHA1 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
-extern void *sha1_buffer (const char *buffer, size_t len, void *resblock);
+extern void *sha1_buffer (const char *buffer, size_t len,
+                          void *restrict resblock);
 
 # endif
 /* Compute SHA1 message digest for bytes read from STREAM.
diff --git a/modules/crypto/sha1-buffer b/modules/crypto/sha1-buffer
index 807f2dc..55a5420 100644
--- a/modules/crypto/sha1-buffer
+++ b/modules/crypto/sha1-buffer
@@ -15,6 +15,7 @@ stdalign
 stdint
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_SHA1
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #25: 0024-crypto-sha256-buffer-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 3599 bytes --]

From cd6346e11a637b08d364399f900c8ddd3f44bf39 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:18:33 +0100
Subject: [PATCH 24/29] crypto/sha256-buffer: Use 'restrict'.

* lib/sha256.h (sha256_finish_ctx, sha224_finish_ctx, sha256_read_ctx,
sha224_read_ctx, sha256_buffer, sha224_buffer): Use 'restrict'.
* modules/crypto/sha256-buffer (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog                    |  5 +++++
 lib/sha256.h                 | 20 ++++++++++++--------
 modules/crypto/sha256-buffer |  1 +
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 379083a..6e782e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/sha256-buffer: Use 'restrict'.
+	* lib/sha256.h (sha256_finish_ctx, sha224_finish_ctx, sha256_read_ctx,
+	sha224_read_ctx, sha256_buffer, sha224_buffer): Use 'restrict'.
+	* modules/crypto/sha256-buffer (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/sha1-buffer: Use 'restrict'.
 	* lib/sha1.h (sha1_finish_ctx, sha1_read_ctx, sha1_buffer): Use
 	'restrict'.
diff --git a/lib/sha256.h b/lib/sha256.h
index 1bc61d4..750d78a 100644
--- a/lib/sha256.h
+++ b/lib/sha256.h
@@ -70,23 +70,27 @@ extern void sha256_process_bytes (const void *buffer, size_t len,
    in first 32 (28) bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf);
-extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf);
+extern void *sha256_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf);
+extern void *sha224_finish_ctx (struct sha256_ctx *ctx, void *restrict resbuf);
 
 
 /* Put result from CTX in first 32 (28) bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
-extern void *sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf);
+extern void *sha256_read_ctx (const struct sha256_ctx *ctx,
+                              void *restrict resbuf);
+extern void *sha224_read_ctx (const struct sha256_ctx *ctx,
+                              void *restrict resbuf);
 
 
-/* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER.  The
-   result is always in little endian byte order, so that a byte-wise
+/* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER.
+   The result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
-extern void *sha256_buffer (const char *buffer, size_t len, void *resblock);
-extern void *sha224_buffer (const char *buffer, size_t len, void *resblock);
+extern void *sha256_buffer (const char *buffer, size_t len,
+                            void *restrict resblock);
+extern void *sha224_buffer (const char *buffer, size_t len,
+                            void *restrict resblock);
 
 # endif
 /* Compute SHA256 (SHA224) message digest for bytes read from STREAM.
diff --git a/modules/crypto/sha256-buffer b/modules/crypto/sha256-buffer
index e5a4703..055275a 100644
--- a/modules/crypto/sha256-buffer
+++ b/modules/crypto/sha256-buffer
@@ -15,6 +15,7 @@ stdalign
 stdint
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_SHA256
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #26: 0025-crypto-sha512-buffer-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 3714 bytes --]

From 734c22abe7d5d046a360415bb030baf2952d5807 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:20:18 +0100
Subject: [PATCH 25/29] crypto/sha512-buffer: Use 'restrict'.

* lib/sha512.h (sha512_finish_ctx, sha384_finish_ctx, sha512_read_ctx,
sha384_read_ctx, sha512_buffer, sha384_buffer): Use 'restrict'.
* modules/crypto/sha512-buffer (configure.ac): Require AC_C_RESTRICT.
---
 ChangeLog                    |  5 +++++
 lib/sha512.h                 | 20 ++++++++++++--------
 modules/crypto/sha512-buffer |  1 +
 3 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6e782e1..8701bea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/sha512-buffer: Use 'restrict'.
+	* lib/sha512.h (sha512_finish_ctx, sha384_finish_ctx, sha512_read_ctx,
+	sha384_read_ctx, sha512_buffer, sha384_buffer): Use 'restrict'.
+	* modules/crypto/sha512-buffer (configure.ac): Require AC_C_RESTRICT.
+
 	crypto/sha256-buffer: Use 'restrict'.
 	* lib/sha256.h (sha256_finish_ctx, sha224_finish_ctx, sha256_read_ctx,
 	sha224_read_ctx, sha256_buffer, sha224_buffer): Use 'restrict'.
diff --git a/lib/sha512.h b/lib/sha512.h
index aaf35a5..21c2f58 100644
--- a/lib/sha512.h
+++ b/lib/sha512.h
@@ -70,8 +70,8 @@ extern void sha512_process_bytes (const void *buffer, size_t len,
    in first 64 (48) bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
-extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
+extern void *sha512_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf);
+extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *restrict resbuf);
 
 
 /* Put result from CTX in first 64 (48) bytes following RESBUF.  The result is
@@ -80,16 +80,20 @@ extern void *sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf);
 
    IMPORTANT: On some systems it is required that RESBUF is correctly
    aligned for a 32 bits value.  */
-extern void *sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
-extern void *sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf);
+extern void *sha512_read_ctx (const struct sha512_ctx *ctx,
+                              void *restrict resbuf);
+extern void *sha384_read_ctx (const struct sha512_ctx *ctx,
+                              void *restrict resbuf);
 
 
-/* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER.  The
-   result is always in little endian byte order, so that a byte-wise
+/* Compute SHA512 (SHA384) message digest for LEN bytes beginning at BUFFER.
+   The result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
-extern void *sha512_buffer (const char *buffer, size_t len, void *resblock);
-extern void *sha384_buffer (const char *buffer, size_t len, void *resblock);
+extern void *sha512_buffer (const char *buffer, size_t len,
+                            void *restrict resblock);
+extern void *sha384_buffer (const char *buffer, size_t len,
+                            void *restrict resblock);
 
 # endif
 /* Compute SHA512 (SHA384) message digest for bytes read from STREAM.
diff --git a/modules/crypto/sha512-buffer b/modules/crypto/sha512-buffer
index 32170a9..7c5f64d 100644
--- a/modules/crypto/sha512-buffer
+++ b/modules/crypto/sha512-buffer
@@ -16,6 +16,7 @@ stdint
 u64
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 gl_SHA512
 
 Makefile.am:
-- 
2.7.4


[-- Attachment #27: 0026-crypto-buffer-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1937 bytes --]

From 7d4a2b0c17628cc4e5fc159b26498564706ee1be Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:22:42 +0100
Subject: [PATCH 26/29] crypto/*-buffer: Use 'restrict'.

* lib/gl_openssl.h (GL_CRYPTO_FN (_finish_ctx), GL_CRYPTO_FN (_buffer),
GL_CRYPTO_FN (_read_ctx)): Use 'restrict'.
---
 ChangeLog        | 4 ++++
 lib/gl_openssl.h | 6 +++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8701bea..768083e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/*-buffer: Use 'restrict'.
+	* lib/gl_openssl.h (GL_CRYPTO_FN (_finish_ctx), GL_CRYPTO_FN (_buffer),
+	GL_CRYPTO_FN (_read_ctx)): Use 'restrict'.
+
 	crypto/sha512-buffer: Use 'restrict'.
 	* lib/sha512.h (sha512_finish_ctx, sha384_finish_ctx, sha512_read_ctx,
 	sha384_read_ctx, sha512_buffer, sha384_buffer): Use 'restrict'.
diff --git a/lib/gl_openssl.h b/lib/gl_openssl.h
index e5991d8..e985b1c 100644
--- a/lib/gl_openssl.h
+++ b/lib/gl_openssl.h
@@ -90,15 +90,15 @@ GL_CRYPTO_FN (_process_block) (const void *buf, size_t len, struct _gl_ctx *ctx)
 #endif
 
 GL_OPENSSL_INLINE void *
-GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void *res)
+GL_CRYPTO_FN (_finish_ctx) (struct _gl_ctx *ctx, void *restrict res)
 { OPENSSL_FN (_Final) ((unsigned char *) res, (_gl_CTX *) ctx); return res; }
 
 GL_OPENSSL_INLINE void *
-GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void *res)
+GL_CRYPTO_FN (_buffer) (const char *buf, size_t len, void *restrict res)
 { return OPENSSL_FN () ((const unsigned char *) buf, len, (unsigned char *) res); }
 
 GL_OPENSSL_INLINE void *
-GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void *res)
+GL_CRYPTO_FN (_read_ctx) (const struct _gl_ctx *ctx, void *restrict res)
 {
   /* Assume any unprocessed bytes in ctx are not to be ignored.  */
   _gl_CTX tmp_ctx = *(_gl_CTX *) ctx;
-- 
2.7.4


[-- Attachment #28: 0027-crypto-sm3-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 2865 bytes --]

From fd783467d341d2916ef5a798748c2bab20e6ec2a Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:25:28 +0100
Subject: [PATCH 27/29] crypto/sm3: Use 'restrict'.

* lib/sm3.h (sm3_finish_ctx, sm3_read_ctx, sm3_buffer): Use 'restrict'.
* m4/sm3.m4 (gl_SM3): Require AC_C_RESTRICT.
---
 ChangeLog | 4 ++++
 lib/sm3.h | 7 ++++---
 m4/sm3.m4 | 5 ++++-
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 768083e..5a1c591 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/sm3: Use 'restrict'.
+	* lib/sm3.h (sm3_finish_ctx, sm3_read_ctx, sm3_buffer): Use 'restrict'.
+	* m4/sm3.m4 (gl_SM3): Require AC_C_RESTRICT.
+
 	crypto/*-buffer: Use 'restrict'.
 	* lib/gl_openssl.h (GL_CRYPTO_FN (_finish_ctx), GL_CRYPTO_FN (_buffer),
 	GL_CRYPTO_FN (_read_ctx)): Use 'restrict'.
diff --git a/lib/sm3.h b/lib/sm3.h
index e0bdd90..fd7cc98 100644
--- a/lib/sm3.h
+++ b/lib/sm3.h
@@ -75,18 +75,19 @@ extern void sm3_process_bytes (const void *buffer, size_t len,
    in first 32 bytes following RESBUF.  The result is always in little
    endian byte order, so that a byte-wise output yields to the wanted
    ASCII representation of the message digest.  */
-extern void *sm3_finish_ctx (struct sm3_ctx *ctx, void *resbuf);
+extern void *sm3_finish_ctx (struct sm3_ctx *ctx, void *restrict resbuf);
 
 /* Put result from CTX in first 32 bytes following RESBUF.  The result is
    always in little endian byte order, so that a byte-wise output yields
    to the wanted ASCII representation of the message digest.  */
-extern void *sm3_read_ctx (const struct sm3_ctx *ctx, void *resbuf);
+extern void *sm3_read_ctx (const struct sm3_ctx *ctx, void *restrict resbuf);
 
 /* Compute SM3 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
-extern void *sm3_buffer (const char *buffer, size_t len, void *resblock);
+extern void *sm3_buffer (const char *buffer, size_t len,
+                         void *restrict resblock);
 
 # endif
 /* Compute SM3 message digest for bytes read from STREAM.  The
diff --git a/m4/sm3.m4 b/m4/sm3.m4
index af8cb5a..cb31930 100644
--- a/m4/sm3.m4
+++ b/m4/sm3.m4
@@ -1,4 +1,4 @@
-# sm3.m4 serial 1
+# sm3.m4 serial 2
 dnl Copyright (C) 2017-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -6,6 +6,9 @@ dnl with or without modifications, as long as this notice is preserved.
 
 AC_DEFUN([gl_SM3],
 [
+  dnl Prerequisites of lib/sm3.h.
+  AC_REQUIRE([AC_C_RESTRICT])
+
   dnl Prerequisites of lib/sm3.c.
   AC_REQUIRE([gl_BIGENDIAN])
 
-- 
2.7.4


[-- Attachment #29: 0028-crypto-hmac-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 4171 bytes --]

From 7c69c58720bc2b3cdfca4a3d8564f77aa662e576 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:27:35 +0100
Subject: [PATCH 28/29] crypto/hmac-*: Use 'restrict'.

* lib/hmac.h (hmac_md5, hmac_sha1, hmac_sha256, hmac_sha512): Use
'restrict'.
* modules/crypto/hmac-md5 (configure.ac): Require AC_C_RESTRICT.
* modules/crypto/hmac-sha1 (configure.ac): Likewise.
* modules/crypto/hmac-sha256 (configure.ac): Likewise.
* modules/crypto/hmac-sha512 (configure.ac): Likewise.
---
 ChangeLog                  | 8 ++++++++
 lib/hmac.h                 | 8 ++++----
 modules/crypto/hmac-md5    | 1 +
 modules/crypto/hmac-sha1   | 1 +
 modules/crypto/hmac-sha256 | 1 +
 modules/crypto/hmac-sha512 | 1 +
 6 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5a1c591..e62e1aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/hmac-*: Use 'restrict'.
+	* lib/hmac.h (hmac_md5, hmac_sha1, hmac_sha256, hmac_sha512): Use
+	'restrict'.
+	* modules/crypto/hmac-md5 (configure.ac): Require AC_C_RESTRICT.
+	* modules/crypto/hmac-sha1 (configure.ac): Likewise.
+	* modules/crypto/hmac-sha256 (configure.ac): Likewise.
+	* modules/crypto/hmac-sha512 (configure.ac): Likewise.
+
 	crypto/sm3: Use 'restrict'.
 	* lib/sm3.h (sm3_finish_ctx, sm3_read_ctx, sm3_buffer): Use 'restrict'.
 	* m4/sm3.m4 (gl_SM3): Require AC_C_RESTRICT.
diff --git a/lib/hmac.h b/lib/hmac.h
index a390702..135eb2a 100644
--- a/lib/hmac.h
+++ b/lib/hmac.h
@@ -27,7 +27,7 @@
    RESBUF buffer.  Return 0 on success.  */
 int
 hmac_md5 (const void *key, size_t keylen,
-          const void *buffer, size_t buflen, void *resbuf);
+          const void *buffer, size_t buflen, void *restrict resbuf);
 
 /* Compute Hashed Message Authentication Code with SHA-1, over BUFFER
    data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
@@ -35,7 +35,7 @@ hmac_md5 (const void *key, size_t keylen,
    success.  */
 int
 hmac_sha1 (const void *key, size_t keylen,
-           const void *in, size_t inlen, void *resbuf);
+           const void *in, size_t inlen, void *restrict resbuf);
 
 /* Compute Hashed Message Authentication Code with SHA-256, over BUFFER
    data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
@@ -43,7 +43,7 @@ hmac_sha1 (const void *key, size_t keylen,
    success.  */
 int
 hmac_sha256 (const void *key, size_t keylen,
-             const void *in, size_t inlen, void *resbuf);
+             const void *in, size_t inlen, void *restrict resbuf);
 
 /* Compute Hashed Message Authentication Code with SHA-512, over BUFFER
    data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
@@ -51,6 +51,6 @@ hmac_sha256 (const void *key, size_t keylen,
    success.  */
 int
 hmac_sha512 (const void *key, size_t keylen,
-             const void *in, size_t inlen, void *resbuf);
+             const void *in, size_t inlen, void *restrict resbuf);
 
 #endif /* HMAC_H */
diff --git a/modules/crypto/hmac-md5 b/modules/crypto/hmac-md5
index a2bb9ed..8739c06 100644
--- a/modules/crypto/hmac-md5
+++ b/modules/crypto/hmac-md5
@@ -11,6 +11,7 @@ memxor
 crypto/md5
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += hmac-md5.c
diff --git a/modules/crypto/hmac-sha1 b/modules/crypto/hmac-sha1
index 6bec8ae..d49d68d 100644
--- a/modules/crypto/hmac-sha1
+++ b/modules/crypto/hmac-sha1
@@ -11,6 +11,7 @@ memxor
 crypto/sha1
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += hmac-sha1.c
diff --git a/modules/crypto/hmac-sha256 b/modules/crypto/hmac-sha256
index 8bd47e8..e67ffd4 100644
--- a/modules/crypto/hmac-sha256
+++ b/modules/crypto/hmac-sha256
@@ -11,6 +11,7 @@ memxor
 crypto/sha256
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += hmac-sha256.c
diff --git a/modules/crypto/hmac-sha512 b/modules/crypto/hmac-sha512
index ad0e81b..53e11f8 100644
--- a/modules/crypto/hmac-sha512
+++ b/modules/crypto/hmac-sha512
@@ -11,6 +11,7 @@ memxor
 crypto/sha512
 
 configure.ac:
+AC_REQUIRE([AC_C_RESTRICT])
 
 Makefile.am:
 lib_SOURCES += hmac-sha512.c
-- 
2.7.4


[-- Attachment #30: 0029-crypto-gc-Use-restrict.patch --]
[-- Type: text/x-patch, Size: 1905 bytes --]

From 46b3b6881a8a677c7a577ec4182b2eb4d5aa230c Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Sun, 23 Feb 2020 13:29:14 +0100
Subject: [PATCH 29/29] crypto/gc: Use 'restrict'.

* lib/gc.h (gc_pbkdf2_hmac, gc_pbkdf2_sha1): Use 'restrict'.
* m4/gc.m4 (gl_GC): Require AC_C_RESTRICT.
---
 ChangeLog | 4 ++++
 lib/gc.h  | 4 ++--
 m4/gc.m4  | 4 +++-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e62e1aa..5b5b35d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2020-02-23  Bruno Haible  <bruno@clisp.org>
 
+	crypto/gc: Use 'restrict'.
+	* lib/gc.h (gc_pbkdf2_hmac, gc_pbkdf2_sha1): Use 'restrict'.
+	* m4/gc.m4 (gl_GC): Require AC_C_RESTRICT.
+
 	crypto/hmac-*: Use 'restrict'.
 	* lib/hmac.h (hmac_md5, hmac_sha1, hmac_sha256, hmac_sha512): Use
 	'restrict'.
diff --git a/lib/gc.h b/lib/gc.h
index 05fb8a3..87acdbc 100644
--- a/lib/gc.h
+++ b/lib/gc.h
@@ -185,12 +185,12 @@ extern Gc_rc
 gc_pbkdf2_hmac (Gc_hash hash,
                 const char *P, size_t Plen,
                 const char *S, size_t Slen,
-                unsigned int c, char *DK, size_t dkLen);
+                unsigned int c, char *restrict DK, size_t dkLen);
 
 extern Gc_rc
 gc_pbkdf2_sha1 (const char *P, size_t Plen,
                 const char *S, size_t Slen,
-                unsigned int c, char *DK, size_t dkLen);
+                unsigned int c, char *restrict DK, size_t dkLen);
 
 /*
   TODO:
diff --git a/m4/gc.m4 b/m4/gc.m4
index 0180d32..7f8f462 100644
--- a/m4/gc.m4
+++ b/m4/gc.m4
@@ -1,4 +1,4 @@
-# gc.m4 serial 12
+# gc.m4 serial 13
 dnl Copyright (C) 2005-2020 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -25,4 +25,6 @@ AC_DEFUN([gl_GC],
     fi
   fi
   AC_SUBST([LIB_CRYPTO])
+
+  AC_REQUIRE([AC_C_RESTRICT])
 ])
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: restrict - summary
  2020-02-17 21:19     ` restrict - summary Bruno Haible
  2020-02-22 22:51       ` Bruno Haible
  2020-02-23 12:39       ` Bruno Haible
@ 2020-02-23 13:30       ` Bruno Haible
  2 siblings, 0 replies; 20+ messages in thread
From: Bruno Haible @ 2020-02-23 13:30 UTC (permalink / raw)
  To: bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

This patch, finally, makes use of 'restrict' also in the libunistring header
files.


2020-02-23  Bruno Haible  <bruno@clisp.org>

	uni*/base: Use 'restrict'.
	* lib/unitypes.in.h (_UC_RESTRICT): New macro, based on '_Restrict_'
	from lib/regex.h.
	* lib/unistr.in.h (u8_cpy, u16_cpy, u32_cpy, u8_strcpy, u16_strcpy,
	u32_strcpy, u8_stpcpy, u16_stpcpy, u32_stpcpy, u8_strncpy, u16_strncpy,
	u32_strncpy, u8_stpncpy, u16_stpncpy, u32_stpncpy, u8_strcat,
	u16_strcat, u32_strcat, u8_strncat, u16_strncat, u32_strncat, u8_strtok,
	u16_strtok, u32_strtok): Use '_UC_RESTRICT'.
	* lib/uninorm.in.h (u8_normalize, u16_normalize, u32_normalize): Use
	'_UC_RESTRICT'.
	* lib/uniconv.in.h (u8_conv_to_encoding, u16_conv_to_encoding,
	u32_conv_to_encoding): Use '_UC_RESTRICT'.
	* lib/unicase.in.h (u8_toupper, u16_toupper, u32_toupper, u8_tolower,
	u16_tolower, u32_tolower, u8_totitle, u16_totitle, u32_totitle,
	u8_ct_toupper, u16_ct_toupper, u32_ct_toupper, u8_ct_tolower,
	u16_ct_tolower, u32_ct_tolower, u8_ct_totitle, u16_ct_totitle,
	u32_ct_totitle, u8_casefold, u16_casefold, u32_casefold, u8_ct_casefold,
	u16_ct_casefold, u32_ct_casefold, u8_casexfrm, u16_casexfrm,
	u32_casexfrm, ulc_casexfrm): Use '_UC_RESTRICT'.
	* lib/unilbrk.in.h (u8_possible_linebreaks, u16_possible_linebreaks,
	u32_possible_linebreaks, ulc_possible_linebreaks, u8_width_linebreaks,
	u16_width_linebreaks, u32_width_linebreaks, ulc_width_linebreaks): Use
	'_UC_RESTRICT'.
	* lib/uniwbrk.in.h (ulc_wordbreaks): Use '_UC_RESTRICT'.
	* lib/unistdio.in.h (ulc_sprintf, ulc_snprintf, ulc_asnprintf,
	ulc_vsprintf, ulc_vsnprintf, ulc_vasnprintf, u8_u8_sprintf,
	u8_u8_snprintf, u8_u8_asnprintf, u8_u8_vsprintf, u8_u8_vsnprintf,
	u8_u8_vasnprintf, u16_u16_sprintf, u16_u16_snprintf, u16_u16_asnprintf,
	u16_u16_vsprintf, u16_u16_vsnprintf, u16_u16_vasnprintf,
	u32_u32_sprintf, u32_u32_snprintf, u32_u32_asnprintf, u32_u32_vsprintf,
	u32_u32_vsnprintf, u32_u32_vasnprintf): Use '_UC_RESTRICT'.

diff --git a/lib/unitypes.in.h b/lib/unitypes.in.h
index c7c268f..5fff76a 100644
--- a/lib/unitypes.in.h
+++ b/lib/unitypes.in.h
@@ -43,4 +43,17 @@ typedef uint32_t ucs4_t;
 # endif
 #endif
 
+/* Qualifier in a function declaration, that asserts that the caller must
+   pass a pointer to a different object in the specified pointer argument
+   than in the other pointer arguments.  */
+#ifndef _UC_RESTRICT
+# if defined __restrict || 2 < __GNUC__ + (95 <= __GNUC_MINOR__)
+#  define _UC_RESTRICT __restrict
+# elif 199901L <= __STDC_VERSION__ || defined restrict
+#  define _UC_RESTRICT restrict
+# else
+#  define _UC_RESTRICT
+# endif
+#endif
+
 #endif /* _UNITYPES_H */
diff --git a/lib/unicase.in.h b/lib/unicase.in.h
index 45c5f91..d74afa1 100644
--- a/lib/unicase.in.h
+++ b/lib/unicase.in.h
@@ -96,15 +96,15 @@ extern const char *
 extern uint8_t *
        u8_toupper (const uint8_t *s, size_t n, const char *iso639_language,
                    uninorm_t nf,
-                   uint8_t *resultbuf, size_t *lengthp);
+                   uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_toupper (const uint16_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint16_t *resultbuf, size_t *lengthp);
+                    uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_toupper (const uint32_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint32_t *resultbuf, size_t *lengthp);
+                    uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Return the lowercase mapping of a string.
    The nf argument identifies the normalization form to apply after the
@@ -112,15 +112,15 @@ extern uint32_t *
 extern uint8_t *
        u8_tolower (const uint8_t *s, size_t n, const char *iso639_language,
                    uninorm_t nf,
-                   uint8_t *resultbuf, size_t *lengthp);
+                   uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_tolower (const uint16_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint16_t *resultbuf, size_t *lengthp);
+                    uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_tolower (const uint32_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint32_t *resultbuf, size_t *lengthp);
+                    uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Return the titlecase mapping of a string.
    The nf argument identifies the normalization form to apply after the
@@ -128,15 +128,15 @@ extern uint32_t *
 extern uint8_t *
        u8_totitle (const uint8_t *s, size_t n, const char *iso639_language,
                    uninorm_t nf,
-                   uint8_t *resultbuf, size_t *lengthp);
+                   uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_totitle (const uint16_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint16_t *resultbuf, size_t *lengthp);
+                    uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_totitle (const uint32_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint32_t *resultbuf, size_t *lengthp);
+                    uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* The case-mapping context given by a prefix string.  */
 typedef struct casing_prefix_context
@@ -204,21 +204,21 @@ extern uint8_t *
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint8_t *resultbuf, size_t *lengthp);
+                      uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_toupper (const uint16_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_toupper (const uint32_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Return the lowercase mapping of a string that is surrounded by a prefix
    and a suffix.  */
@@ -228,21 +228,21 @@ extern uint8_t *
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint8_t *resultbuf, size_t *lengthp);
+                      uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_tolower (const uint16_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_tolower (const uint32_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Return the titlecase mapping of a string that is surrounded by a prefix
    and a suffix.  */
@@ -252,21 +252,21 @@ extern uint8_t *
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint8_t *resultbuf, size_t *lengthp);
+                      uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_totitle (const uint16_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_totitle (const uint32_t *s, size_t n,
                       casing_prefix_context_t prefix_context,
                       casing_suffix_context_t suffix_context,
                       const char *iso639_language,
                       uninorm_t nf,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Return the case folded string.
    Comparing uN_casefold (S1) and uN_casefold (S2) with uN_cmp2() is equivalent
@@ -276,15 +276,15 @@ extern uint32_t *
 extern uint8_t *
        u8_casefold (const uint8_t *s, size_t n, const char *iso639_language,
                     uninorm_t nf,
-                    uint8_t *resultbuf, size_t *lengthp);
+                    uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_casefold (const uint16_t *s, size_t n, const char *iso639_language,
                      uninorm_t nf,
-                     uint16_t *resultbuf, size_t *lengthp);
+                     uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_casefold (const uint32_t *s, size_t n, const char *iso639_language,
                      uninorm_t nf,
-                     uint32_t *resultbuf, size_t *lengthp);
+                     uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 /* Likewise, for a string that is surrounded by a prefix and a suffix.  */
 extern uint8_t *
        u8_ct_casefold (const uint8_t *s, size_t n,
@@ -292,21 +292,21 @@ extern uint8_t *
                        casing_suffix_context_t suffix_context,
                        const char *iso639_language,
                        uninorm_t nf,
-                       uint8_t *resultbuf, size_t *lengthp);
+                       uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_ct_casefold (const uint16_t *s, size_t n,
                         casing_prefix_context_t prefix_context,
                         casing_suffix_context_t suffix_context,
                         const char *iso639_language,
                         uninorm_t nf,
-                        uint16_t *resultbuf, size_t *lengthp);
+                        uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_ct_casefold (const uint32_t *s, size_t n,
                         casing_prefix_context_t prefix_context,
                         casing_suffix_context_t suffix_context,
                         const char *iso639_language,
                         uninorm_t nf,
-                        uint32_t *resultbuf, size_t *lengthp);
+                        uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Compare S1 and S2, ignoring differences in case and normalization.
    The nf argument identifies the normalization form to apply after the
@@ -336,16 +336,20 @@ extern int
    NF must be either UNINORM_NFC, UNINORM_NFKC, or NULL for no normalization.  */
 extern char *
        u8_casexfrm (const uint8_t *s, size_t n, const char *iso639_language,
-                    uninorm_t nf, char *resultbuf, size_t *lengthp);
+                    uninorm_t nf,
+                    char *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern char *
        u16_casexfrm (const uint16_t *s, size_t n, const char *iso639_language,
-                     uninorm_t nf, char *resultbuf, size_t *lengthp);
+                     uninorm_t nf,
+                     char *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern char *
        u32_casexfrm (const uint32_t *s, size_t n, const char *iso639_language,
-                     uninorm_t nf, char *resultbuf, size_t *lengthp);
+                     uninorm_t nf,
+                     char *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern char *
        ulc_casexfrm (const char *s, size_t n, const char *iso639_language,
-                     uninorm_t nf, char *resultbuf, size_t *lengthp);
+                     uninorm_t nf,
+                     char *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Compare S1 and S2, ignoring differences in case and normalization, using the
    collation rules of the current locale.
diff --git a/lib/uniconv.in.h b/lib/uniconv.in.h
index 53dc3fc..d552edb 100644
--- a/lib/uniconv.in.h
+++ b/lib/uniconv.in.h
@@ -98,19 +98,19 @@ extern char *
                             enum iconv_ilseq_handler handler,
                             const uint8_t *src, size_t srclen,
                             size_t *offsets,
-                            char *resultbuf, size_t *lengthp);
+                            char *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern char *
        u16_conv_to_encoding (const char *tocode,
                              enum iconv_ilseq_handler handler,
                              const uint16_t *src, size_t srclen,
                              size_t *offsets,
-                             char *resultbuf, size_t *lengthp);
+                             char *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern char *
        u32_conv_to_encoding (const char *tocode,
                              enum iconv_ilseq_handler handler,
                              const uint32_t *src, size_t srclen,
                              size_t *offsets,
-                             char *resultbuf, size_t *lengthp);
+                             char *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 /* Converts a NUL terminated string from a given encoding.
    The result is malloc allocated, or NULL (with errno set) in case of error.
diff --git a/lib/unilbrk.in.h b/lib/unilbrk.in.h
index 408b905..6c5ac86 100644
--- a/lib/unilbrk.in.h
+++ b/lib/unilbrk.in.h
@@ -58,16 +58,16 @@ enum
  */
 extern void
        u8_possible_linebreaks (const uint8_t *s, size_t n,
-                               const char *encoding, char *p);
+                               const char *encoding, char *_UC_RESTRICT p);
 extern void
        u16_possible_linebreaks (const uint16_t *s, size_t n,
-                                const char *encoding, char *p);
+                                const char *encoding, char *_UC_RESTRICT p);
 extern void
        u32_possible_linebreaks (const uint32_t *s, size_t n,
-                                const char *encoding, char *p);
+                                const char *encoding, char *_UC_RESTRICT p);
 extern void
        ulc_possible_linebreaks (const char *s, size_t n,
-                                const char *encoding, char *p);
+                                const char *encoding, char *_UC_RESTRICT p);
 
 /* Choose the best line breaks, assuming the uc_width function.
    The string is s[0..n-1].  The maximum number of columns per line is given
@@ -84,22 +84,22 @@ extern int
        u8_width_linebreaks (const uint8_t *s, size_t n, int width,
                             int start_column, int at_end_columns,
                             const char *o, const char *encoding,
-                            char *p);
+                            char *_UC_RESTRICT p);
 extern int
        u16_width_linebreaks (const uint16_t *s, size_t n, int width,
                              int start_column, int at_end_columns,
                              const char *o, const char *encoding,
-                             char *p);
+                             char *_UC_RESTRICT p);
 extern int
        u32_width_linebreaks (const uint32_t *s, size_t n, int width,
                              int start_column, int at_end_columns,
                              const char *o, const char *encoding,
-                             char *p);
+                             char *_UC_RESTRICT p);
 extern int
        ulc_width_linebreaks (const char *s, size_t n, int width,
                              int start_column, int at_end_columns,
                              const char *o, const char *encoding,
-                             char *p);
+                             char *_UC_RESTRICT p);
 
 
 #ifdef __cplusplus
diff --git a/lib/uninorm.in.h b/lib/uninorm.in.h
index 9ebdb6b..4cef857 100644
--- a/lib/uninorm.in.h
+++ b/lib/uninorm.in.h
@@ -143,13 +143,13 @@ extern uninorm_t
 /* Return the specified normalization form of a string.  */
 extern uint8_t *
        u8_normalize (uninorm_t nf, const uint8_t *s, size_t n,
-                     uint8_t *resultbuf, size_t *lengthp);
+                     uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint16_t *
        u16_normalize (uninorm_t nf, const uint16_t *s, size_t n,
-                      uint16_t *resultbuf, size_t *lengthp);
+                      uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 extern uint32_t *
        u32_normalize (uninorm_t nf, const uint32_t *s, size_t n,
-                      uint32_t *resultbuf, size_t *lengthp);
+                      uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp);
 
 
 /* Compare S1 and S2, ignoring differences in normalization.
diff --git a/lib/unistdio.in.h b/lib/unistdio.in.h
index e6091ec..cb17dd6 100644
--- a/lib/unistdio.in.h
+++ b/lib/unistdio.in.h
@@ -61,28 +61,28 @@ extern "C" {
 
 /* ASCII format string, result in locale dependent encoded 'char *'.  */
 extern int
-       ulc_sprintf (char *buf,
+       ulc_sprintf (char *_UC_RESTRICT buf,
                     const char *format, ...);
 extern int
-       ulc_snprintf (char *buf, size_t size,
+       ulc_snprintf (char *_UC_RESTRICT buf, size_t size,
                      const char *format, ...);
 extern int
        ulc_asprintf (char **resultp,
                      const char *format, ...);
 extern char *
-       ulc_asnprintf (char *resultbuf, size_t *lengthp,
+       ulc_asnprintf (char *_UC_RESTRICT resultbuf, size_t *lengthp,
                       const char *format, ...);
 extern int
-       ulc_vsprintf (char *buf,
+       ulc_vsprintf (char *_UC_RESTRICT buf,
                      const char *format, va_list ap);
 extern int
-       ulc_vsnprintf (char *buf, size_t size,
+       ulc_vsnprintf (char *_UC_RESTRICT buf, size_t size,
                       const char *format, va_list ap);
 extern int
        ulc_vasprintf (char **resultp,
                       const char *format, va_list ap);
 extern char *
-       ulc_vasnprintf (char *resultbuf, size_t *lengthp,
+       ulc_vasnprintf (char *_UC_RESTRICT resultbuf, size_t *lengthp,
                        const char *format, va_list ap);
 
 /* ASCII format string, result in UTF-8 format.  */
@@ -113,28 +113,28 @@ extern uint8_t *
 
 /* UTF-8 format string, result in UTF-8 format.  */
 extern int
-       u8_u8_sprintf (uint8_t *buf,
+       u8_u8_sprintf (uint8_t *_UC_RESTRICT buf,
                       const uint8_t *format, ...);
 extern int
-       u8_u8_snprintf (uint8_t *buf, size_t size,
+       u8_u8_snprintf (uint8_t *_UC_RESTRICT buf, size_t size,
                        const uint8_t *format, ...);
 extern int
        u8_u8_asprintf (uint8_t **resultp,
                        const uint8_t *format, ...);
 extern uint8_t *
-       u8_u8_asnprintf (uint8_t *resultbuf, size_t *lengthp,
+       u8_u8_asnprintf (uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp,
                         const uint8_t *format, ...);
 extern int
-       u8_u8_vsprintf (uint8_t *buf,
+       u8_u8_vsprintf (uint8_t *_UC_RESTRICT buf,
                        const uint8_t *format, va_list ap);
 extern int
-       u8_u8_vsnprintf (uint8_t *buf, size_t size,
+       u8_u8_vsnprintf (uint8_t *_UC_RESTRICT buf, size_t size,
                         const uint8_t *format, va_list ap);
 extern int
        u8_u8_vasprintf (uint8_t **resultp,
                         const uint8_t *format, va_list ap);
 extern uint8_t *
-       u8_u8_vasnprintf (uint8_t *resultbuf, size_t *lengthp,
+       u8_u8_vasnprintf (uint8_t *_UC_RESTRICT resultbuf, size_t *lengthp,
                          const uint8_t *format, va_list ap);
 
 /* ASCII format string, result in UTF-16 format.  */
@@ -165,28 +165,28 @@ extern uint16_t *
 
 /* UTF-16 format string, result in UTF-16 format.  */
 extern int
-       u16_u16_sprintf (uint16_t *buf,
+       u16_u16_sprintf (uint16_t *_UC_RESTRICT buf,
                         const uint16_t *format, ...);
 extern int
-       u16_u16_snprintf (uint16_t *buf, size_t size,
+       u16_u16_snprintf (uint16_t *_UC_RESTRICT buf, size_t size,
                          const uint16_t *format, ...);
 extern int
        u16_u16_asprintf (uint16_t **resultp,
                          const uint16_t *format, ...);
 extern uint16_t *
-       u16_u16_asnprintf (uint16_t *resultbuf, size_t *lengthp,
+       u16_u16_asnprintf (uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp,
                           const uint16_t *format, ...);
 extern int
-       u16_u16_vsprintf (uint16_t *buf,
+       u16_u16_vsprintf (uint16_t *_UC_RESTRICT buf,
                          const uint16_t *format, va_list ap);
 extern int
-       u16_u16_vsnprintf (uint16_t *buf, size_t size,
+       u16_u16_vsnprintf (uint16_t *_UC_RESTRICT buf, size_t size,
                           const uint16_t *format, va_list ap);
 extern int
        u16_u16_vasprintf (uint16_t **resultp,
                           const uint16_t *format, va_list ap);
 extern uint16_t *
-       u16_u16_vasnprintf (uint16_t *resultbuf, size_t *lengthp,
+       u16_u16_vasnprintf (uint16_t *_UC_RESTRICT resultbuf, size_t *lengthp,
                            const uint16_t *format, va_list ap);
 
 /* ASCII format string, result in UTF-32 format.  */
@@ -217,28 +217,28 @@ extern uint32_t *
 
 /* UTF-32 format string, result in UTF-32 format.  */
 extern int
-       u32_u32_sprintf (uint32_t *buf,
+       u32_u32_sprintf (uint32_t *_UC_RESTRICT buf,
                         const uint32_t *format, ...);
 extern int
-       u32_u32_snprintf (uint32_t *buf, size_t size,
+       u32_u32_snprintf (uint32_t *_UC_RESTRICT buf, size_t size,
                          const uint32_t *format, ...);
 extern int
        u32_u32_asprintf (uint32_t **resultp,
                          const uint32_t *format, ...);
 extern uint32_t *
-       u32_u32_asnprintf (uint32_t *resultbuf, size_t *lengthp,
+       u32_u32_asnprintf (uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp,
                           const uint32_t *format, ...);
 extern int
-       u32_u32_vsprintf (uint32_t *buf,
+       u32_u32_vsprintf (uint32_t *_UC_RESTRICT buf,
                          const uint32_t *format, va_list ap);
 extern int
-       u32_u32_vsnprintf (uint32_t *buf, size_t size,
+       u32_u32_vsnprintf (uint32_t *_UC_RESTRICT buf, size_t size,
                           const uint32_t *format, va_list ap);
 extern int
        u32_u32_vasprintf (uint32_t **resultp,
                           const uint32_t *format, va_list ap);
 extern uint32_t *
-       u32_u32_vasnprintf (uint32_t *resultbuf, size_t *lengthp,
+       u32_u32_vasnprintf (uint32_t *_UC_RESTRICT resultbuf, size_t *lengthp,
                            const uint32_t *format, va_list ap);
 
 /* ASCII format string, output to FILE in locale dependent encoding.  */
diff --git a/lib/unistr.in.h b/lib/unistr.in.h
index bc0d237..0acfae6 100644
--- a/lib/unistr.in.h
+++ b/lib/unistr.in.h
@@ -373,11 +373,11 @@ u32_uctomb (uint32_t *s, ucs4_t uc, int n)
 /* Copy N units from SRC to DEST.  */
 /* Similar to memcpy().  */
 extern uint8_t *
-       u8_cpy (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_cpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_cpy (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_cpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_cpy (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_cpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
 
 /* Copy N units from SRC to DEST, guaranteeing correct behavior for
    overlapping memory areas.  */
@@ -528,57 +528,57 @@ extern size_t
 /* Copy SRC to DEST.  */
 /* Similar to strcpy(), wcscpy().  */
 extern uint8_t *
-       u8_strcpy (uint8_t *dest, const uint8_t *src);
+       u8_strcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
 extern uint16_t *
-       u16_strcpy (uint16_t *dest, const uint16_t *src);
+       u16_strcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
 extern uint32_t *
-       u32_strcpy (uint32_t *dest, const uint32_t *src);
+       u32_strcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
 
 /* Copy SRC to DEST, returning the address of the terminating NUL in DEST.  */
 /* Similar to stpcpy().  */
 extern uint8_t *
-       u8_stpcpy (uint8_t *dest, const uint8_t *src);
+       u8_stpcpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
 extern uint16_t *
-       u16_stpcpy (uint16_t *dest, const uint16_t *src);
+       u16_stpcpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
 extern uint32_t *
-       u32_stpcpy (uint32_t *dest, const uint32_t *src);
+       u32_stpcpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
 
 /* Copy no more than N units of SRC to DEST.  */
 /* Similar to strncpy(), wcsncpy().  */
 extern uint8_t *
-       u8_strncpy (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_strncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_strncpy (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_strncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_strncpy (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_strncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
 
 /* Copy no more than N units of SRC to DEST.  Return a pointer past the last
    non-NUL unit written into DEST.  */
 /* Similar to stpncpy().  */
 extern uint8_t *
-       u8_stpncpy (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_stpncpy (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_stpncpy (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_stpncpy (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_stpncpy (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_stpncpy (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
 
 /* Append SRC onto DEST.  */
 /* Similar to strcat(), wcscat().  */
 extern uint8_t *
-       u8_strcat (uint8_t *dest, const uint8_t *src);
+       u8_strcat (uint8_t *_UC_RESTRICT dest, const uint8_t *src);
 extern uint16_t *
-       u16_strcat (uint16_t *dest, const uint16_t *src);
+       u16_strcat (uint16_t *_UC_RESTRICT dest, const uint16_t *src);
 extern uint32_t *
-       u32_strcat (uint32_t *dest, const uint32_t *src);
+       u32_strcat (uint32_t *_UC_RESTRICT dest, const uint32_t *src);
 
 /* Append no more than N units of SRC onto DEST.  */
 /* Similar to strncat(), wcsncat().  */
 extern uint8_t *
-       u8_strncat (uint8_t *dest, const uint8_t *src, size_t n);
+       u8_strncat (uint8_t *_UC_RESTRICT dest, const uint8_t *src, size_t n);
 extern uint16_t *
-       u16_strncat (uint16_t *dest, const uint16_t *src, size_t n);
+       u16_strncat (uint16_t *_UC_RESTRICT dest, const uint16_t *src, size_t n);
 extern uint32_t *
-       u32_strncat (uint32_t *dest, const uint32_t *src, size_t n);
+       u32_strncat (uint32_t *_UC_RESTRICT dest, const uint32_t *src, size_t n);
 
 /* Compare S1 and S2.  */
 /* Similar to strcmp(), wcscmp().  */
@@ -732,11 +732,14 @@ extern bool
    This interface is actually more similar to wcstok than to strtok.  */
 /* Similar to strtok_r(), wcstok().  */
 extern uint8_t *
-       u8_strtok (uint8_t *str, const uint8_t *delim, uint8_t **ptr);
+       u8_strtok (uint8_t *_UC_RESTRICT str, const uint8_t *delim,
+                  uint8_t **ptr);
 extern uint16_t *
-       u16_strtok (uint16_t *str, const uint16_t *delim, uint16_t **ptr);
+       u16_strtok (uint16_t *_UC_RESTRICT str, const uint16_t *delim,
+                   uint16_t **ptr);
 extern uint32_t *
-       u32_strtok (uint32_t *str, const uint32_t *delim, uint32_t **ptr);
+       u32_strtok (uint32_t *_UC_RESTRICT str, const uint32_t *delim,
+                   uint32_t **ptr);
 
 
 #ifdef __cplusplus
diff --git a/lib/uniwbrk.in.h b/lib/uniwbrk.in.h
index 1407644..136aad0 100644
--- a/lib/uniwbrk.in.h
+++ b/lib/uniwbrk.in.h
@@ -81,7 +81,7 @@ extern void
 extern void
        u32_wordbreaks (const uint32_t *s, size_t n, char *p);
 extern void
-       ulc_wordbreaks (const char *s, size_t n, char *p);
+       ulc_wordbreaks (const char *s, size_t n, char *_UC_RESTRICT p);
 
 /* ========================================================================= */
 



^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: restrict - summary
  2020-02-22 22:51       ` Bruno Haible
@ 2020-02-24 19:17         ` Eric Blake
  0 siblings, 0 replies; 20+ messages in thread
From: Eric Blake @ 2020-02-24 19:17 UTC (permalink / raw)
  To: Bruno Haible, bug-gnulib; +Cc: Tim Rühsen, Mats Erik Andersson

On 2/22/20 4:51 PM, Bruno Haible wrote:
> Here comes the first part: the 'restrict' in the POSIX function declarations.
> 
> Note that the POSIX declarations of posix_spawn and posix_spawnp [1] are
> incorrect: They lack a 'restrict' for the file_actions argument.
> 
> [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html

Bug reported to the POSIX folks:
https://www.austingroupbugs.net/view.php?id=1328

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org



^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2020-02-24 19:18 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-09 14:44 Possible testing case of snprintf Mats Erik Andersson
2020-02-09 15:24 ` Tim Rühsen
2020-02-10  3:02   ` restrict Bruno Haible
2020-02-10  8:39     ` restrict Jeffrey Walton
2020-02-10 10:11     ` restrict Tim Rühsen
2020-02-16 21:44     ` restrict Paul Eggert
2020-02-16 23:49       ` restrict Bruno Haible
2020-02-17  0:14         ` restrict Bruno Haible
2020-02-17  2:46           ` restrict Paul Eggert
2020-02-17  3:53             ` restrict Bruno Haible
2020-02-17  9:51               ` restrict Tim Rühsen
2020-02-17 21:03                 ` restrict Bruno Haible
2020-02-17 18:03         ` restrict Paul Eggert
2020-02-17 20:55           ` restrict Bruno Haible
2020-02-17 22:28             ` restrict Paul Eggert
2020-02-17 21:19     ` restrict - summary Bruno Haible
2020-02-22 22:51       ` Bruno Haible
2020-02-24 19:17         ` Eric Blake
2020-02-23 12:39       ` Bruno Haible
2020-02-23 13:30       ` Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).