From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [IPv6:2001:67c:2050:0:465::201]) by sourceware.org (Postfix) with ESMTPS id 030FD3856DD6; Thu, 13 Oct 2022 17:03:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 030FD3856DD6 Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=aarsen.me Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=aarsen.me Received: from smtp202.mailbox.org (smtp202.mailbox.org [IPv6:2001:67c:2050:b231:465::202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4MpG7N6mfXz9sS2; Thu, 13 Oct 2022 19:03:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1665680609; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=OulqMRwWL6TORCBz+Q4RjDtD0sc9mPR3ruZPKuy477E=; b=QfICHMsLF4UlRT27v07r1PNy6po0HNRAe/uDUOTXbjAZm70/OJ+m1SovAFTfhoEx8XQcD3 0YHRT5Zy+j/ZVkAnYLODZjLUVL3chVJtwkagosFJHKkXBhBqvzttcSXXmDTYem7AjCZ7JU fACcqpbINtNyz/bBbDELvdqnetCB4Km7TKu1Ytt1bRGuVhHHS19dVmYoIJYqLLDwolxIAR PIdEMGrTGiaYVhSfV2PBen04I8FalHaLg92qJp7CgOLao13wzaici0mtbOJmrG5jdkVGYs SWC7NTj6uuyRkpWgenikbLcy3nMKwgJ+8XEdZ6Z7VBtIELemeAa3eV81X4mfnQ== From: Arsen =?utf-8?B?QXJzZW5vdmnEhw==?= To: Jonathan Wakely , gcc-patches@gcc.gnu.org Cc: "gcc@gcc.gnu.org" , Jakub Jelinek , "Joseph S. Myers" , Jason Merrill Subject: Re: Handling of main() function for freestanding Date: Thu, 13 Oct 2022 19:03:24 +0200 Message-ID: <16718001.dR7co8bJll@bstg> In-Reply-To: <2489d88a-e80b-2f89-bac5-07c0b70bc175@redhat.com> References: <2489d88a-e80b-2f89-bac5-07c0b70bc175@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart5489017.aVk9u90zge"; micalg="pgp-sha512"; protocol="application/pgp-signature" X-Rspamd-Queue-Id: 4MpG7N6mfXz9sS2 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_INFOUSMEBIZ,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --nextPart5489017.aVk9u90zge Content-Type: multipart/mixed; boundary="nextPart2380794.Ikxl3CHv88"; protected-headers="v1" Content-Transfer-Encoding: 7Bit From: Arsen =?utf-8?B?QXJzZW5vdmnEhw==?= To: Jonathan Wakely , gcc-patches@gcc.gnu.org Subject: Re: Handling of main() function for freestanding Date: Thu, 13 Oct 2022 19:02:56 +0200 Message-ID: <16718001.dR7co8bJll@bstg> In-Reply-To: <2489d88a-e80b-2f89-bac5-07c0b70bc175@redhat.com> MIME-Version: 1.0 This is a multi-part message in MIME format. --nextPart2380794.Ikxl3CHv88 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hi, On Friday, 7 October 2022 15:51:31 CEST Jason Merrill wrote: > > * gcc.dg/noreturn-4.c: Likewise. >=20 > I'd be inclined to drop this test. That seems like an odd choice, why do that over using another function=20 for the test case? (there's nothing specific to main in this test, and=20 it doesn't even need to link, so using any ol' function should be okay;=20 see attachment) The attached patch is also v2 of the original builtin-main one submitted=20 earlier. Tested on x86_64-pc-linux-gnu. This revision excludes the=20 mentioned pedwarns unless hosted. Thanks, =2D-=20 Arsen Arsenovi=C4=87 --nextPart2380794.Ikxl3CHv88 Content-Disposition: attachment; filename="v2-0001-c-family-Implement-new-int-main-semantics-in-free.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="v2-0001-c-family-Implement-new-int-main-semantics-in-free.patch" >From 27a2cf85b1c3eb901413fd135918af0377bd1459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arsen=20Arsenovi=C4=87?= 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 --nextPart2380794.Ikxl3CHv88-- --nextPart5489017.aVk9u90zge Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part. Content-Transfer-Encoding: 7Bit -----BEGIN PGP SIGNATURE----- iNUEABYKAH0WIQT+4rPRE/wAoxYtYGFSwpQwHqLEkwUCY0hEwF8UgAAAAAAuAChp c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0RkVF MkIzRDExM0ZDMDBBMzE2MkQ2MDYxNTJDMjk0MzAxRUEyQzQ5MwAKCRBSwpQwHqLE k250AP9J7Ea0ujXhyWqcdxGtNqc+eF/WEanYrRDrUv4XaRzE3QEAs0+kxWDVzQIg i/zN/JPxN/nhLNHsFH48UJnxDSZU2gg= =FHts -----END PGP SIGNATURE----- --nextPart5489017.aVk9u90zge--