[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
clang's __diagnose_if__ and glibc fortify
From: |
Bruno Haible |
Subject: |
clang's __diagnose_if__ and glibc fortify |
Date: |
Sun, 23 Aug 2020 15:46:50 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-186-generic; KDE/5.18.0; x86_64; ; ) |
Paul Eggert wrote:
>+ libc-config: avoid Clang’s __diagnose_if__
>+ * lib/cdefs.h (__warndecl, __warnattr, __errordecl):
>+ For now, do not use __diagnose_if__ here, as this fails
>+ on Fedora 31 with Clang 9.0.1, with diagnostic
>+ "/usr/include/bits/stdio2.h:263:9: error: fgets called with bigger
>+ size than length of destination buffer
>+ [-Werror,-Wuser-defined-warnings]". I guess Clang 9 warns even
>+ for functions that are not called?
I can reproduce the redundant warnings, on Fedora 31 with Clang 9.0.1, when
applying the change to gnulib/lib/cdefs.h also to /usr/include/sys/cdefs.h.
With the attached program foo.c I get warnings for each of these inline
functions that conditionally invokes a *_chk_warn function.
Apparently, clang - unlike GCC - processes the body of the inline function
also when the inline function is never referenced.
It would be possible to silence these warnings by adding a gnulib module
as attached (clang-warnings.tar.gz).
BUT since the macros __warndecl and __warnattr are ONLY used by Fortify
inline functions - there are no other uses in the glibc headers, nor in gnulib -
and most of these uses produce redundant warnings, this is all pointless.
What matters for user code is that gnulib's "attribute.h" defines
ATTRIBUTE_WARNING and ATTRIBUTE_ERROR in a way that works with clang.
In order to use the clang __diagnose_if__ primitive, the Fortify inline
functions would need to be written in a different way. This has been done
in the Android header files. For example, here is the fgets function in
glibc - tailored for GCC -:
extern char *__REDIRECT (__fgets_chk_warn,
(char *__restrict __s, size_t __size, int __n,
FILE *__restrict __stream), __fgets_chk)
__wur __warnattr ("fgets called with bigger size than length "
"of destination buffer");
__fortify_function __wur char *
fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
{
if (__bos (__s) != (size_t) -1)
{
if (!__builtin_constant_p (__n) || __n <= 0)
return __fgets_chk (__s, __bos (__s), __n, __stream);
if ((size_t) __n > __bos (__s))
return __fgets_chk_warn (__s, __bos (__s), __n, __stream); // <===
line 263
}
return __fgets_alias (__s, __n, __stream);
}
and here it is in Android - tailored for clang -:
__BIONIC_FORTIFY_INLINE
char* fgets(char* const __pass_object_size dest, int size, FILE* stream)
__overloadable
__clang_error_if(size < 0, "in call to 'fgets', size should not be
negative")
__clang_error_if(size > __bos(dest),
"in call to 'fgets', size is larger than the
destination buffer") {
size_t bos = __bos(dest);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __call_bypassing_fortify(fgets)(dest, size, stream);
}
return __fgets_chk(dest, size, stream, bos);
}
2020-08-23 Bruno Haible <bruno@clisp.org>
libc-config: Improve comments.
* lib/cdefs.h (__warndecl, __warnattr, __errordecl): Explain why we
cannot use clang's __diagnose_if__ here.
diff --git a/lib/cdefs.h b/lib/cdefs.h
index 32a2c40..1ae9ffc 100644
--- a/lib/cdefs.h
+++ b/lib/cdefs.h
@@ -148,7 +148,11 @@
# define __warnattr(msg) __attribute__((__warning__ (msg)))
# define __errordecl(name, msg) \
extern void name (void) __attribute__((__error__ (msg)))
-#elif __glibc_clang_has_attribute (__diagnose_if__) && 0 /* fails on Fedora 31
with Clang 9. */
+#elif __glibc_clang_has_attribute (__diagnose_if__) && 0
+/* These definitions are not enabled, because they produce bogus warnings
+ in the glibc Fortify functions. These functions are written in a style
+ that works with GCC. In order to work with clang, these functions would
+ need to be modified. */
# define __warndecl(name, msg) \
extern void name (void) __attribute__((__diagnose_if__ (1, msg, "warning")))
# define __warnattr(msg) __attribute__((__diagnose_if__ (1, msg, "warning")))
foo.c
Description: Text Data
foo-warnings.txt
Description: Text document
clang-warnings.tar.gz
Description: application/compressed-tar
clang's __diagnose_if__ and glibc fortify,
Bruno Haible <=