improve clang support (21)

2020-08-10 Thread Bruno Haible
clang supports the various function attributes from GCC 4.2.x, plus
also attribute __artificial__ (in clang >= 7).

With this patch, the attributes are enabled also on Windows, where clang
does not define __GNUC__.

The patch uses __has_attribute in lib/cdefs.h, so that the code will
refrain from using __attribute__ in very old versions of clang. This should
ease the sync with glibc.

In the rest of the gnulib code, I used a simpler approach: I just used
'defined __clang__', because that is simpler, and the attribute support
exists in clang for a very long time (for example, __attribute__ __format__
__strfmon__ exists since at least 2008). If that produces problems, it
will be easy to correct.


2020-08-10  Bruno Haible  

Use many __attribute__s with clang.
* m4/gnulib-common.m4 (_Noreturn): Use __attribute__ __noreturn__ also
on clang.
* lib/cdefs.h (__glibc_clang_has_attribute, __glibc_clang_has_builtin):
New macros.
(__THROW, __THROWNL, __NTH, __NTHNL): Use __attribute__ __nothrow__ also
on clang.
(__warndecl, __warnattr, __errordecl): Use __attribute__ __diagnose_if__
also on older clang versions.
(__attribute__): Don't define to empty on clang.
(__attribute_malloc__): Use __attribute__ __malloc__ also on clang.
(__attribute_pure__): Use __attribute__ __pure__ also on clang.
(__attribute_const__): Use __attribute__ __const__ also on clang.
(__attribute_used__): Use __attribute__ __used__ also on clang.
(__attribute_noinline__): Use __attribute__ __noinline__ also on clang.
(__attribute_deprecated__): Use __attribute__ __deprecated__ also on
clang.
(__attribute_format_arg__): Use __attribute__ __format_arg__ also on
clang.
(__attribute_format_strfmon__): Use __attribute__ __format__ __strfmon__
also on clang.
(__nonnull): Use __attribute__ __nonnull__ also on clang.
(__attribute_warn_unused_result__): Use __attribute__
__warn_unused_result__ also on clang.
(__always_inline): Use __attribute__ __always_inline__ also on clang.
(__attribute_artificial__): Use __attribute__ __artificial__ also on
clang >= 7.
(__glibc_unlikely, __glibc_likely): Use __builtin_expect also on older
clang versions.
(_Noreturn): Don't redefine on clang >= 3.5.
* lib/arg-nonnull.h (_GL_ARG_NONNULL): Use __attribute__ __nonnull__
also on clang.
* lib/dirent.in.h (_GL_ATTRIBUTE_PURE): Use __attribute__ __pure__ also
on clang.
* lib/stdlib.in.h (_GL_ATTRIBUTE_PURE): Likewise.
* lib/string.in.h (_GL_ATTRIBUTE_PURE): Likewise.
* lib/wchar.in.h (_GL_ATTRIBUTE_PURE): Likewise.
* lib/stdio.in.h (_GL_ATTRIBUTE_FORMAT): Use __attribute__ __format__
also on clang.
* lib/monetary.in.h (_GL_ATTRIBUTE_FORMAT): Likewise.
* lib/textstyle.in.h (ostream_printf, ostream_vprintf): Likewise.
* lib/unitypes.in.h (_UC_ATTRIBUTE_CONST): Use __attribute__ __const__
also on clang.
(_UC_ATTRIBUTE_PURE): Use __attribute__ __pure__ also on clang.
* lib/noreturn.h (_GL_NORETURN_FUNC, _GL_NORETURN_FUNCPTR): Use
__attribute__ __noreturn__ also on clang.
* lib/obstack.h (__attribute_noreturn__): Likewise.
* lib/file-set.h (record_file): Use __attribute__ __nonnull__ also on
clang.
* lib/argp-help.c (hol_entry_long_iterate): Use __attribute__
always_inline also on clang.
* tests/test-printf-posix.c (func1, func2, func3, func4): Test also on
clang.

diff --git a/lib/arg-nonnull.h b/lib/arg-nonnull.h
index d4d195a..42d7e70 100644
--- a/lib/arg-nonnull.h
+++ b/lib/arg-nonnull.h
@@ -18,7 +18,7 @@
that the values passed as arguments n, ..., m must be non-NULL pointers.
n = 1 stands for the first argument, n = 2 for the second argument etc.  */
 #ifndef _GL_ARG_NONNULL
-# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
+# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || defined 
__clang__
 #  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
 # else
 #  define _GL_ARG_NONNULL(params)
diff --git a/lib/argp-help.c b/lib/argp-help.c
index 02faa60..9c95c16 100644
--- a/lib/argp-help.c
+++ b/lib/argp-help.c
@@ -570,7 +570,7 @@ hol_entry_short_iterate (const struct hol_entry *entry,
 }
 
 static inline int
-#if __GNUC__ >= 3
+#if (__GNUC__ >= 3) || (__clang_major__ >= 4)
 __attribute__ ((always_inline))
 #endif
 hol_entry_long_iterate (const struct hol_entry *entry,
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 801753c..170d9e6 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -34,7 +34,34 @@
 #undef __P
 #undef __PMT
 
-#ifdef __GNUC__
+/* Compilers that are not clang may object to
+   #if defined __clang__ && __has_attribute(...)
+   even though they do not need to evaluate the right-hand side of the &&.  */

Re: c-ldtoastr test failure

2020-08-10 Thread Bruno Haible
Hi Marc,

> thanks for catching that. The proposed change is perfect.

OK, pushed it.

> Actually, I
> had made that fix in my local code as well so I am wondering why it
> didn't make itself into the patch I sent you.

What I committed in your name on 2020-06-25 was what you had sent to the
list on 2020-05-20.

If you do "git status" regularly, you will notice pending patches of yours.

Bruno




Re: c-ldtoastr test failure

2020-08-10 Thread Marc Nieper-Wißkirchen
Hi Bruno,

thanks for catching that. The proposed change is perfect. Actually, I
had made that fix in my local code as well so I am wondering why it
didn't make itself into the patch I sent you.

Best,

Marc

Am Mo., 10. Aug. 2020 um 08:55 Uhr schrieb Bruno Haible :
>
> Hi Marc,
>
> On a Linux/x86_64 system, the c-ldtoastr uni test fails.
>
> How to reproduce:
> $ ./gnulib-tool --test --single-configure c-ldtoastr
>
> The test fails like this:
> ../../gltests/test-c-ldtoastr.c:54: assertion '!strcmp (buf, "0.1")' failed
>
> In the debugger, I see that where the code expects a result "0.1",
> the actual result is "0.1555".
>
> This rounding error is not caused by the library code for binary to decimal
> conversion, because you can see that the number in its full glory in the
> debugger:
>
> (gdb) step
> c_ldtoastr (buf=buf@entry=0x7fffd670 "1,", bufsize=bufsize@entry=40, 
> flags=flags@entry=0, width=width@entry=0,
> x=0.155511151231257827) at ../../gllib/ftoastr.c:113
>
>
> Here's a suggested fix. OK to push?
>
>
> 2020-08-09  Bruno Haible  
>
> c-ldtoastr tests: Fix test failure.
> * tests/test-c-ldtoastr.c (main): Support platforms where 'long 
> double'
> is longer than 'double'.
>
> diff --git a/tests/test-c-ldtoastr.c b/tests/test-c-ldtoastr.c
> index 140f0c6..7e38422 100644
> --- a/tests/test-c-ldtoastr.c
> +++ b/tests/test-c-ldtoastr.c
> @@ -50,7 +50,7 @@ main (int argc, char *argv[])
>{
>  char buf[DBL_BUFSIZE_BOUND];
>
> -c_ldtoastr (buf, sizeof buf, 0, 0, 0.1);
> +c_ldtoastr (buf, sizeof buf, 0, 0, 0.1L);
>  ASSERT (!strcmp (buf, "0.1"));
>}
>
>



Re: improve clang support (20)

2020-08-10 Thread Gisle Vanem

Bruno Haible wrote:


When building a testdir of all of gnulib with clang 9 on a glibc system,
I see these compilation errors:


Good work on the clang support, but it looks like you have not
tried clang-cl with the Microsoft 'Windows-Kit' headers.

Microsoft added support for 'clang/clang-cl' in it's headers
some time ago. For most of the 'tests/test-std*.c' programs to
work, one has to add '-D_CRT_USE_BUILTIN_OFFSETOF' to the CFLAGS.
I fail to see where/how the 'm4' macros does that.

If not using '-D_CRT_USE_BUILTIN_OFFSETOF', there are all kinds
of errors occurs. Like:

test-stddef.c(47,9): error: static_assert expression is not an integral 
constant expression
verify (offsetof (struct d, f) == 1);
^~~~
f:/ProgramFiler-x86/WindowsKits/include/10.0.19041.0/ucrt/stddef.h(49,31):
note: expanded from macro 'offsetof'
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
  ^
../lib\verify.h(283,32): note: expanded from macro 'verify'
# define verify(R) _GL_VERIFY (R, "verify (" #R ")", -)
   ^~~~
../lib\verify.h(216,57): note: expanded from macro '_GL_VERIFY'
# define _GL_VERIFY(R, DIAGNOSTIC, ...) _Static_assert (R, DIAGNOSTIC)
^
test-stddef.c(47,9): note: cast that performs the conversions of a
reinterpret_cast is not allowed in a constant expression
f:/ProgramFiler-x86/WindowsKits/include/10.0.19041.0/ucrt/stddef.h(49,32):
note: expanded from macro 'offsetof'
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
   ^

-

But (unrelated to the above) I still get this error:

test-stdbool.c(67,8): error: 'd' declared as an array with a negative size
char d[(bool) 0.5 == true ? 1 : -1];
   ^~~
test-stdbool.c(73,6): warning: incompatible pointer to integer conversion
initializing 'signed char' with an expression of type 'struct s *' 
[-Wint-conversion]
bool e = 
 ^   ~~
test-stdbool.c(73,10): error: initializer element is not a compile-time constant
bool e = 
 ^~

'test-stdbool.c' compiles fine with MSVC-2019 (?!)

--
--gv




c-ldtoastr test failure

2020-08-10 Thread Bruno Haible
Hi Marc,

On a Linux/x86_64 system, the c-ldtoastr uni test fails.

How to reproduce:
$ ./gnulib-tool --test --single-configure c-ldtoastr

The test fails like this:
../../gltests/test-c-ldtoastr.c:54: assertion '!strcmp (buf, "0.1")' failed

In the debugger, I see that where the code expects a result "0.1",
the actual result is "0.1555".

This rounding error is not caused by the library code for binary to decimal
conversion, because you can see that the number in its full glory in the
debugger:

(gdb) step
c_ldtoastr (buf=buf@entry=0x7fffd670 "1,", bufsize=bufsize@entry=40, 
flags=flags@entry=0, width=width@entry=0, 
x=0.155511151231257827) at ../../gllib/ftoastr.c:113


Here's a suggested fix. OK to push?


2020-08-09  Bruno Haible  

c-ldtoastr tests: Fix test failure.
* tests/test-c-ldtoastr.c (main): Support platforms where 'long double'
is longer than 'double'.

diff --git a/tests/test-c-ldtoastr.c b/tests/test-c-ldtoastr.c
index 140f0c6..7e38422 100644
--- a/tests/test-c-ldtoastr.c
+++ b/tests/test-c-ldtoastr.c
@@ -50,7 +50,7 @@ main (int argc, char *argv[])
   {
 char buf[DBL_BUFSIZE_BOUND];
 
-c_ldtoastr (buf, sizeof buf, 0, 0, 0.1);
+c_ldtoastr (buf, sizeof buf, 0, 0, 0.1L);
 ASSERT (!strcmp (buf, "0.1"));
   }
 




improve clang support (20)

2020-08-10 Thread Bruno Haible
When building a testdir of all of gnulib with clang 9 on a glibc system,
I see these compilation errors:

In file included from ../../gltests/test-list-c++.cc:23:
../gllib/string.h:821:22: error: functions that differ only in their return 
type cannot be overloaded
_GL_WARN_ON_USE_CXX (strchr, const char *, (const char *, int),
 ^ ~~
../gllib/string.h:544:16: note: expanded from macro '_GL_WARN_ON_USE_CXX'
extern rettype function parameters_and_attributes \
   ~~~ ^
/usr/include/string.h:231:14: note: previous declaration is here
extern char *strchr (const char *__s, int __c)
   ~~^
In file included from ../../gltests/test-list-c++.cc:23:
../gllib/string.h:1016:22: error: functions that differ only in their return 
type cannot be overloaded
_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *),
 ^  ~~
../gllib/string.h:544:16: note: expanded from macro '_GL_WARN_ON_USE_CXX'
extern rettype function parameters_and_attributes \
   ~~~ ^
/usr/include/string.h:310:14: note: previous declaration is here
extern char *strpbrk (const char *__s, const char *__accept)
   ~~^
In file included from ../../gltests/test-list-c++.cc:23:
../gllib/string.h:1045:22: error: functions that differ only in their return 
type cannot be overloaded
_GL_WARN_ON_USE_CXX (strrchr, const char *, (const char *, int),
 ^  ~~
../gllib/string.h:544:16: note: expanded from macro '_GL_WARN_ON_USE_CXX'
extern rettype function parameters_and_attributes \
   ~~~ ^
/usr/include/string.h:258:14: note: previous declaration is here
extern char *strrchr (const char *__s, int __c)
   ~~^
3 errors generated.

So, where gcc wants a declaration of 'strchr', 'strpbrk', 'strrchr' with
return type 'const char *' (see [1]), clang wants to see a return type
'char *'.

[1] https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00099.html


2020-08-09  Bruno Haible  

string: Fix build error in C++ mode with clang (regression from today).
* lib/warn-on-use.h (_GL_WARN_ON_USE_CXX): Expect two rettype
parameters, one for GCC, one for clang.
* lib/c++defs.h (_GL_CXXALIASWARN1_2): Update.
* lib/string.in.h (strchr, strpbrk, strrchr): For clang, pass 'char *'
as return type.

diff --git a/lib/c++defs.h b/lib/c++defs.h
index 75d6250..cd56ea2 100644
--- a/lib/c++defs.h
+++ b/lib/c++defs.h
@@ -298,7 +298,7 @@
we enable the warning only when not optimizing.  */
 # if !(defined __GNUC__ && !defined __clang__ && __OPTIMIZE__)
 #  define 
_GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
-_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
+_GL_WARN_ON_USE_CXX (func, rettype, rettype, parameters_and_attributes, \
  "The symbol ::" #func " refers to the system 
function. " \
  "Use " #namespace "::" #func " instead.")
 # else
diff --git a/lib/string.in.h b/lib/string.in.h
index c18efa7..ef702e3 100644
--- a/lib/string.in.h
+++ b/lib/string.in.h
@@ -329,7 +329,8 @@ _GL_WARN_ON_USE (stpncpy, "stpncpy is unportable - "
GB18030 and the character to be searched is a digit.  */
 # undef strchr
 /* Assume strchr is always declared.  */
-_GL_WARN_ON_USE_CXX (strchr, const char *, (const char *, int),
+_GL_WARN_ON_USE_CXX (strchr,
+ const char *, char *, (const char *, int),
  "strchr cannot work correctly on character strings "
  "in some multibyte locales - "
  "use mbschr if you care about internationalization");
@@ -524,7 +525,8 @@ _GL_CXXALIASWARN (strpbrk);
locale encoding is GB18030 and one of the characters to be searched is a
digit.  */
 #  undef strpbrk
-_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *),
+_GL_WARN_ON_USE_CXX (strpbrk,
+ const char *, char *, (const char *, const char *),
  "strpbrk cannot work correctly on character strings "
  "in multibyte locales - "
  "use mbspbrk if you care about internationalization");
@@ -532,7 +534,8 @@ _GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, 
const char *),
 #elif defined GNULIB_POSIXCHECK
 # undef strpbrk
 # if HAVE_RAW_DECL_STRPBRK
-_GL_WARN_ON_USE_CXX (strpbrk, const char *, (const char *, const char *),
+_GL_WARN_ON_USE_CXX (strpbrk,
+ const char *, char *, (const char *, const char *),
  "strpbrk is unportable - "
  "use gnulib module strpbrk for portability");
 # endif
@@ -553,7 +556,8 @@ _GL_WARN_ON_USE (strspn, "strspn cannot work correctly on 
character strings "
GB18030 and the character to be searched is a digit.  */
 # undef strrchr
 /* Assume strrchr is always declared.  */
-_GL_WARN_ON_USE_CXX (strrchr, const char *, (const char