Re: restrict

2020-02-10 Thread Jeffrey Walton
On Sun, Feb 9, 2020 at 10:03 PM Bruno Haible  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



Re: restrict

2020-02-10 Thread Tim Rühsen
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 
> 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 questi

[PATCH 0/1] xnanosleep: Use pause for infinite duration.

2020-02-10 Thread Vladimir Panteleev
Users have discovered that the "sleep" command accepts "infinity" as
its duration argument. However, specifying the "infinity" duration
does not actually cause GNU sleep to sleep for an infinite
duration. This is because the duration was being unconditionally
converted to a timespec value, and infinities are not representable as
timespecs.

Address this by using the "pause" system call (instead of "nanosleep")
when the duration is a positive infinity. This allows us to avoid
burdening the operating system with a timer which likely will never be
reached.

---

Commentary: Yes, this patch isn't too serious. There is an interesting
discussion here [1] which compares a few ways to get a process to
simply block indefinitely. I thought it was a shame that the most
elegant-looking solution, "sleep infinity", turned out to be inferior
to the other, more complicated ones.

Possibly xnanosleep is not the best way to perform this change. The
downside is that it changes the behavior of xnanosleep - it is no
longer just a nanosleep wrapper. The upside is that this the place
where the lossy conversion occurs, so the alternative would mean that
all nanosleep callers would have to check the argument.

I'm not sure if isfinite is the best way to check for infinity, as far
as the tradeoff between portability and dependencies goes. An
alternative would be "static const double infinity = 1.0 / 0.0; if
(seconds == infinity)" but I don't know how good that is in terms of
portability. I noticed that e.g. vasnprintf.c defines a private
isfinite-like function.

By the way, shouldn't xnanosleep be using the second nanosleep
parameter to track how much time there's left to sleep in case of an
interruption?

 [1]: https://stackoverflow.com/a/41655546/21501

---

Vladimir Panteleev (1):
  xnanosleep: Use pause for infinite duration.

 lib/xnanosleep.c | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

-- 
2.25.0




[PATCH] xnanosleep: Use pause for infinite duration.

2020-02-10 Thread Vladimir Panteleev
* lib/xnanosleep.c (xnanosleep): When the duration is the positive
infinity, use pause instead of nanosleep.
---
 lib/xnanosleep.c | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/lib/xnanosleep.c b/lib/xnanosleep.c
index 5774f75f3..58a2f5254 100644
--- a/lib/xnanosleep.c
+++ b/lib/xnanosleep.c
@@ -25,7 +25,9 @@
 #include 
 
 #include 
+#include 
 #include 
+#include 
 
 /* Sleep until the time (call it WAKE_UP_TIME) specified as
SECONDS seconds after the time this function is called.
@@ -37,21 +39,33 @@
 int
 xnanosleep (double seconds)
 {
-  struct timespec ts_sleep = dtotimespec (seconds);
-
-  for (;;)
+  if (!isfinite(seconds) && seconds > 0)
+{
+  for (;;)
+{
+  pause();
+  if (errno != EINTR)
+return -1;
+}
+}
+  else
 {
-  /* Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno
- when resumed after being suspended.  Earlier versions would
- set errno to EINTR.  nanosleep from linux-2.6.10, as well as
- implementations by (all?) other vendors, doesn't return -1
- in that case;  either it continues sleeping (if time remains)
- or it returns zero (if the wake-up time has passed).  */
-  errno = 0;
-  if (nanosleep (&ts_sleep, NULL) == 0)
-break;
-  if (errno != EINTR && errno != 0)
-return -1;
+  struct timespec ts_sleep = dtotimespec (seconds);
+
+  for (;;)
+{
+  /* Linux-2.6.8.1's nanosleep returns -1, but doesn't set errno
+ when resumed after being suspended.  Earlier versions would
+ set errno to EINTR.  nanosleep from linux-2.6.10, as well as
+ implementations by (all?) other vendors, doesn't return -1
+ in that case;  either it continues sleeping (if time remains)
+ or it returns zero (if the wake-up time has passed).  */
+  errno = 0;
+  if (nanosleep (&ts_sleep, NULL) == 0)
+break;
+  if (errno != EINTR && errno != 0)
+return -1;
+}
 }
 
   return 0;
-- 
2.25.0




[PATCH] m4: fix --disable-rpath for AIX

2020-02-10 Thread CHIGOT, CLEMENT
Currently, --disable-rpath will add directly $found_so to the compilation
line. However, on AIX, this will result on the path being hardcoded in
the built binaries.
The only way to avoid hardcoded paths without using linker flags (like
-Wl,-bnoipath) is to add -l$name.
---
 m4/lib-link.m4 | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/m4/lib-link.m4 b/m4/lib-link.m4
index 0ff10731f..01bcfd5ee 100644
--- a/m4/lib-link.m4
+++ b/m4/lib-link.m4
@@ -377,7 +377,12 @@ AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
  || test "X$found_dir" = "X/usr/$acl_libdirstem" \
  || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
 dnl No hardcoding is needed.
-LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+case $host_os in
+  dnl Using directly $found_so on AIX will result into
+  dnl hardcoded libraries' path inside binaries.
+  aix*) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir 
-l$name" ;;
+  *) LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" ;;
+esac
   else
 dnl Use an explicit option to hardcode DIR into the resulting
 dnl binary.
-- 
2.17.1





Re: [PATCH] test-canonicalize: avoid a build failure

2020-02-10 Thread Bruno Haible
> * tests/test-canonicalize.c: Protect the inclusion of null-ptr.h
> with the same guard as that used to protect usage of the null_ptr
> function

The same thing is needed in test-ptsname_r.c:


2020-02-10  Bruno Haible  

ptsname_r-tests: Avoid unused function warning.
* tests/test-ptsname_r.c: Don't include null-ptr.h if we don't need it.

diff --git a/tests/test-ptsname_r.c b/tests/test-ptsname_r.c
index 24be52f..381e3da 100644
--- a/tests/test-ptsname_r.c
+++ b/tests/test-ptsname_r.c
@@ -36,7 +36,10 @@ SIGNATURE_CHECK (ptsname_r, int, (int, char *, size_t));
 
 #include "same-inode.h"
 
-#include "null-ptr.h"
+#if GNULIB_defined_ptsname_r
+# include "null-ptr.h"
+#endif
+
 #include "macros.h"
 
 /* Compare two slave names.




pthread-mutex-tests, pthread-rwlock-tests: Fix link errors on HP-UX

2020-02-10 Thread Bruno Haible
On HP-UX 11.31 / ia64, I'm seeing these link errors:

cc +DD64 -AC99 -D_HPUX_SOURCE -D_XOPEN_SOURCE=600  -g  
-L/home/haible/prefix-hpux113ia64-64-cc/lib -o test-pthread-mutex 
test-pthread-mutex.o libtests.a ../gllib/libgnu.a libtests.a  -lpthread
ld: Unsatisfied symbol "sem_trywait" in file test-pthread-mutex.o
ld: Unsatisfied symbol "sem_init" in file test-pthread-mutex.o
ld: Unsatisfied symbol "sem_post" in file test-pthread-mutex.o
3 errors.
gmake[4]: *** [test-pthread-mutex] Error 1

cc +DD64 -AC99 -D_HPUX_SOURCE -D_XOPEN_SOURCE=600  -g  
-L/home/haible/prefix-hpux113ia64-64-cc/lib -o test-pthread-rwlock 
test-pthread-rwlock.o libtests.a ../gllib/libgnu.a libtests.a  -lpthread
ld: Unsatisfied symbol "sem_trywait" in file test-pthread-rwlock.o
ld: Unsatisfied symbol "sem_init" in file test-pthread-rwlock.o
ld: Unsatisfied symbol "sem_post" in file test-pthread-rwlock.o
3 errors.
gmake[4]: *** [test-pthread-rwlock] Error 1

This patch fixes them.


2020-02-10  Bruno Haible  

pthread-mutex-tests, pthread-rwlock-tests: Fix link errors on HP-UX.
* modules/pthread-mutex-tests (Makefile.am): Link test-pthread-mutex
with $(LIB_SEMAPHORE).
* modules/pthread-rwlock-tests (Makefile.am): Link test-pthread-rwlock
with $(LIB_SEMAPHORE).

diff --git a/modules/pthread-mutex-tests b/modules/pthread-mutex-tests
index eb6ec7b..12d386e 100644
--- a/modules/pthread-mutex-tests
+++ b/modules/pthread-mutex-tests
@@ -11,4 +11,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-pthread-mutex
 check_PROGRAMS += test-pthread-mutex
-test_pthread_mutex_LDADD = $(LDADD) @LIBPMULTITHREAD@ @LIB_SCHED_YIELD@
+test_pthread_mutex_LDADD = $(LDADD) @LIBPMULTITHREAD@ @LIB_SCHED_YIELD@ 
@LIB_SEMAPHORE@
diff --git a/modules/pthread-rwlock-tests b/modules/pthread-rwlock-tests
index 7f35198..340ebf0 100644
--- a/modules/pthread-rwlock-tests
+++ b/modules/pthread-rwlock-tests
@@ -12,4 +12,4 @@ configure.ac:
 Makefile.am:
 TESTS += test-pthread-rwlock
 check_PROGRAMS += test-pthread-rwlock
-test_pthread_rwlock_LDADD = $(LDADD) @LIBPMULTITHREAD@ @LIB_SCHED_YIELD@
+test_pthread_rwlock_LDADD = $(LDADD) @LIBPMULTITHREAD@ @LIB_SCHED_YIELD@ 
@LIB_SEMAPHORE@




copysignf: fix link error on HP-UX with cc

2020-02-10 Thread Bruno Haible
On HP-UX 11.31/ia64 with cc, I'm seeing this link error:

cc +DD64 -AC99 -D_HPUX_SOURCE -D_XOPEN_SOURCE=600  -g  
-L/home/haible/prefix-hpux113ia64-64-cc/lib -o test-copysignf test-copysignf.o 
libtests.a ../gllib/libgnu.a libtests.a
ld: Unsatisfied symbol "_copysignf" in file test-copysignf.o
1 error.
gmake[4]: *** [test-copysignf] Error 1

This patch fixes it.


2020-02-10  Bruno Haible  

copysignf: Fix link error on HP-UX with cc.
* m4/copysignf.m4 (gl_FUNC_COPYSIGNF): Require AC_CANONICAL_HOST. On
HP-UX, set COPYSIGNF_LIBM to -lm.

diff --git a/m4/copysignf.m4 b/m4/copysignf.m4
index c6dea3e..284eb74 100644
--- a/m4/copysignf.m4
+++ b/m4/copysignf.m4
@@ -1,4 +1,4 @@
-# copysignf.m4 serial 3
+# copysignf.m4 serial 4
 dnl Copyright (C) 2011-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,
@@ -7,6 +7,7 @@ dnl with or without modifications, as long as this notice is 
preserved.
 AC_DEFUN([gl_FUNC_COPYSIGNF],
 [
   AC_REQUIRE([gl_MATH_H_DEFAULTS])
+  AC_REQUIRE([AC_CANONICAL_HOST])
 
   dnl Persuade glibc  to declare copysignf().
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
@@ -28,7 +29,12 @@ AC_DEFUN([gl_FUNC_COPYSIGNF],
   else
 HAVE_COPYSIGNF=0
 HAVE_DECL_COPYSIGNF=0
-COPYSIGNF_LIBM=
+dnl On HP-UX 11.31/ia64, cc has a built-in for copysignf that redirects
+dnl to the symbol '_copysignf', defined in libm, not libc.
+case "$host_os" in
+  hpux*) COPYSIGNF_LIBM='-lm' ;;
+  *) COPYSIGNF_LIBM= ;;
+esac
   fi
   AC_SUBST([COPYSIGNF_LIBM])
 ])