improve clang support (21)
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
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
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)
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
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)
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