diff mbox series

stdio: Move include of bits/stdio-ldbl.h before bits/stdio.h

Message ID 20210322111530.3215018-1-glaubitz@physik.fu-berlin.de
State Changes Requested
Delegated to: Adhemerval Zanella Netto
Headers show
Series stdio: Move include of bits/stdio-ldbl.h before bits/stdio.h | expand

Commit Message

John Paul Adrian Glaubitz March 22, 2021, 11:15 a.m. UTC
On targets where long double math is optional and the architecture
does not support support long double, glibc defines a number of
redirection macros which alias "foo" with "__nldbl_foo" while
applying an __asm__ label.

As a result, the __asm__ label gets applied after vfprintf() has
already been used which is not allowed. Moving bits/stdio-ldbl.h
bits/stdio.h in libio/stdio.h avoids this problem.

Fixes bug 27558.
---
 libio/stdio.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Adhemerval Zanella March 23, 2021, 5:59 p.m. UTC | #1
On 22/03/2021 08:15, John Paul Adrian Glaubitz wrote:
> On targets where long double math is optional and the architecture
> does not support support long double, glibc defines a number of
> redirection macros which alias "foo" with "__nldbl_foo" while
> applying an __asm__ label.
> 
> As a result, the __asm__ label gets applied after vfprintf() has
> already been used which is not allowed. Moving bits/stdio-ldbl.h
> bits/stdio.h in libio/stdio.h avoids this problem.
> 
> Fixes bug 27558.
> ---
>   libio/stdio.h | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/libio/stdio.h b/libio/stdio.h
> index 144137cf67..ae5337e855 100644
> --- a/libio/stdio.h
> +++ b/libio/stdio.h
> @@ -857,6 +857,11 @@ extern void funlockfile (FILE *__stream) __THROW;
>   extern int __uflow (FILE *);
>   extern int __overflow (FILE *, int);
>   
> +#include <bits/floatn.h>
> +#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
> +# include <bits/stdio-ldbl.h>
> +#endif
> +
>   /* If we are compiling with optimizing read this file.  It contains
>      several optimizing inline functions and macros.  */
>   #ifdef __USE_EXTERN_INLINES
> @@ -866,11 +871,6 @@ extern int __overflow (FILE *, int);
>   # include <bits/stdio2.h>
>   #endif
>   
> -#include <bits/floatn.h>
> -#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
> -# include <bits/stdio-ldbl.h>
> -#endif
> -
>   __END_DECLS
>   
>   #endif /* <stdio.h> included.  */
> 

I am not sure if this is the correct approach, I am seeing it building 
for powerpc64le with gcc version 10.2.1 20210126:

| powerpc64le-glibc-linux-gnu-gcc nscd.c -c [...]
| In file included from ../include/sys/cdefs.h:3,
|                  from ../include/features.h:484,
|                  from ../sysdeps/powerpc/bits/floatn.h:22,
|                  from ../include/stdio.h:7,
|                  from ../argp/argp.h:23,
|                  from ../include/argp.h:2,
|                  from nscd.c:20:
| ../misc/sys/cdefs.h:503:20: error: ‘__dprintf_chk’ undeclared here 
(not in a function); did you mean ‘__sprintf_chk’?
|   503 |   extern __typeof (__##name) __##name \
       |                    ^~
| ../libio/bits/stdio-ldbl.h:98:1: note: in expansion of macro 
‘__LDBL_REDIR2_DECL’
|    98 | __LDBL_REDIR2_DECL (dprintf_chk)
|       | ^~~~~~~~~~~~~~~~~~
| [...]

The postprocessor output shows:

| [...]
|  2820 extern __typeof (__dprintf_chk) __dprintf_chk __asm ("" "__" 
"dprintf_chk" "ieee128");
| [...]
|  3067 extern int __dprintf_chk (int __fd, int __flag, const char 
*__restrict __fmt,
| 3068      ...) __attribute__ ((__format__ (__printf__, 3, 4)));

Meaning we are not using __typeof *before* the function prototype
is define.

I think to proper handle this LLVM limitation we will need to fully
rework how __LDBL_REDIR2_DECL does the redirect by something similar
to what __REDIRECT does by defining something like:

| #if __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
| # ifdef __REDIRECT
|
| /* Alias name defined automatically.  */
| #  define __LDBL_REDIR(name, proto) \
|  extern name proto __asm__ (__ASMNAME ("__" #name "ieee128")); 

|
| /* Alias name defined automatically, with leading underscores.  */ 

| #  define __LDBL_REDIR2_DECL(name) \
|    extern __##name proto __asm__ (__ASMNAME ("__" #name "ieee128")); 
 

|
| /* Alias name defined manually.  */
| #  define __LDBL_REDIR1(name, proto, alias) \
|  extern name proto __asm__ (__ASMNAME (alias)); 


And replace __LDBL_REDIR_DECL with __LDBL_REDIR and __LDBL_REDIR1_DECL
with __LDBL_REDIR1 (while adding the require argument prototype).  It
will allow to move the stdio-ldbl.h definitions to stdio and remove the
header.
diff mbox series

Patch

diff --git a/libio/stdio.h b/libio/stdio.h
index 144137cf67..ae5337e855 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -857,6 +857,11 @@  extern void funlockfile (FILE *__stream) __THROW;
 extern int __uflow (FILE *);
 extern int __overflow (FILE *, int);
 
+#include <bits/floatn.h>
+#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
+# include <bits/stdio-ldbl.h>
+#endif
+
 /* If we are compiling with optimizing read this file.  It contains
    several optimizing inline functions and macros.  */
 #ifdef __USE_EXTERN_INLINES
@@ -866,11 +871,6 @@  extern int __overflow (FILE *, int);
 # include <bits/stdio2.h>
 #endif
 
-#include <bits/floatn.h>
-#if defined __LDBL_COMPAT || __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI == 1
-# include <bits/stdio-ldbl.h>
-#endif
-
 __END_DECLS
 
 #endif /* <stdio.h> included.  */