public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: "Arsen Arsenović" <arsen@aarsen.me>
To: Jonathan Wakely <jwakely.gcc@gmail.com>, gcc-patches@gcc.gnu.org
Cc: "gcc@gcc.gnu.org" <gcc@gcc.gnu.org>,
	Jakub Jelinek <jakub@redhat.com>,
	"Joseph S. Myers" <joseph@codesourcery.com>,
	Jason Merrill <jason@redhat.com>
Subject: Re: Handling of main() function for freestanding
Date: Thu, 13 Oct 2022 19:03:24 +0200	[thread overview]
Message-ID: <16718001.dR7co8bJll@bstg> (raw)
In-Reply-To: <2489d88a-e80b-2f89-bac5-07c0b70bc175@redhat.com>


[-- 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 --]

  parent reply	other threads:[~2022-10-13 17:03 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-28 20:15 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-04 23:28   ` Joel Sherrill
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ć [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=16718001.dR7co8bJll@bstg \
    --to=arsen@aarsen.me \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gcc@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jason@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=jwakely.gcc@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).