[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Gnulib's alloca.h used even when there is a system header
From: |
Eli Zaretskii |
Subject: |
Re: Gnulib's alloca.h used even when there is a system header |
Date: |
Tue, 19 Feb 2019 19:18:15 +0200 |
> From: Bruno Haible <address@hidden>
> Cc: Eli Zaretskii <address@hidden>, Paul Eggert <address@hidden>
> Date: Tue, 19 Feb 2019 00:32:24 +0100
>
> Hi Eli,
>
> > ./alloca.h:40:18: error: inlining failed in call to always_inline
> > '__builtin_alloca': function not considered for inlining
> > # define alloca __builtin_alloca
> > ^
>
> GCC never inlines a function that calls alloca() or __builtin_alloca().
> The reason is that if you call this function in a loop, then without
> inlining it will consume a bounded amount of stack whereas with inlining
> it might cause a stack overflow.
>
> The mingw people have declared their new alloca() function as "always
> inline", and GCC is decent enough to point us to the dilemma that it
> cannot resolve.
The GCC diagnostics is somewhat cryptic, so it's hard for me to be
sure what it means. My original interpretation was that due to
Gnulib's #define, what GCC sees is this:
extern inline __attribute__((__always_inline__))
void *__builtin_alloca( size_t __n ){ return __builtin_alloca( __n ); }
which AFAIU cannot possibly compile.
As for not ever inlining, please see a toy function I compiled and its
disassembly at the end of this message. Does this confirm what you
say above? I'm not sure.
> The upshot is: you can't define an alloca() function this way.
> Either define it as a macro - which is what the gnulib override does,
> if it gets activated -, or define it as a function in assembly-language.
>
> Since you say that this is a fresh bug from mingw, it's probably best
> that it gets reported to the mingw people. Then we don't need a Gnulib
> workaround.
CC'ing Keith, who maintains the MinGW runtime.
Regardless of whether there is or isn't a bug in MinGW, I urge you to
reconsider whether unconditionally overriding a system header in such
a way is a good idea, at least for platforms that use GCC. I think
this is a fragile arrangement, even if it seems to work.
Here's the toy source code I used:
#include <alloca.h>
#include <string.h>
char *
make_string (int c, size_t n)
{
char *local_string = alloca (n + 1);
int i;
for (i = 0; i < n; i++)
local_string[i] = c;
local_string[n] = '\0';
return strdup (local_string);
}
And here's the disassembly of the object file generated by MinGW GCC:
al.o: file format pe-i386
Disassembly of section .text:
00000000 <_make_string>:
#include <alloca.h>
#include <string.h>
char *
make_string (int c, size_t n)
{
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 28 sub $0x28,%esp
char *local_string = alloca (n + 1);
6: 8b 45 0c mov 0xc(%ebp),%eax
9: 83 c0 01 add $0x1,%eax
c: 89 45 ec mov %eax,-0x14(%ebp)
#if defined _GNU_SOURCE || ! defined _NO_OLDNAMES
/* This is the GNU standard API; it is also compatible with Microsoft's
* original, but now deprecated, naming convention.
*/
__CRT_ALIAS void *alloca( size_t __n ){ return __builtin_alloca( __n ); }
f: 8b 45 ec mov -0x14(%ebp),%eax
12: 8d 50 0f lea 0xf(%eax),%edx
15: b8 10 00 00 00 mov $0x10,%eax
1a: 83 e8 01 sub $0x1,%eax
1d: 01 d0 add %edx,%eax
1f: b9 10 00 00 00 mov $0x10,%ecx
24: ba 00 00 00 00 mov $0x0,%edx
29: f7 f1 div %ecx
2b: 6b c0 10 imul $0x10,%eax,%eax
2e: e8 00 00 00 00 call 33 <_make_string+0x33>
33: 29 c4 sub %eax,%esp
35: 8d 44 24 04 lea 0x4(%esp),%eax
39: 83 c0 0f add $0xf,%eax
3c: c1 e8 04 shr $0x4,%eax
3f: c1 e0 04 shl $0x4,%eax
42: 89 45 f0 mov %eax,-0x10(%ebp)
int i;
for (i = 0; i < n; i++)
45: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp)
4c: eb 11 jmp 5f <_make_string+0x5f>
local_string[i] = c;
4e: 8b 55 f4 mov -0xc(%ebp),%edx
51: 8b 45 f0 mov -0x10(%ebp),%eax
54: 01 d0 add %edx,%eax
56: 8b 55 08 mov 0x8(%ebp),%edx
59: 88 10 mov %dl,(%eax)
make_string (int c, size_t n)
{
char *local_string = alloca (n + 1);
int i;
for (i = 0; i < n; i++)
5b: 83 45 f4 01 addl $0x1,-0xc(%ebp)
5f: 8b 45 f4 mov -0xc(%ebp),%eax
62: 39 45 0c cmp %eax,0xc(%ebp)
65: 77 e7 ja 4e <_make_string+0x4e>
local_string[i] = c;
local_string[n] = '\0';
67: 8b 55 f0 mov -0x10(%ebp),%edx
6a: 8b 45 0c mov 0xc(%ebp),%eax
6d: 01 d0 add %edx,%eax
6f: c6 00 00 movb $0x0,(%eax)
return strdup (local_string);
72: 8b 45 f0 mov -0x10(%ebp),%eax
75: 89 04 24 mov %eax,(%esp)
78: e8 00 00 00 00 call 7d <_make_string+0x7d>
}
7d: c9 leave
7e: c3 ret
7f: 90 nop
- Gnulib's alloca.h used even when there is a system header, Eli Zaretskii, 2019/02/17
- Re: Gnulib's alloca.h used even when there is a system header, Paul Eggert, 2019/02/17
- Re: Gnulib's alloca.h used even when there is a system header, Eli Zaretskii, 2019/02/17
- Re: Gnulib's alloca.h used even when there is a system header, Paul Eggert, 2019/02/17
- Re: Gnulib's alloca.h used even when there is a system header, Bruno Haible, 2019/02/17
- Re: Gnulib's alloca.h used even when there is a system header, Eli Zaretskii, 2019/02/18
- Re: Gnulib's alloca.h used even when there is a system header, Bruno Haible, 2019/02/18
- Re: Gnulib's alloca.h used even when there is a system header,
Eli Zaretskii <=
- Re: Gnulib's alloca.h used even when there is a system header, Eli Zaretskii, 2019/02/28
Re: Gnulib's alloca.h used even when there is a system header, Bruno Haible, 2019/02/17