public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Handling of main() function for freestanding
@ 2022-09-28 20:15 Jonathan Wakely
  2022-09-29  6:00 ` Richard Biener
  2022-10-04 22:25 ` Jason Merrill
  0 siblings, 2 replies; 20+ messages in thread
From: Jonathan Wakely @ 2022-09-28 20:15 UTC (permalink / raw)
  To: gcc; +Cc: arsen, Jason Merrill

As part of implementing a C++23 proposal [1] to massively increase the
scope of the freestanding C++ standard library some questions came up
about the special handling of main() that happens for hosted
environments.

As required by both C++ (all versions) and C (since C99), falling off
the end of the main() function is not undefined, the compiler is
required to insert an implicit 'return 0' [2][3]. However, this
special handling only applies to hosted environments. For freestanding
the return type or even the existence of main is
implementation-defined. As a result, GCC gives a -Wreturn-type warning
for this code with -ffreestanding, but not with -fhosted:

int main() { }

Arsen (CC'd) has been working on the libstdc++ changes for the
freestanding proposal, and several thousand libstdc++ tests were
failing when using -ffreestanding, because of the -Wreturn-type
warnings. He wrote a patch to the compiler [4] to add a new
-fspecial-main flag which defaults to on for -fhosted, but can be used
with -ffreestanding to do the implicit 'return 0' (and so disable the
-Wreturn-type warnings) for freestanding as well. This fixes the
libstdc++ test FAILs.

However, after discussing this briefly with Jason it occurred to us
that if the user declares an 'int main()' function, it's a pretty big
hint that they do want main() to return an int. And so having
undefined behaviour do to a missing return isn't really doing anybody
any favours. If you're compiling for freestanding and you *don't* want
to return a value from main(), then just declare it as void main()
instead. So now we're wondering if we need -fspecial-main at all, or
if int main() and int main(int, char**) should always be "special",
even for freestanding. So Arsen wrote a patch to do that too [5].

The argument against making 'int main()' imply 'special main' is that
in a freestanding environment, a function called 'int main()' might be
just a normal function, not the program's entry point. And in that
case, maybe you really do want -Wreturn-type warnings. I don't know
how realistic that is.

So the question is, should Arsen continue with his -fspecial-main
patch, and propose it along with the libstdc++ changes, or should gcc
change to always make 'int main()' "special" even for freestanding?
void main() and long main() and other signatures would still be
allowed for freestanding, and would not have the implicit 'return 0'.

I have no horse in this race, so if the maintainers of bare metal
ports think int main() should not be special for -ffreestanding, so be
it. I hope the first patch to add -fspecial-main would be acceptable
in that case, and libstdc++ will use it when testing with
-ffreestanding.

[1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1642r11.html
[2] https://eel.is/c++draft/basic.start.main#5.sentence-2
[3] https://cigix.me/c17#5.1.2.2.3.p1
[4] https://github.com/ArsenArsen/gcc/commit/7e67edaced33e31a0dd4db4b3dd404c4a8daba59
[5] https://github.com/ArsenArsen/gcc/commit/c9bf2f9ed6161a38238e9c7f340d2c3bb04fe443

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-09-28 20:15 Handling of main() function for freestanding Jonathan Wakely
@ 2022-09-29  6:00 ` Richard Biener
  2022-09-29  7:12   ` Jakub Jelinek
  2022-10-04 22:25 ` Jason Merrill
  1 sibling, 1 reply; 20+ messages in thread
From: Richard Biener @ 2022-09-29  6:00 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc

On Wed, Sep 28, 2022 at 10:17 PM Jonathan Wakely via Gcc
<gcc@gcc.gnu.org> wrote:
>
> As part of implementing a C++23 proposal [1] to massively increase the
> scope of the freestanding C++ standard library some questions came up
> about the special handling of main() that happens for hosted
> environments.
>
> As required by both C++ (all versions) and C (since C99), falling off
> the end of the main() function is not undefined, the compiler is
> required to insert an implicit 'return 0' [2][3]. However, this
> special handling only applies to hosted environments. For freestanding
> the return type or even the existence of main is
> implementation-defined.
 ^^^^^^^^^^^^^^^^^^^^^^

so just document that 'int main(int, char **)' is special to GCC even in
freestanding environments and do not emit -Wreturn-type diagnostics?
I think that's entirely reasonable (but of course make sure to add
an implicit return 0; then as well)

Richard.

> As a result, GCC gives a -Wreturn-type warning
> for this code with -ffreestanding, but not with -fhosted:
>
> int main() { }
>
> Arsen (CC'd) has been working on the libstdc++ changes for the
> freestanding proposal, and several thousand libstdc++ tests were
> failing when using -ffreestanding, because of the -Wreturn-type
> warnings. He wrote a patch to the compiler [4] to add a new
> -fspecial-main flag which defaults to on for -fhosted, but can be used
> with -ffreestanding to do the implicit 'return 0' (and so disable the
> -Wreturn-type warnings) for freestanding as well. This fixes the
> libstdc++ test FAILs.
>
> However, after discussing this briefly with Jason it occurred to us
> that if the user declares an 'int main()' function, it's a pretty big
> hint that they do want main() to return an int. And so having
> undefined behaviour do to a missing return isn't really doing anybody
> any favours. If you're compiling for freestanding and you *don't* want
> to return a value from main(), then just declare it as void main()
> instead. So now we're wondering if we need -fspecial-main at all, or
> if int main() and int main(int, char**) should always be "special",
> even for freestanding. So Arsen wrote a patch to do that too [5].
>
> The argument against making 'int main()' imply 'special main' is that
> in a freestanding environment, a function called 'int main()' might be
> just a normal function, not the program's entry point. And in that
> case, maybe you really do want -Wreturn-type warnings. I don't know
> how realistic that is.
>
> So the question is, should Arsen continue with his -fspecial-main
> patch, and propose it along with the libstdc++ changes, or should gcc
> change to always make 'int main()' "special" even for freestanding?
> void main() and long main() and other signatures would still be
> allowed for freestanding, and would not have the implicit 'return 0'.
>
> I have no horse in this race, so if the maintainers of bare metal
> ports think int main() should not be special for -ffreestanding, so be
> it. I hope the first patch to add -fspecial-main would be acceptable
> in that case, and libstdc++ will use it when testing with
> -ffreestanding.
>
> [1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1642r11.html
> [2] https://eel.is/c++draft/basic.start.main#5.sentence-2
> [3] https://cigix.me/c17#5.1.2.2.3.p1
> [4] https://github.com/ArsenArsen/gcc/commit/7e67edaced33e31a0dd4db4b3dd404c4a8daba59
> [5] https://github.com/ArsenArsen/gcc/commit/c9bf2f9ed6161a38238e9c7f340d2c3bb04fe443

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-09-29  6:00 ` Richard Biener
@ 2022-09-29  7:12   ` Jakub Jelinek
  2022-09-29  9:21     ` Jonathan Wakely
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Jelinek @ 2022-09-29  7:12 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jonathan Wakely, gcc

On Thu, Sep 29, 2022 at 08:00:15AM +0200, Richard Biener via Gcc wrote:
> On Wed, Sep 28, 2022 at 10:17 PM Jonathan Wakely via Gcc
> <gcc@gcc.gnu.org> wrote:
> >
> > As part of implementing a C++23 proposal [1] to massively increase the
> > scope of the freestanding C++ standard library some questions came up
> > about the special handling of main() that happens for hosted
> > environments.
> >
> > As required by both C++ (all versions) and C (since C99), falling off
> > the end of the main() function is not undefined, the compiler is
> > required to insert an implicit 'return 0' [2][3]. However, this
> > special handling only applies to hosted environments. For freestanding
> > the return type or even the existence of main is
> > implementation-defined.
>  ^^^^^^^^^^^^^^^^^^^^^^
> 
> so just document that 'int main(int, char **)' is special to GCC even in
> freestanding environments and do not emit -Wreturn-type diagnostics?
> I think that's entirely reasonable (but of course make sure to add
> an implicit return 0; then as well)

-fspecial-main is weirdly named, I wonder if we couldn't do the
above by default and have -fno-builtin-main turn that special behavior
off (in that case then don't append return 0 and emit -Wreturn-type
diagnostics).  Not all our builtins are about whether we expand them inline, but
about whether we apply special handling to those functions, assume special
properties etc.  Just -fno-builtin shouldn't imply -fno-builtin-main...

	Jakub


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-09-29  7:12   ` Jakub Jelinek
@ 2022-09-29  9:21     ` Jonathan Wakely
  0 siblings, 0 replies; 20+ messages in thread
From: Jonathan Wakely @ 2022-09-29  9:21 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Richard Biener, gcc

On Thu, 29 Sept 2022 at 08:12, Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Thu, Sep 29, 2022 at 08:00:15AM +0200, Richard Biener via Gcc wrote:
> > On Wed, Sep 28, 2022 at 10:17 PM Jonathan Wakely via Gcc
> > <gcc@gcc.gnu.org> wrote:
> > >
> > > As part of implementing a C++23 proposal [1] to massively increase the
> > > scope of the freestanding C++ standard library some questions came up
> > > about the special handling of main() that happens for hosted
> > > environments.
> > >
> > > As required by both C++ (all versions) and C (since C99), falling off
> > > the end of the main() function is not undefined, the compiler is
> > > required to insert an implicit 'return 0' [2][3]. However, this
> > > special handling only applies to hosted environments. For freestanding
> > > the return type or even the existence of main is
> > > implementation-defined.
> >  ^^^^^^^^^^^^^^^^^^^^^^
> >
> > so just document that 'int main(int, char **)' is special to GCC even in
> > freestanding environments and do not emit -Wreturn-type diagnostics?
> > I think that's entirely reasonable (but of course make sure to add
> > an implicit return 0; then as well)
>
> -fspecial-main is weirdly named, I wonder if we couldn't do the
> above by default and have -fno-builtin-main turn that special behavior
> off (in that case then don't append return 0 and emit -Wreturn-type
> diagnostics).  Not all our builtins are about whether we expand them inline, but
> about whether we apply special handling to those functions, assume special
> properties etc.  Just -fno-builtin shouldn't imply -fno-builtin-main...

Yeah, that sounds like a good compromise. Make int main do the right
thing by default, but offer a switch to restore the current behaviour
for anybody who really wants it.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-09-28 20:15 Handling of main() function for freestanding Jonathan Wakely
  2022-09-29  6:00 ` Richard Biener
@ 2022-10-04 22:25 ` Jason Merrill
  2022-10-07 11:30   ` Jonathan Wakely
  1 sibling, 1 reply; 20+ messages in thread
From: Jason Merrill @ 2022-10-04 22:25 UTC (permalink / raw)
  To: Jonathan Wakely, gcc; +Cc: arsen

On 9/28/22 16:15, Jonathan Wakely wrote:
> As part of implementing a C++23 proposal [1] to massively increase the
> scope of the freestanding C++ standard library some questions came up
> about the special handling of main() that happens for hosted
> environments.
> 
> As required by both C++ (all versions) and C (since C99), falling off
> the end of the main() function is not undefined, the compiler is
> required to insert an implicit 'return 0' [2][3]. However, this
> special handling only applies to hosted environments. For freestanding
> the return type or even the existence of main is
> implementation-defined. As a result, GCC gives a -Wreturn-type warning
> for this code with -ffreestanding, but not with -fhosted:
> 
> int main() { }
> 
> Arsen (CC'd) has been working on the libstdc++ changes for the
> freestanding proposal, and several thousand libstdc++ tests were
> failing when using -ffreestanding, because of the -Wreturn-type
> warnings. He wrote a patch to the compiler [4] to add a new
> -fspecial-main flag which defaults to on for -fhosted, but can be used
> with -ffreestanding to do the implicit 'return 0' (and so disable the
> -Wreturn-type warnings) for freestanding as well. This fixes the
> libstdc++ test FAILs.
> 
> However, after discussing this briefly with Jason it occurred to us
> that if the user declares an 'int main()' function, it's a pretty big
> hint that they do want main() to return an int. And so having
> undefined behaviour do to a missing return isn't really doing anybody
> any favours. If you're compiling for freestanding and you *don't* want
> to return a value from main(), then just declare it as void main()
> instead. So now we're wondering if we need -fspecial-main at all, or
> if int main() and int main(int, char**) should always be "special",
> even for freestanding. So Arsen wrote a patch to do that too [5].
> 
> The argument against making 'int main()' imply 'special main' is that
> in a freestanding environment, a function called 'int main()' might be
> just a normal function, not the program's entry point. And in that
> case, maybe you really do want -Wreturn-type warnings. I don't know
> how realistic that is.
> 
> So the question is, should Arsen continue with his -fspecial-main
> patch, and propose it along with the libstdc++ changes, or should gcc
> change to always make 'int main()' "special" even for freestanding?
> void main() and long main() and other signatures would still be
> allowed for freestanding, and would not have the implicit 'return 0'.

I would rather not add a flag.  No well-defined freestanding program is 
affected by implicit return 0 from main, it should always be enabled.

> I have no horse in this race, so if the maintainers of bare metal
> ports think int main() should not be special for -ffreestanding, so be
> it. I hope the first patch to add -fspecial-main would be acceptable
> in that case, and libstdc++ will use it when testing with
> -ffreestanding.
> 
> [1] https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1642r11.html
> [2] https://eel.is/c++draft/basic.start.main#5.sentence-2
> [3] https://cigix.me/c17#5.1.2.2.3.p1
> [4] https://github.com/ArsenArsen/gcc/commit/7e67edaced33e31a0dd4db4b3dd404c4a8daba59
> [5] https://github.com/ArsenArsen/gcc/commit/c9bf2f9ed6161a38238e9c7f340d2c3bb04fe443
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-04 22:25 ` Jason Merrill
@ 2022-10-07 11:30   ` Jonathan Wakely
  2022-10-07 13:51     ` Jason Merrill
  0 siblings, 1 reply; 20+ messages in thread
From: Jonathan Wakely @ 2022-10-07 11:30 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc, arsen, Jakub Jelinek

On Tue, 4 Oct 2022 at 23:25, Jason Merrill <jason@redhat.com> wrote:
>
> On 9/28/22 16:15, Jonathan Wakely wrote:
> > As part of implementing a C++23 proposal [1] to massively increase the
> > scope of the freestanding C++ standard library some questions came up
> > about the special handling of main() that happens for hosted
> > environments.
> >
> > As required by both C++ (all versions) and C (since C99), falling off
> > the end of the main() function is not undefined, the compiler is
> > required to insert an implicit 'return 0' [2][3]. However, this
> > special handling only applies to hosted environments. For freestanding
> > the return type or even the existence of main is
> > implementation-defined. As a result, GCC gives a -Wreturn-type warning
> > for this code with -ffreestanding, but not with -fhosted:
> >
> > int main() { }
> >
> > Arsen (CC'd) has been working on the libstdc++ changes for the
> > freestanding proposal, and several thousand libstdc++ tests were
> > failing when using -ffreestanding, because of the -Wreturn-type
> > warnings. He wrote a patch to the compiler [4] to add a new
> > -fspecial-main flag which defaults to on for -fhosted, but can be used
> > with -ffreestanding to do the implicit 'return 0' (and so disable the
> > -Wreturn-type warnings) for freestanding as well. This fixes the
> > libstdc++ test FAILs.
> >
> > However, after discussing this briefly with Jason it occurred to us
> > that if the user declares an 'int main()' function, it's a pretty big
> > hint that they do want main() to return an int. And so having
> > undefined behaviour do to a missing return isn't really doing anybody
> > any favours. If you're compiling for freestanding and you *don't* want
> > to return a value from main(), then just declare it as void main()
> > instead. So now we're wondering if we need -fspecial-main at all, or
> > if int main() and int main(int, char**) should always be "special",
> > even for freestanding. So Arsen wrote a patch to do that too [5].
> >
> > The argument against making 'int main()' imply 'special main' is that
> > in a freestanding environment, a function called 'int main()' might be
> > just a normal function, not the program's entry point. And in that
> > case, maybe you really do want -Wreturn-type warnings. I don't know
> > how realistic that is.
> >
> > So the question is, should Arsen continue with his -fspecial-main
> > patch, and propose it along with the libstdc++ changes, or should gcc
> > change to always make 'int main()' "special" even for freestanding?
> > void main() and long main() and other signatures would still be
> > allowed for freestanding, and would not have the implicit 'return 0'.
>
> I would rather not add a flag.  No well-defined freestanding program is
> affected by implicit return 0 from main, it should always be enabled.

There are some tests that fail if we do that. For whatever reason,
they're checking the current semantics.

Arsen implemented Jakub's suggestion which is to add the implicit
return by default, but add -fno-builtin-main to restore the previous
behaviour. Is that acceptable? If not, can you and Jakub reach
consensus so that Arsen knows what to do instead?
His -fno-builtin-main patch is at
https://gcc.gnu.org/pipermail/gcc-patches/2022-September/602644.html
(This is the only one of his patch series not committed, and results
in 100s of FAILs for libstdc++ when testing with -fffreestanding).

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-07 11:30   ` Jonathan Wakely
@ 2022-10-07 13:51     ` Jason Merrill
  2022-10-07 13:53       ` Jakub Jelinek
  2022-10-13 17:03       ` Arsen Arsenović
  0 siblings, 2 replies; 20+ messages in thread
From: Jason Merrill @ 2022-10-07 13:51 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc, arsen, Jakub Jelinek, Joseph S. Myers

On 10/7/22 07:30, Jonathan Wakely wrote:
> On Tue, 4 Oct 2022 at 23:25, Jason Merrill <jason@redhat.com> wrote:
>>
>> On 9/28/22 16:15, Jonathan Wakely wrote:
>>> As part of implementing a C++23 proposal [1] to massively increase the
>>> scope of the freestanding C++ standard library some questions came up
>>> about the special handling of main() that happens for hosted
>>> environments.
>>>
>>> As required by both C++ (all versions) and C (since C99), falling off
>>> the end of the main() function is not undefined, the compiler is
>>> required to insert an implicit 'return 0' [2][3]. However, this
>>> special handling only applies to hosted environments. For freestanding
>>> the return type or even the existence of main is
>>> implementation-defined. As a result, GCC gives a -Wreturn-type warning
>>> for this code with -ffreestanding, but not with -fhosted:
>>>
>>> int main() { }
>>>
>>> Arsen (CC'd) has been working on the libstdc++ changes for the
>>> freestanding proposal, and several thousand libstdc++ tests were
>>> failing when using -ffreestanding, because of the -Wreturn-type
>>> warnings. He wrote a patch to the compiler [4] to add a new
>>> -fspecial-main flag which defaults to on for -fhosted, but can be used
>>> with -ffreestanding to do the implicit 'return 0' (and so disable the
>>> -Wreturn-type warnings) for freestanding as well. This fixes the
>>> libstdc++ test FAILs.
>>>
>>> However, after discussing this briefly with Jason it occurred to us
>>> that if the user declares an 'int main()' function, it's a pretty big
>>> hint that they do want main() to return an int. And so having
>>> undefined behaviour do to a missing return isn't really doing anybody
>>> any favours. If you're compiling for freestanding and you *don't* want
>>> to return a value from main(), then just declare it as void main()
>>> instead. So now we're wondering if we need -fspecial-main at all, or
>>> if int main() and int main(int, char**) should always be "special",
>>> even for freestanding. So Arsen wrote a patch to do that too [5].
>>>
>>> The argument against making 'int main()' imply 'special main' is that
>>> in a freestanding environment, a function called 'int main()' might be
>>> just a normal function, not the program's entry point. And in that
>>> case, maybe you really do want -Wreturn-type warnings. I don't know
>>> how realistic that is.
>>>
>>> So the question is, should Arsen continue with his -fspecial-main
>>> patch, and propose it along with the libstdc++ changes, or should gcc
>>> change to always make 'int main()' "special" even for freestanding?
>>> void main() and long main() and other signatures would still be
>>> allowed for freestanding, and would not have the implicit 'return 0'.
>>
>> I would rather not add a flag.  No well-defined freestanding program is
>> affected by implicit return 0 from main, it should always be enabled.
> 
> There are some tests that fail if we do that. For whatever reason,
> they're checking the current semantics.

> 	* gcc.dg/c11-noreturn-4.c: Add -fno-builtin-main to options.
> 	* gcc.dg/inline-10.c: Likewise.

IMO we still shouldn't emit these pedwarns when freestanding, we 
shouldn't require people to add another flag to avoid them.

Adding the implicit return 0 unconditionally doesn't mean we also need 
to adopt all the other special treatment of main.

And I guess we shouldn't implicitly return 0 if the function is declared 
noreturn.

> 	* gcc.dg/noreturn-4.c: Likewise.

I'd be inclined to drop this test.

> Arsen implemented Jakub's suggestion which is to add the implicit
> return by default, but add -fno-builtin-main to restore the previous
> behaviour. Is that acceptable? If not, can you and Jakub reach
> consensus so that Arsen knows what to do instead?
> His -fno-builtin-main patch is at
> https://gcc.gnu.org/pipermail/gcc-patches/2022-September/602644.html
> (This is the only one of his patch series not committed, and results
> in 100s of FAILs for libstdc++ when testing with -fffreestanding).


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-07 13:51     ` Jason Merrill
@ 2022-10-07 13:53       ` Jakub Jelinek
  2022-10-13 17:03       ` Arsen Arsenović
  1 sibling, 0 replies; 20+ messages in thread
From: Jakub Jelinek @ 2022-10-07 13:53 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Jonathan Wakely, gcc, arsen, Joseph S. Myers

On Fri, Oct 07, 2022 at 09:51:31AM -0400, Jason Merrill wrote:
> > There are some tests that fail if we do that. For whatever reason,
> > they're checking the current semantics.
> 
> > 	* gcc.dg/c11-noreturn-4.c: Add -fno-builtin-main to options.
> > 	* gcc.dg/inline-10.c: Likewise.
> 
> IMO we still shouldn't emit these pedwarns when freestanding, we shouldn't
> require people to add another flag to avoid them.
> 
> Adding the implicit return 0 unconditionally doesn't mean we also need to
> adopt all the other special treatment of main.
> 
> And I guess we shouldn't implicitly return 0 if the function is declared
> noreturn.
> 
> > 	* gcc.dg/noreturn-4.c: Likewise.
> 
> I'd be inclined to drop this test.

Ok.

> > Arsen implemented Jakub's suggestion which is to add the implicit
> > return by default, but add -fno-builtin-main to restore the previous
> > behaviour. Is that acceptable? If not, can you and Jakub reach
> > consensus so that Arsen knows what to do instead?
> > His -fno-builtin-main patch is at
> > https://gcc.gnu.org/pipermail/gcc-patches/2022-September/602644.html
> > (This is the only one of his patch series not committed, and results
> > in 100s of FAILs for libstdc++ when testing with -fffreestanding).

	Jakub


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-07 13:51     ` Jason Merrill
  2022-10-07 13:53       ` Jakub Jelinek
@ 2022-10-13 17:03       ` Arsen Arsenović
  2022-10-13 17:10         ` Jakub Jelinek
  2022-10-13 17:24         ` Jason Merrill
  1 sibling, 2 replies; 20+ messages in thread
From: Arsen Arsenović @ 2022-10-13 17:03 UTC (permalink / raw)
  To: Jonathan Wakely, gcc-patches
  Cc: gcc, Jakub Jelinek, Joseph S. Myers, Jason Merrill


[-- Attachment #1.1: Type: text/plain, Size: 604 bytes --]

Hi,

On Friday, 7 October 2022 15:51:31 CEST Jason Merrill wrote:
> > 	* gcc.dg/noreturn-4.c: Likewise.
> 
> I'd be inclined to drop this test.
That seems like an odd choice, why do that over using another function 
for the test case? (there's nothing specific to main in this test, and 
it doesn't even need to link, so using any ol' function should be okay; 
see attachment)

The attached patch is also v2 of the original builtin-main one submitted 
earlier.  Tested on x86_64-pc-linux-gnu.  This revision excludes the 
mentioned pedwarns unless hosted.

Thanks,
-- 
Arsen Arsenović

[-- Attachment #1.2: v2-0001-c-family-Implement-new-int-main-semantics-in-free.patch --]
[-- Type: text/x-patch, Size: 12375 bytes --]

From 27a2cf85b1c3eb901413fd135918af0377bd1459 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
Date: Tue, 20 Sep 2022 19:17:31 +0200
Subject: [PATCH v2] c-family: Implement new `int main' semantics in
 freestanding

From now, by default, (specifically) `int main' in freestanding will
implicitly return 0, as it does for hosted modes. The old behaviour is
still accessible via -fno-builtin-main.

gcc/c-family/ChangeLog:

	* c-common.cc (disable_builtin_function): Support special value
	`main' that, in freestanding, allows disabling special casing
	placed around `main'.
	* c-common.h: Add flag_builtin_main.
	(want_builtin_main_p): New function, true iff hosted OR
	builtin_main are set.

gcc/c/ChangeLog:

	* c-decl.cc (grokdeclarator): Consider flag_builtin_main when
	deciding whether to emit warnings.
	(finish_function): Consider flag_builtin_main and the noreturn
	flag when deciding whether to emit an implicit zero return.
	* c-objc-common.cc (c_missing_noreturn_ok_p): Consider missing
	noreturn okay only when hosted or when builtin_main is enabled.

gcc/cp/ChangeLog:

	* cp-tree.h (DECL_MAIN_P): Consider flag_builtin_main when
	deciding whether this function is to be the special function
	main.
	* decl.cc (grokfndecl): Only pedwarn on hosted.
	(finish_function): Do not inject extra return of marked
	noreturn.

gcc/ChangeLog:

	* doc/invoke.texi: Document -fno-builtin-main.

gcc/testsuite/ChangeLog:

	* gcc.dg/noreturn-4.c: Don't use `main', but a generic function
	name instead.
	* g++.dg/freestanding-main-implicitly-returns.C: New test.
	* g++.dg/no-builtin-main.C: New test.
	* gcc.dg/freestanding-main-implicitly-returns.c: New test.
	* gcc.dg/no-builtin-main.c: New test.
---
 gcc/c-family/c-common.cc                      |  6 ++++++
 gcc/c-family/c-common.h                       | 10 ++++++++++
 gcc/c/c-decl.cc                               |  4 ++--
 gcc/c/c-objc-common.cc                        |  9 ++++++---
 gcc/cp/cp-tree.h                              | 12 ++++++-----
 gcc/cp/decl.cc                                |  6 ++++--
 gcc/doc/invoke.texi                           | 20 ++++++++++++++-----
 .../freestanding-main-implicitly-returns.C    |  5 +++++
 gcc/testsuite/g++.dg/no-builtin-main.C        |  5 +++++
 .../freestanding-main-implicitly-returns.c    |  5 +++++
 gcc/testsuite/gcc.dg/no-builtin-main.c        |  5 +++++
 gcc/testsuite/gcc.dg/noreturn-4.c             |  6 +++---
 12 files changed, 73 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/freestanding-main-implicitly-returns.C
 create mode 100644 gcc/testsuite/g++.dg/no-builtin-main.C
 create mode 100644 gcc/testsuite/gcc.dg/freestanding-main-implicitly-returns.c
 create mode 100644 gcc/testsuite/gcc.dg/no-builtin-main.c

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 9ec9100cc90..f9060cbc171 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -232,6 +232,10 @@ int flag_isoc2x;
 
 int flag_hosted = 1;
 
+/* Nonzero means that we want to give main its special meaning */
+
+int flag_builtin_main = 1;
+
 
 /* ObjC language option variables.  */
 
@@ -4879,6 +4883,8 @@ disable_builtin_function (const char *name)
 {
   if (startswith (name, "__builtin_"))
     error ("cannot disable built-in function %qs", name);
+  else if (strcmp("main", name) == 0)
+    flag_builtin_main = 0;
   else
     {
       disabled_builtin *new_disabled_builtin = XNEW (disabled_builtin);
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 62ab4ba437b..44537cc6977 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -689,6 +689,16 @@ extern int flag_isoc2x;
 
 extern int flag_hosted;
 
+/* Nonzero means that we want to give main its special meaning */
+
+extern int flag_builtin_main;
+
+/* Returns false if both flag_hosted and flag_builtin_main are zero, true
+   otherwise. */
+inline bool builtin_main_p() {
+  return flag_hosted || flag_builtin_main;
+}
+
 /* ObjC language option variables.  */
 
 
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 193e268f04e..891e36b30b6 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -10442,9 +10442,9 @@ finish_function (location_t end_loc)
   if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
     DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
 
-  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted
+  if (MAIN_NAME_P (DECL_NAME (fndecl)) && builtin_main_p()
       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
-      == integer_type_node && flag_isoc99)
+      == integer_type_node && flag_isoc99 && !TREE_THIS_VOLATILE (fndecl))
     {
       /* Hack.  We don't want the middle-end to warn that this return
 	 is unreachable, so we mark its location as special.  Using
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index 70e10a98e33..e229580b182 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -37,9 +37,12 @@ static bool c_tree_printer (pretty_printer *, text_info *, const char *,
 bool
 c_missing_noreturn_ok_p (tree decl)
 {
-  /* A missing noreturn is not ok for freestanding implementations and
-     ok for the `main' function in hosted implementations.  */
-  return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
+  /* Missing a return is only okay when flag_builtin_main is enabled, and we
+     are `int main'. */
+  if (!MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+    return false;
+  return builtin_main_p()
+    && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == integer_type_node;
 }
 
 /* Called from check_global_declaration.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3b67be651b9..10406fbfb00 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -772,11 +772,13 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 
 /* Returns nonzero iff NODE is a declaration for the global function
    `main'.  */
-#define DECL_MAIN_P(NODE)				\
-   (DECL_EXTERN_C_FUNCTION_P (NODE)			\
-    && DECL_NAME (NODE) != NULL_TREE			\
-    && MAIN_NAME_P (DECL_NAME (NODE))			\
-    && flag_hosted)
+#define DECL_MAIN_P(NODE)					\
+   (DECL_EXTERN_C_FUNCTION_P (NODE)				\
+    && DECL_NAME (NODE) != NULL_TREE				\
+    && MAIN_NAME_P (DECL_NAME (NODE))				\
+    && (flag_hosted || (flag_builtin_main			\
+	&& TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (NODE)))	\
+	    == integer_type_node)))
 
 /* Lookup walker marking.  */
 #define LOOKUP_SEEN_P(NODE) TREE_VISITED (NODE)
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 82eb0c2f22a..54bbd15a1ce 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -10301,7 +10301,8 @@ grokfndecl (tree ctype,
   if (ctype && funcdef_flag)
     check_class_member_definition_namespace (decl);
 
-  if (ctype == NULL_TREE && DECL_MAIN_P (decl))
+  /* We should only be pedantic about main if hosted. */
+  if (ctype == NULL_TREE && DECL_MAIN_P (decl) && flag_hosted)
     {
       if (PROCESSING_REAL_TEMPLATE_DECL_P())
 	error_at (location, "cannot declare %<::main%> to be a template");
@@ -17854,7 +17855,8 @@ finish_function (bool inline_p)
   if (!DECL_CLONED_FUNCTION_P (fndecl))
     {
       /* Make it so that `main' always returns 0 by default.  */
-      if (DECL_MAIN_P (current_function_decl))
+      if (DECL_MAIN_P (current_function_decl)
+	  && !TREE_THIS_VOLATILE(current_function_decl))
 	finish_return_stmt (integer_zero_node);
 
       if (use_eh_spec_block (current_function_decl))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a9ecc4426a4..41d7fa6f922 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -2541,8 +2541,10 @@ the @code{asm} keyword, since @code{typeof} is a standard keyword in
 ISO C2X.
 
 @item -fno-builtin
+@itemx -fno-builtin-main
 @itemx -fno-builtin-@var{function}
 @opindex fno-builtin
+@opindex fno-builtin-main
 @opindex fbuiltin
 @cindex built-in functions
 Don't recognize built-in functions that do not begin with
@@ -2581,6 +2583,11 @@ built-in functions selectively when using @option{-fno-builtin} or
 #define strcpy(d, s)    __builtin_strcpy ((d), (s))
 @end smallexample
 
+The special form @option{-fno-builtin-main} permits disabling special
+handling of the @code{main} function, such as the implicit zero
+return.  This option has no effect in hosted mode (as hosted takes
+precedence over it) and is not implied by @option{-fno-builtin}.
+
 @item -fcond-mismatch
 @opindex fcond-mismatch
 Allow conditional expressions with mismatched types in the second and
@@ -2589,13 +2596,16 @@ is not supported for C++.
 
 @item -ffreestanding
 @opindex ffreestanding
+@opindex fno-builtin-main
 @cindex hosted environment
 
 Assert that compilation targets a freestanding environment.  This
-implies @option{-fno-builtin}.  A freestanding environment
-is one in which the standard library may not exist, and program startup may
-not necessarily be at @code{main}.  The most obvious example is an OS kernel.
-This is equivalent to @option{-fno-hosted}.
+implies @option{-fno-builtin}.  A freestanding environment is one in
+which the standard library may not exist, and program startup may not
+necessarily be at @code{main}.  The most obvious example is an OS
+kernel.  Note that this option does not imply
+@option{-fno-builtin-main}.  @option{-ffreestanding} is equivalent to
+@option{-fno-hosted}.
 
 @xref{Standards,,Language Standards Supported by GCC}, for details of
 freestanding and hosted environments.
@@ -5864,7 +5874,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
 -Wimplicit-function-declaration @r{(C and Objective-C only)} @gol
 -Winit-self @r{(only for C++)} @gol
 -Wlogical-not-parentheses @gol
--Wmain @r{(only for C/ObjC and unless} @option{-ffreestanding}@r{)}  @gol
+-Wmain @r{(only for C/ObjC and unless} @option{-fno-builtin-main}@r{)}  @gol
 -Wmaybe-uninitialized @gol
 -Wmemset-elt-size @gol
 -Wmemset-transposed-args @gol
diff --git a/gcc/testsuite/g++.dg/freestanding-main-implicitly-returns.C b/gcc/testsuite/g++.dg/freestanding-main-implicitly-returns.C
new file mode 100644
index 00000000000..068ddd4d5ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/freestanding-main-implicitly-returns.C
@@ -0,0 +1,5 @@
+/* Make sure main is implicitly returned from, even in freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-Wreturn-type -ffreestanding" } */
+
+int main() {}
diff --git a/gcc/testsuite/g++.dg/no-builtin-main.C b/gcc/testsuite/g++.dg/no-builtin-main.C
new file mode 100644
index 00000000000..7431784d018
--- /dev/null
+++ b/gcc/testsuite/g++.dg/no-builtin-main.C
@@ -0,0 +1,5 @@
+/* Make sure we get warned about missing return with -fno-builtin-main. */
+/* { dg-do compile } */
+/* { dg-options "-Wreturn-type -ffreestanding -fno-builtin-main" } */
+
+int main() {} /* { dg-warning "-Wreturn-type" } */
diff --git a/gcc/testsuite/gcc.dg/freestanding-main-implicitly-returns.c b/gcc/testsuite/gcc.dg/freestanding-main-implicitly-returns.c
new file mode 100644
index 00000000000..068ddd4d5ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/freestanding-main-implicitly-returns.c
@@ -0,0 +1,5 @@
+/* Make sure main is implicitly returned from, even in freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-Wreturn-type -ffreestanding" } */
+
+int main() {}
diff --git a/gcc/testsuite/gcc.dg/no-builtin-main.c b/gcc/testsuite/gcc.dg/no-builtin-main.c
new file mode 100644
index 00000000000..7431784d018
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/no-builtin-main.c
@@ -0,0 +1,5 @@
+/* Make sure we get warned about missing return with -fno-builtin-main. */
+/* { dg-do compile } */
+/* { dg-options "-Wreturn-type -ffreestanding -fno-builtin-main" } */
+
+int main() {} /* { dg-warning "-Wreturn-type" } */
diff --git a/gcc/testsuite/gcc.dg/noreturn-4.c b/gcc/testsuite/gcc.dg/noreturn-4.c
index 6fe144754d0..ddedb0896db 100644
--- a/gcc/testsuite/gcc.dg/noreturn-4.c
+++ b/gcc/testsuite/gcc.dg/noreturn-4.c
@@ -1,10 +1,10 @@
 /* Check for "noreturn" warning in main. */
 /* { dg-do compile } */
-/* { dg-options "-O2 -Wmissing-noreturn -ffreestanding" } */
+/* { dg-options "-O2 -Wmissing-noreturn" } */
 extern void exit (int) __attribute__ ((__noreturn__));
 
-int
-main (void) /* { dg-warning "function might be candidate for attribute 'noreturn'" "warn for main" } */
+void
+f (void) /* { dg-warning "function might be candidate for attribute 'noreturn'" "warn for main" } */
 {
   exit (0);
 }
-- 
2.38.0


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-13 17:03       ` Arsen Arsenović
@ 2022-10-13 17:10         ` Jakub Jelinek
  2022-10-13 17:26           ` Arsen Arsenović
  2022-10-13 17:24         ` Jason Merrill
  1 sibling, 1 reply; 20+ messages in thread
From: Jakub Jelinek @ 2022-10-13 17:10 UTC (permalink / raw)
  To: Arsen Arsenović
  Cc: Jonathan Wakely, gcc-patches, gcc, Joseph S. Myers, Jason Merrill

On Thu, Oct 13, 2022 at 07:03:24PM +0200, Arsen Arsenović wrote:
> @@ -1,10 +1,10 @@
>  /* Check for "noreturn" warning in main. */
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -Wmissing-noreturn -ffreestanding" } */
> +/* { dg-options "-O2 -Wmissing-noreturn" } */
>  extern void exit (int) __attribute__ ((__noreturn__));
>  
> -int
> -main (void) /* { dg-warning "function might be candidate for attribute 'noreturn'" "warn for main" } */
> +void
> +f (void) /* { dg-warning "function might be candidate for attribute 'noreturn'" "warn for main" } */
>  {
>    exit (0);
>  }

Don't we have such a test already elsewhere?  If not, then certain
"warn for main" part should be removed or replaced...

	Jakub


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-13 17:03       ` Arsen Arsenović
  2022-10-13 17:10         ` Jakub Jelinek
@ 2022-10-13 17:24         ` Jason Merrill
  2022-10-13 20:14           ` Arsen Arsenović
  1 sibling, 1 reply; 20+ messages in thread
From: Jason Merrill @ 2022-10-13 17:24 UTC (permalink / raw)
  To: Arsen Arsenović, Jonathan Wakely, gcc-patches
  Cc: gcc, Jakub Jelinek, Joseph S. Myers

On 10/13/22 13:02, Arsen Arsenović wrote:
> Hi,
> 
> On Friday, 7 October 2022 15:51:31 CEST Jason Merrill wrote:
>>> 	* gcc.dg/noreturn-4.c: Likewise.
>>
>> I'd be inclined to drop this test.
> That seems like an odd choice, why do that over using another function
> for the test case? (there's nothing specific to main in this test, and
> it doesn't even need to link, so using any ol' function should be okay;
> see attachment)

It seemed to me that the test was specifically checking that main was 
treated like any other function when freestanding.

> The attached patch is also v2 of the original builtin-main one submitted
> earlier.  Tested on x86_64-pc-linux-gnu.  This revision excludes the
> mentioned pedwarns unless hosted.

I was arguing that we don't need the new flag; there shouldn't be any 
need to turn it off.

Jason


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-13 17:10         ` Jakub Jelinek
@ 2022-10-13 17:26           ` Arsen Arsenović
  0 siblings, 0 replies; 20+ messages in thread
From: Arsen Arsenović @ 2022-10-13 17:26 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jonathan Wakely, gcc-patches, gcc, Joseph S. Myers,
	Jason Merrill, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 377 bytes --]

On Thursday, 13 October 2022 19:10:10 CEST Jakub Jelinek wrote:
> Don't we have such a test already elsewhere?  If not, then certain
> "warn for main" part should be removed or replaced...

Whoops, missed that comment.  There is actually an equivalent test that 
I overlooked (noreturn-1.c), so maybe dropping is the right thing to do, 
indeed.

-- 
Arsen Arsenović

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-13 17:24         ` Jason Merrill
@ 2022-10-13 20:14           ` Arsen Arsenović
  2022-10-13 21:16             ` Jason Merrill
  0 siblings, 1 reply; 20+ messages in thread
From: Arsen Arsenović @ 2022-10-13 20:14 UTC (permalink / raw)
  To: Jonathan Wakely, gcc-patches
  Cc: gcc, Jakub Jelinek, Joseph S. Myers, Jason Merrill


[-- Attachment #1.1: Type: text/plain, Size: 663 bytes --]

On Thursday, 13 October 2022 19:24:41 CEST Jason Merrill wrote:
> I was arguing that we don't need the new flag; there shouldn't be any
> need to turn it off.
At the time, I opted to go with a more conservative route; I haven't 
been around enough to have very strong opinions ;)  I certainly can't 
think of a way always adding a return can go wrong, but figured someone, 
somehow, might rely on this behavior.  Removed the flag and tested on 
x86_64-pc-linux-gnu, v3 attached.

FWIW, there's precedent for treating main specially regardless of 
flag_hosted (e.g. it's always marked extern "C" in the C++ frontend, 
AFAICT).

-- 
Arsen Arsenović

[-- Attachment #1.2: v3-0001-c-family-Implicitly-return-zero-from-main-even-on.patch --]
[-- Type: text/x-patch, Size: 4980 bytes --]

From e60be6bb45fdba8085bde5d1883deeae640e786b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
Date: Thu, 13 Oct 2022 21:46:30 +0200
Subject: [PATCH v3] c-family: Implicitly return zero from main even on
 freestanding

... unless marked noreturn.

This should not get in anyone's way, but should permit the use of main()
in freestanding more easily, especially for writing test cases that
should work both in freestanding and hosted modes.

gcc/c/ChangeLog:

	* c-decl.cc (finish_function): Ignore hosted when deciding
	whether to implicitly return zero, but check noreturn.
	* c-objc-common.cc (c_missing_noreturn_ok_p): Loosen the
	requirements to just MAIN_NAME_P.

gcc/cp/ChangeLog:

	* cp-tree.h (DECL_MAIN_FREESTANDING_P): Move most DECL_MAIN_P
	logic here, so that we can use it when not hosted.
	(DECL_MAIN_P): Implement in terms of DECL_MAIN_FREESTANDING_P.
	* decl.cc (finish_function): Use DECL_MAIN_FREESTANDING_P
	instead of DECL_MAIN_P, to lose the hosted requirement, but
	check noreturn.

gcc/testsuite/ChangeLog:

	* g++.dg/freestanding-main.C: New test.
	* gcc.dg/freestanding-main.c: New test.
---
 gcc/c/c-decl.cc                          | 2 +-
 gcc/c/c-objc-common.cc                   | 5 ++---
 gcc/cp/cp-tree.h                         | 8 +++++---
 gcc/cp/decl.cc                           | 3 ++-
 gcc/testsuite/g++.dg/freestanding-main.C | 5 +++++
 gcc/testsuite/gcc.dg/freestanding-main.c | 5 +++++
 6 files changed, 20 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/freestanding-main.C
 create mode 100644 gcc/testsuite/gcc.dg/freestanding-main.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 193e268f04e..8c655590558 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -10442,7 +10442,7 @@ finish_function (location_t end_loc)
   if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
     DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
 
-  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted
+  if (MAIN_NAME_P (DECL_NAME (fndecl)) && !TREE_THIS_VOLATILE (fndecl)
       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
       == integer_type_node && flag_isoc99)
     {
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index 70e10a98e33..2933414fd45 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -37,9 +37,8 @@ static bool c_tree_printer (pretty_printer *, text_info *, const char *,
 bool
 c_missing_noreturn_ok_p (tree decl)
 {
-  /* A missing noreturn is not ok for freestanding implementations and
-     ok for the `main' function in hosted implementations.  */
-  return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
+  /* A missing noreturn is ok for the `main' function.  */
+  return MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
 }
 
 /* Called from check_global_declaration.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3b67be651b9..4c7adfbffd8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -772,11 +772,13 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 
 /* Returns nonzero iff NODE is a declaration for the global function
    `main'.  */
-#define DECL_MAIN_P(NODE)				\
+#define DECL_MAIN_FREESTANDING_P(NODE)			\
    (DECL_EXTERN_C_FUNCTION_P (NODE)			\
     && DECL_NAME (NODE) != NULL_TREE			\
-    && MAIN_NAME_P (DECL_NAME (NODE))			\
-    && flag_hosted)
+    && MAIN_NAME_P (DECL_NAME (NODE)))
+
+/* Nonzero iff NODE is a declaration for `main', and we are hosted. */
+#define DECL_MAIN_P(NODE) (DECL_MAIN_FREESTANDING_P(NODE) && flag_hosted)
 
 /* Lookup walker marking.  */
 #define LOOKUP_SEEN_P(NODE) TREE_VISITED (NODE)
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 82eb0c2f22a..cfc8cd5afd7 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17854,7 +17854,8 @@ finish_function (bool inline_p)
   if (!DECL_CLONED_FUNCTION_P (fndecl))
     {
       /* Make it so that `main' always returns 0 by default.  */
-      if (DECL_MAIN_P (current_function_decl))
+      if (DECL_MAIN_FREESTANDING_P (current_function_decl)
+	  && !TREE_THIS_VOLATILE (current_function_decl))
 	finish_return_stmt (integer_zero_node);
 
       if (use_eh_spec_block (current_function_decl))
diff --git a/gcc/testsuite/g++.dg/freestanding-main.C b/gcc/testsuite/g++.dg/freestanding-main.C
new file mode 100644
index 00000000000..3718cc4508e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/freestanding-main.C
@@ -0,0 +1,5 @@
+/* Make sure we don't get a missing return warning on freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-ffreestanding -Wreturn-type" } */
+
+int main() {}
diff --git a/gcc/testsuite/gcc.dg/freestanding-main.c b/gcc/testsuite/gcc.dg/freestanding-main.c
new file mode 100644
index 00000000000..3718cc4508e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/freestanding-main.c
@@ -0,0 +1,5 @@
+/* Make sure we don't get a missing return warning on freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-ffreestanding -Wreturn-type" } */
+
+int main() {}
-- 
2.38.0


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-13 20:14           ` Arsen Arsenović
@ 2022-10-13 21:16             ` Jason Merrill
  2022-10-14 10:04               ` Arsen Arsenović
  0 siblings, 1 reply; 20+ messages in thread
From: Jason Merrill @ 2022-10-13 21:16 UTC (permalink / raw)
  To: Arsen Arsenović, Jonathan Wakely, gcc-patches
  Cc: gcc, Jakub Jelinek, Joseph S. Myers

On 10/13/22 16:14, Arsen Arsenović wrote:
> On Thursday, 13 October 2022 19:24:41 CEST Jason Merrill wrote:
>> I was arguing that we don't need the new flag; there shouldn't be any
>> need to turn it off.
> At the time, I opted to go with a more conservative route; I haven't
> been around enough to have very strong opinions ;)  I certainly can't
> think of a way always adding a return can go wrong, but figured someone,
> somehow, might rely on this behavior.  Removed the flag and tested on
> x86_64-pc-linux-gnu, v3 attached.

Thanks!

> FWIW, there's precedent for treating main specially regardless of
> flag_hosted (e.g. it's always marked extern "C" in the C++ frontend,
> AFAICT).
> 
> -#define DECL_MAIN_P(NODE)				\
> +#define DECL_MAIN_FREESTANDING_P(NODE)			\
>     (DECL_EXTERN_C_FUNCTION_P (NODE)			\
>      && DECL_NAME (NODE) != NULL_TREE			\
> -    && MAIN_NAME_P (DECL_NAME (NODE))			\
> -    && flag_hosted)
> +    && MAIN_NAME_P (DECL_NAME (NODE)))
> +
> +/* Nonzero iff NODE is a declaration for `main', and we are hosted. */
> +#define DECL_MAIN_P(NODE) (DECL_MAIN_FREESTANDING_P(NODE) && flag_hosted)

I liked in the previous version that you checked the return type of main 
when !flag_hosted, here and in c_missing_noreturn_ok_p.  Let's bring 
that back.

Jason


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-13 21:16             ` Jason Merrill
@ 2022-10-14 10:04               ` Arsen Arsenović
  2022-10-14 15:17                 ` Jason Merrill
  2022-10-21 10:33                 ` Ping (c,c++): " Arsen Arsenović
  0 siblings, 2 replies; 20+ messages in thread
From: Arsen Arsenović @ 2022-10-14 10:04 UTC (permalink / raw)
  To: Jonathan Wakely, gcc-patches
  Cc: gcc, Jakub Jelinek, Joseph S. Myers, Jason Merrill


[-- Attachment #1.1: Type: text/plain, Size: 324 bytes --]

On Thursday, 13 October 2022 23:16:02 CEST Jason Merrill wrote:
> I liked in the previous version that you checked the return type of
> main when !flag_hosted, here and in c_missing_noreturn_ok_p.  Let's
> bring that back.
Ah, right; I forgot about that.  What do you think of this?  

Thanks,
-- 
Arsen Arsenović

[-- Attachment #1.2: v4-0001-c-family-Implicitly-return-zero-from-main-even-on.patch --]
[-- Type: text/x-patch, Size: 7528 bytes --]

From dfc1677d1dcfa1b3b963fca8ea5eb8878c4e63d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= <arsen@aarsen.me>
Date: Thu, 13 Oct 2022 21:46:30 +0200
Subject: [PATCH v4] c-family: Implicitly return zero from main even on
 freestanding

... unless marked noreturn.

This should not get in anyone's way, but should permit the use of main()
in freestanding more easily, especially for writing test cases that
should work both in freestanding and hosted modes.

gcc/c/ChangeLog:

	* c-decl.cc (finish_function): Ignore hosted when deciding
	whether to implicitly return zero, but check noreturn.
	* c-objc-common.cc (c_missing_noreturn_ok_p): Loosen the
	requirements to just MAIN_NAME_P when hosted, or `int main'
	otherwise.

gcc/cp/ChangeLog:

	* cp-tree.h (DECL_MAIN_P): Move most logic, besides the hosted
	check, from here...
	(DECL_MAIN_ANY_P): ... to here, so that it can be reused ...
	(DECL_MAIN_FREESTANDING_P): ... here, with an additional
	constraint on (hosted OR return type == int)
	* decl.cc (finish_function): Use DECL_MAIN_FREESTANDING_P
	instead of DECL_MAIN_P, to loosen the hosted requirement, but
	check noreturn, before adding implicit returns.

gcc/testsuite/ChangeLog:

	* gcc.dg/noreturn-4.c: Removed.
	* g++.dg/freestanding-main.C: New test.
	* g++.dg/freestanding-nonint-main.C: New test.
	* gcc.dg/freestanding-main.c: New test.
	* gcc.dg/freestanding-nonint-main.c: New test.
---
 gcc/c/c-decl.cc                                 |  2 +-
 gcc/c/c-objc-common.cc                          |  9 ++++++---
 gcc/cp/cp-tree.h                                | 15 ++++++++++++---
 gcc/cp/decl.cc                                  |  3 ++-
 gcc/testsuite/g++.dg/freestanding-main.C        |  5 +++++
 gcc/testsuite/g++.dg/freestanding-nonint-main.C |  5 +++++
 gcc/testsuite/gcc.dg/freestanding-main.c        |  5 +++++
 gcc/testsuite/gcc.dg/freestanding-nonint-main.c |  5 +++++
 gcc/testsuite/gcc.dg/noreturn-4.c               | 10 ----------
 9 files changed, 41 insertions(+), 18 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/freestanding-main.C
 create mode 100644 gcc/testsuite/g++.dg/freestanding-nonint-main.C
 create mode 100644 gcc/testsuite/gcc.dg/freestanding-main.c
 create mode 100644 gcc/testsuite/gcc.dg/freestanding-nonint-main.c
 delete mode 100644 gcc/testsuite/gcc.dg/noreturn-4.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 193e268f04e..8c655590558 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -10442,7 +10442,7 @@ finish_function (location_t end_loc)
   if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
     DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
 
-  if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted
+  if (MAIN_NAME_P (DECL_NAME (fndecl)) && !TREE_THIS_VOLATILE (fndecl)
       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl)))
       == integer_type_node && flag_isoc99)
     {
diff --git a/gcc/c/c-objc-common.cc b/gcc/c/c-objc-common.cc
index 70e10a98e33..b4680912547 100644
--- a/gcc/c/c-objc-common.cc
+++ b/gcc/c/c-objc-common.cc
@@ -37,9 +37,12 @@ static bool c_tree_printer (pretty_printer *, text_info *, const char *,
 bool
 c_missing_noreturn_ok_p (tree decl)
 {
-  /* A missing noreturn is not ok for freestanding implementations and
-     ok for the `main' function in hosted implementations.  */
-  return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
+  /* A missing noreturn is ok for the `main' function.  */
+  if (!MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl)))
+    return false;
+
+  return flag_hosted
+    || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == integer_type_node;
 }
 
 /* Called from check_global_declaration.  */
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3b67be651b9..33529fa8093 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -772,11 +772,20 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
 
 /* Returns nonzero iff NODE is a declaration for the global function
    `main'.  */
-#define DECL_MAIN_P(NODE)				\
+#define DECL_MAIN_ANY_P(NODE)				\
    (DECL_EXTERN_C_FUNCTION_P (NODE)			\
     && DECL_NAME (NODE) != NULL_TREE			\
-    && MAIN_NAME_P (DECL_NAME (NODE))			\
-    && flag_hosted)
+    && MAIN_NAME_P (DECL_NAME (NODE)))
+
+/* Nonzero iff NODE is a declaration for `int main', or we are hosted. */
+#define DECL_MAIN_FREESTANDING_P(NODE)				\
+  (DECL_MAIN_ANY_P(NODE)					\
+   && (flag_hosted						\
+       || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (NODE)))	\
+          == integer_type_node))
+
+/* Nonzero iff NODE is a declaration for `main', and we are hosted. */
+#define DECL_MAIN_P(NODE) (DECL_MAIN_ANY_P(NODE) && flag_hosted)
 
 /* Lookup walker marking.  */
 #define LOOKUP_SEEN_P(NODE) TREE_VISITED (NODE)
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 82eb0c2f22a..cfc8cd5afd7 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17854,7 +17854,8 @@ finish_function (bool inline_p)
   if (!DECL_CLONED_FUNCTION_P (fndecl))
     {
       /* Make it so that `main' always returns 0 by default.  */
-      if (DECL_MAIN_P (current_function_decl))
+      if (DECL_MAIN_FREESTANDING_P (current_function_decl)
+	  && !TREE_THIS_VOLATILE (current_function_decl))
 	finish_return_stmt (integer_zero_node);
 
       if (use_eh_spec_block (current_function_decl))
diff --git a/gcc/testsuite/g++.dg/freestanding-main.C b/gcc/testsuite/g++.dg/freestanding-main.C
new file mode 100644
index 00000000000..3718cc4508e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/freestanding-main.C
@@ -0,0 +1,5 @@
+/* Make sure we don't get a missing return warning on freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-ffreestanding -Wreturn-type" } */
+
+int main() {}
diff --git a/gcc/testsuite/g++.dg/freestanding-nonint-main.C b/gcc/testsuite/g++.dg/freestanding-nonint-main.C
new file mode 100644
index 00000000000..a8571cc6f0b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/freestanding-nonint-main.C
@@ -0,0 +1,5 @@
+/* Check that we get the right warning for nonint main in freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-ffreestanding -Wreturn-type" } */
+
+const char *main() {} /* { dg-warning "-Wreturn-type" } */
diff --git a/gcc/testsuite/gcc.dg/freestanding-main.c b/gcc/testsuite/gcc.dg/freestanding-main.c
new file mode 100644
index 00000000000..3718cc4508e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/freestanding-main.c
@@ -0,0 +1,5 @@
+/* Make sure we don't get a missing return warning on freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-ffreestanding -Wreturn-type" } */
+
+int main() {}
diff --git a/gcc/testsuite/gcc.dg/freestanding-nonint-main.c b/gcc/testsuite/gcc.dg/freestanding-nonint-main.c
new file mode 100644
index 00000000000..d8393346b09
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/freestanding-nonint-main.c
@@ -0,0 +1,5 @@
+/* Check that we get the right warning for nonint main in freestanding. */
+/* { dg-do compile } */
+/* { dg-options "-ffreestanding -Wreturn-type" } */
+
+const char *main(void) {} /* { dg-warning "-Wreturn-type" } */
diff --git a/gcc/testsuite/gcc.dg/noreturn-4.c b/gcc/testsuite/gcc.dg/noreturn-4.c
deleted file mode 100644
index 6fe144754d0..00000000000
--- a/gcc/testsuite/gcc.dg/noreturn-4.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* Check for "noreturn" warning in main. */
-/* { dg-do compile } */
-/* { dg-options "-O2 -Wmissing-noreturn -ffreestanding" } */
-extern void exit (int) __attribute__ ((__noreturn__));
-
-int
-main (void) /* { dg-warning "function might be candidate for attribute 'noreturn'" "warn for main" } */
-{
-  exit (0);
-}
-- 
2.38.0


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Handling of main() function for freestanding
  2022-10-14 10:04               ` Arsen Arsenović
@ 2022-10-14 15:17                 ` Jason Merrill
  2022-10-21 10:33                 ` Ping (c,c++): " Arsen Arsenović
  1 sibling, 0 replies; 20+ messages in thread
From: Jason Merrill @ 2022-10-14 15:17 UTC (permalink / raw)
  To: Arsen Arsenović, Jonathan Wakely, gcc-patches
  Cc: gcc, Jakub Jelinek, Joseph S. Myers, Marek Polacek

On 10/14/22 06:04, Arsen Arsenović wrote:
> On Thursday, 13 October 2022 23:16:02 CEST Jason Merrill wrote:
>> I liked in the previous version that you checked the return type of
>> main when !flag_hosted, here and in c_missing_noreturn_ok_p.  Let's
>> bring that back.
> Ah, right; I forgot about that.  What do you think of this?

Looks good to me, but a C maintainer should also approve it.

Jason


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Ping (c,c++): Handling of main() function for freestanding
  2022-10-14 10:04               ` Arsen Arsenović
  2022-10-14 15:17                 ` Jason Merrill
@ 2022-10-21 10:33                 ` Arsen Arsenović
  2022-10-21 21:02                   ` Joseph Myers
  1 sibling, 1 reply; 20+ messages in thread
From: Arsen Arsenović @ 2022-10-21 10:33 UTC (permalink / raw)
  To: gcc-patches
  Cc: Jonathan Wakely, Jakub Jelinek, gcc, Joseph S. Myers,
	Arsen Arsenović

[-- Attachment #1: Type: text/plain, Size: 378 bytes --]

Ping on this patch.

https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603574.html

For context, see the rest of this thread.  TL;DR is that `int main' 
should implicitly return 0 on freestanding, without the other burdens of 
main (hosted should remain unchanged, as well as non-int `main's).  This 
applies to both the C and C++ frontends.
-- 
Arsen Arsenović

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Ping (c,c++): Handling of main() function for freestanding
  2022-10-21 10:33                 ` Ping (c,c++): " Arsen Arsenović
@ 2022-10-21 21:02                   ` Joseph Myers
  2022-10-23 11:54                     ` Arsen Arsenović
  0 siblings, 1 reply; 20+ messages in thread
From: Joseph Myers @ 2022-10-21 21:02 UTC (permalink / raw)
  To: Arsen Arsenović; +Cc: gcc-patches, Jakub Jelinek, gcc

[-- Attachment #1: Type: text/plain, Size: 501 bytes --]

On Fri, 21 Oct 2022, Arsen Arsenović via Gcc wrote:

> Ping on this patch.
> 
> https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603574.html
> 
> For context, see the rest of this thread.  TL;DR is that `int main' 
> should implicitly return 0 on freestanding, without the other burdens of 
> main (hosted should remain unchanged, as well as non-int `main's).  This 
> applies to both the C and C++ frontends.

I have no objections to the C changes.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Ping (c,c++): Handling of main() function for freestanding
  2022-10-21 21:02                   ` Joseph Myers
@ 2022-10-23 11:54                     ` Arsen Arsenović
  2022-10-24 13:46                       ` Jason Merrill
  0 siblings, 1 reply; 20+ messages in thread
From: Arsen Arsenović @ 2022-10-23 11:54 UTC (permalink / raw)
  To: gcc-patches; +Cc: gcc-patches, Jakub Jelinek, gcc, Joseph Myers

[-- Attachment #1: Type: text/plain, Size: 279 bytes --]

On Friday, 21 October 2022 23:02:02 CEST Joseph Myers wrote:
> I have no objections to the C changes.

Great!  Thanks for the review.  I don't have push rights currently, so I 
must ask that someone else pushes this patch for me.

Have a great day!
-- 
Arsen Arsenović

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 358 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Ping (c,c++): Handling of main() function for freestanding
  2022-10-23 11:54                     ` Arsen Arsenović
@ 2022-10-24 13:46                       ` Jason Merrill
  0 siblings, 0 replies; 20+ messages in thread
From: Jason Merrill @ 2022-10-24 13:46 UTC (permalink / raw)
  To: Arsen Arsenović, gcc-patches; +Cc: Jakub Jelinek, gcc, Joseph Myers

On 10/23/22 07:54, Arsen Arsenović via Gcc-patches wrote:
> On Friday, 21 October 2022 23:02:02 CEST Joseph Myers wrote:
>> I have no objections to the C changes.
> 
> Great!  Thanks for the review.  I don't have push rights currently, so I
> must ask that someone else pushes this patch for me.
> 
> Have a great day!

Done, thanks.

Jason


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-10-24 13:46 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-28 20:15 Handling of main() function for freestanding Jonathan Wakely
2022-09-29  6:00 ` Richard Biener
2022-09-29  7:12   ` Jakub Jelinek
2022-09-29  9:21     ` Jonathan Wakely
2022-10-04 22:25 ` Jason Merrill
2022-10-07 11:30   ` Jonathan Wakely
2022-10-07 13:51     ` Jason Merrill
2022-10-07 13:53       ` Jakub Jelinek
2022-10-13 17:03       ` Arsen Arsenović
2022-10-13 17:10         ` Jakub Jelinek
2022-10-13 17:26           ` Arsen Arsenović
2022-10-13 17:24         ` Jason Merrill
2022-10-13 20:14           ` Arsen Arsenović
2022-10-13 21:16             ` Jason Merrill
2022-10-14 10:04               ` Arsen Arsenović
2022-10-14 15:17                 ` Jason Merrill
2022-10-21 10:33                 ` Ping (c,c++): " Arsen Arsenović
2022-10-21 21:02                   ` Joseph Myers
2022-10-23 11:54                     ` Arsen Arsenović
2022-10-24 13:46                       ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).