Re: [bug #60798] Make does not compile with GCC 11.1.0
On Fri, Dec 3, 2021 at 1:26 PM Edward Welbourne wrote: > > Jouke Witteveen (3 December 2021 13:22) wrote: > > The next warning I get (GCC11) is a _return-local-addr_ warning in > > src/read.c:2534 (find_percent_cached). Maybe GCC doesn't recognize alloca > > as a > > heap allocation? Just guessing; this warning was not obvious to me. > > alloca() is not a heap allocation: > > > DESCRIPTION >The alloca() function allocates size bytes of space in the stack frame >of the caller. This temporary space is automatically freed when the >function that called alloca() returns to its caller. > > > It is a stack allocation. So if make is returning an alloca()'d buffer, > then that is indeed a return of a local address. > Ah, thanks! I see what is happening now. GCC fails to see that in case allocations have happened, new is non-zero and the little block at the end of the function will make sure that the final string allocation will be copied to the string cache (and the returned address will hence not be local). I currently have no idea how to make this easier to understand for GCC.
Re: [bug #60798] Make does not compile with GCC 11.1.0
Jouke Witteveen (3 December 2021 13:22) wrote: > The next warning I get (GCC11) is a _return-local-addr_ warning in > src/read.c:2534 (find_percent_cached). Maybe GCC doesn't recognize alloca as a > heap allocation? Just guessing; this warning was not obvious to me. alloca() is not a heap allocation: DESCRIPTION The alloca() function allocates size bytes of space in the stack frame of the caller. This temporary space is automatically freed when the function that called alloca() returns to its caller. It is a stack allocation. So if make is returning an alloca()'d buffer, then that is indeed a return of a local address. Eddy.
Re: [bug #60798] Make does not compile with GCC 11.1.0
It gives the same error: src/main.c:1954:16: error: writes 1 byte in a region of size 0 [-Werror=stringop-overflow=] 1954 | *(p - 1) = '\0'; | ~^~ Le 21/06/2021 à 16:12, David A. Wheeler a écrit : p[-1] = '\0'; Is this just a style warning being turned into an error? That is, would this compile if the line was rewritten as: *(p - 1) = ‘\0’; Which means the same thing per the spec? If the rewrite would fix it, I suggest doing the rewrite, to reduce compilation problems. --- David A. Wheeler
Re: [bug #60798] Make does not compile with GCC 11.1.0
>> p[-1] = '\0'; Is this just a style warning being turned into an error? That is, would this compile if the line was rewritten as: *(p - 1) = ‘\0’; Which means the same thing per the spec? If the rewrite would fix it, I suggest doing the rewrite, to reduce compilation problems. --- David A. Wheeler
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Jun 19 2021, Paul Smith wrote: > But, as human programmers we can examine this code and understand that > actually, it's never possible for p to point to the first character of > the array: we know that eval_strings->idx is never 0, so we know that p > will always be incremented past the beginning of the memory buffer: > > p = value = alloca (len); > for (i = 0; i < eval_strings->idx; ++i) > { > ... > *(p++) = ' '; > } > p[-1] = '\0'; The crux is of course to tell the compiler that eval_strings->idx is always > 0, which is pretty hard for the compiler to deduce. Andreas. -- Andreas Schwab, SUSE Labs, sch...@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different."
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Sat, 2021-06-19 at 16:23 +0100, Dmitrii Pasechnik wrote: > > I don't think I understand. > > p[] occupies a continuous memory area, starting from p[0], but p[-1] > is not guaranteed by the standard to be accessible for you (well, > unless you control the memory layout by placing p in a struct, not as > the 1st member, but then why would you need p[-1] in the 1st place?) > > What's unclear about it? The problem is that your initial premise is not correct. p here is not an array, it's a pointer. If we had declared it like this: char p[10] then p[-1] would be problematic. But, we don't declare that. We declare it like this: char *p so p is a pointer. It points to some memory, and it can (and does) move both forward AND backward through that memory, via p+X and p-X. That's perfectly legitimate and not illegal or a hack in any way. I guess the compiler believes that it's possible that p might point to the very start of some legitimate memory, and if that were true then p[-1] (or, equivalently, *(p-1)) would be undefined behavior. But, as human programmers we can examine this code and understand that actually, it's never possible for p to point to the first character of the array: we know that eval_strings->idx is never 0, so we know that p will always be incremented past the beginning of the memory buffer: p = value = alloca (len); for (i = 0; i < eval_strings->idx; ++i) { ... *(p++) = ' '; } p[-1] = '\0';
Re: [bug #60798] Make does not compile with GCC 11.1.0
> Date: Sat, 19 Jun 2021 16:40:08 +0100 > From: Dmitrii Pasechnik > Cc: bo...@kolpackov.net, bug-make > > Compiler does not guarantee you that doing something with p[-1] > is not going to end in a segfault. It's hack, as it just happens to work, but > YMMV. > > E.g. clang 10, or Apple's clang 12, will print a warning: > > warning: array index -1 is before the beginning of the array [-Warray-bounds] > printf("%d", p[-1]); > ^ ~~ That warning is a bug in the compiler. p is not an array, it's a pointer into an array, and it doesn't have to (and in this case actually does not) point to the first element of that array.
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Sat, Jun 19, 2021 at 11:10:14AM -0400, Dmitry Goncharov wrote: > On Sat, Jun 19, 2021 at 10:31 AM Dmitrii Pasechnik > wrote: > > It's undefined behaviour in C to point to such a location, isn't it? > > Is this hack really needed? > > There is no hack. It is pointer arithmetic in c. p[-1] is the same as *(p-1). Compiler does not guarantee you that doing something with p[-1] is not going to end in a segfault. It's hack, as it just happens to work, but YMMV. E.g. clang 10, or Apple's clang 12, will print a warning: warning: array index -1 is before the beginning of the array [-Warray-bounds] printf("%d", p[-1]); ^ ~~
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Sat, Jun 19, 2021 at 10:52:41AM -0400, Paul Smith wrote: > On Sat, 2021-06-19 at 15:31 +0100, Dmitrii Pasechnik wrote: > > On Fri, Jun 18, 2021 at 12:53:32PM -0400, Paul D. Smith wrote: > > > > > Follow-up Comment #1, bug #60798 (project make): > > > FWIW, this warning is not valid in this situation. The code is > > > correct; p will always be pointing into a valid buffer and never > > > pointing at the first character in that buffer, so p[-1] always > > > points to valid memory. > > > > It's undefined behaviour in C to point to such a location, isn't it? > > To point to which such location? As I said, we know for a fact that p > does not point at the first character of the array. It's clearly legal > in C to walk backwards through an array!! And referencing the previous > element in an array is certainly not a hack. > > I don't think I understand. p[] occupies a continuous memory area, starting from p[0], but p[-1] is not guaranteed by the standard to be accessible for you (well, unless you control the memory layout by placing p in a struct, not as the 1st member, but then why would you need p[-1] in the 1st place?) What's unclear about it?
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Sat, Jun 19, 2021 at 10:31 AM Dmitrii Pasechnik wrote: > It's undefined behaviour in C to point to such a location, isn't it? > Is this hack really needed? There is no hack. It is pointer arithmetic in c. p[-1] is the same as *(p-1). regards, Dmitry
Re: [bug #60798] Make does not compile with GCC 11.1.0
> From: Paul Smith > Date: Sat, 19 Jun 2021 10:52:41 -0400 > Cc: bug-make@gnu.org > > On Sat, 2021-06-19 at 15:31 +0100, Dmitrii Pasechnik wrote: > > On Fri, Jun 18, 2021 at 12:53:32PM -0400, Paul D. Smith wrote: > > > > > Follow-up Comment #1, bug #60798 (project make): > > > FWIW, this warning is not valid in this situation. The code is > > > correct; p will always be pointing into a valid buffer and never > > > pointing at the first character in that buffer, so p[-1] always > > > points to valid memory. > > > > It's undefined behaviour in C to point to such a location, isn't it? > > To point to which such location? As I said, we know for a fact that p > does not point at the first character of the array. It's clearly legal > in C to walk backwards through an array!! And referencing the previous > element in an array is certainly not a hack. > > I don't think I understand. I think it's a bug in GCC 11 that needs to be reported to the GCC developers.
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Sat, 2021-06-19 at 15:31 +0100, Dmitrii Pasechnik wrote: > On Fri, Jun 18, 2021 at 12:53:32PM -0400, Paul D. Smith wrote: > > > Follow-up Comment #1, bug #60798 (project make): > > FWIW, this warning is not valid in this situation. The code is > > correct; p will always be pointing into a valid buffer and never > > pointing at the first character in that buffer, so p[-1] always > > points to valid memory. > > It's undefined behaviour in C to point to such a location, isn't it? To point to which such location? As I said, we know for a fact that p does not point at the first character of the array. It's clearly legal in C to walk backwards through an array!! And referencing the previous element in an array is certainly not a hack. I don't think I understand.
Re: [bug #60798] Make does not compile with GCC 11.1.0
On Fri, Jun 18, 2021 at 12:53:32PM -0400, Paul D. Smith wrote: > Follow-up Comment #1, bug #60798 (project make): > > FWIW, this warning is not valid in this situation. The code is correct; p > will always be pointing into a valid buffer and never pointing at the first > character in that buffer, so p[-1] always points to valid memory. It's undefined behaviour in C to point to such a location, isn't it? Is this hack really needed? > > When building code for production use, you should never use -Werror.