* Re: Handling of main() function for freestanding [not found] ` <2489d88a-e80b-2f89-bac5-07c0b70bc175@redhat.com> @ 2022-10-13 17:03 ` Arsen Arsenović 2022-10-13 17:10 ` Jakub Jelinek 2022-10-13 17:24 ` Jason Merrill 0 siblings, 2 replies; 12+ 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] 12+ messages in thread
* Re: Handling of main() function for freestanding 2022-10-13 17:03 ` Handling of main() function for freestanding 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; 12+ 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] 12+ 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; 12+ 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] 12+ messages in thread
* Re: Handling of main() function for freestanding 2022-10-13 17:03 ` Handling of main() function for freestanding 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ 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; 12+ 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] 12+ messages in thread
end of thread, other threads:[~2022-10-24 13:46 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <CAH6eHdRr2uYW=Q8BKvhx472LXkT+nCKQg4uYAETNCs+b=YY7GA@mail.gmail.com> [not found] ` <CAH6eHdSWbgYy2qaneHyeEMAVLhkgZGjjtoRO4D5Dy5HOfmP95Q@mail.gmail.com> [not found] ` <2489d88a-e80b-2f89-bac5-07c0b70bc175@redhat.com> 2022-10-13 17:03 ` Handling of main() function for freestanding 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).