c: C2x removal of unprototyped functions
authorJoseph Myers <joseph@codesourcery.com>
Thu, 1 Sep 2022 19:10:59 +0000 (19:10 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Thu, 1 Sep 2022 19:10:59 +0000 (19:10 +0000)
C2x has completely removed unprototyped functions, so that () now
means the same as (void) in both function declarations and
definitions, where previously that change had been made for
definitions only.  Implement this accordingly.

This is a change where GNU/Linux distribution builders might wish to
try builds with a -std=gnu2x default to start early on getting old
code fixed that still has () declarations for functions taking
arguments, in advance of GCC moving to -std=gnu2x as default maybe in
GCC 14 or 15; I don't know how much such code is likely to be in
current use.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

gcc/c/
* c-decl.cc (grokparms): Handle () in a function declaration the
same as (void) for C2X.

gcc/testsuite/
* gcc.dg/c11-unproto-3.c, gcc.dg/c2x-unproto-3.c,
gcc.dg/c2x-unproto-4.c: New tests.
* gcc.dg/c2x-old-style-definition-6.c, gcc.dg/c2x-unproto-1.c,
gcc.dg/c2x-unproto-2.c: Update for removal of unprototyped
functions.

gcc/c/c-decl.cc
gcc/testsuite/gcc.dg/c11-unproto-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-old-style-definition-6.c
gcc/testsuite/gcc.dg/c2x-unproto-1.c
gcc/testsuite/gcc.dg/c2x-unproto-2.c
gcc/testsuite/gcc.dg/c2x-unproto-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-unproto-4.c [new file with mode: 0644]

index 804314d..34f8fed 100644 (file)
@@ -7868,7 +7868,7 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
       error ("%<[*]%> not allowed in other than function prototype scope");
     }
 
-  if (arg_types == NULL_TREE && !funcdef_flag
+  if (arg_types == NULL_TREE && !funcdef_flag && !flag_isoc2x
       && !in_system_header_at (input_location))
     warning (OPT_Wstrict_prototypes,
             "function declaration isn%'t a prototype");
@@ -7896,9 +7896,8 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
       tree parm, type, typelt;
       unsigned int parmno;
 
-      /* In C2X, convert () in a function definition to (void).  */
+      /* In C2X, convert () to (void).  */
       if (flag_isoc2x
-         && funcdef_flag
          && !arg_types
          && !arg_info->parms)
        arg_types = arg_info->types = void_list_node;
diff --git a/gcc/testsuite/gcc.dg/c11-unproto-3.c b/gcc/testsuite/gcc.dg/c11-unproto-3.c
new file mode 100644 (file)
index 0000000..b0e4bf3
--- /dev/null
@@ -0,0 +1,19 @@
+/* Test function declarations without prototypes for C11.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+void f1 ();
+void
+f1a (void)
+{
+  f1 (1, 2);
+}
+
+void f2 ();
+void f2 (int);
+
+void f3 ();
+
+_Static_assert (_Generic (f3,
+                         void (*) (int) : 1,
+                         default : 3) == 1, "unprototyped test");
index fc0e778..72bfd56 100644 (file)
@@ -1,16 +1,16 @@
-/* Test old-style function definitions not in C2x: () does not give
-   type with a prototype except for function definitions.  */
+/* Test old-style function definitions not in C2x: () gives a type with
+   a prototype for all declarations.  */
 /* { dg-do compile } */
 /* { dg-options "-std=c2x" } */
 
-void f1 ();
+void f1 (); /* { dg-message "declared here" } */
 
-/* Prototyped function returning a pointer to unprototyped function.  */
+/* Prototyped function returning a pointer to a function with no arguments.  */
 void (*f2 (void))() { return f1; }
 
 void
 g (void)
 {
-  f1 (1);
-  f2 () (1);
+  f1 (1); /* { dg-error "too many arguments" } */
+  f2 () (1); /* { dg-error "too many arguments" } */
 }
index aa87d78..d21c6a7 100644 (file)
@@ -1,25 +1,21 @@
-/* Test compatibility of unprototyped and prototyped function types (C2x made
-   the case of types affected by default argument promotions compatible, before
-   removing unprototyped functions completely).  Test affected usages are not
-   accepted for C2x.  */
+/* Test compatibility of prototyped function types with and without arguments
+   (C2x made the case of types affected by default argument promotions
+   compatible, before removing unprototyped functions completely).  Test
+   affected usages are not accepted for C2x.  */
 /* { dg-do compile } */
 /* { dg-options "-std=c2x -pedantic-errors" } */
 
 void f1 (); /* { dg-message "previous declaration" } */
 void f1 (float); /* { dg-error "conflicting types" } */
-/* { dg-message "default promotion" "" { target *-*-* } .-1 } */
 
 void f2 (float); /* { dg-message "previous declaration" } */
 void f2 (); /* { dg-error "conflicting types" } */
-/* { dg-message "default promotion" "" { target *-*-* } .-1 } */
 
 void f3 (); /* { dg-message "previous declaration" } */
 void f3 (char); /* { dg-error "conflicting types" } */
-/* { dg-message "default promotion" "" { target *-*-* } .-1 } */
 
 void f4 (char); /* { dg-message "previous declaration" } */
 void f4 (); /* { dg-error "conflicting types" } */
-/* { dg-message "default promotion" "" { target *-*-* } .-1 } */
 
 /* Built-in function case.  */
 float sqrtf (); /* { dg-warning "conflicting types for built-in function" } */
index 3d5ae9d..533fb74 100644 (file)
@@ -1,22 +1,18 @@
-/* Test compatibility of unprototyped and prototyped function types (C2x made
-   the case of types affected by default argument promotions compatible, before
-   removing unprototyped functions completely).  Test always-invalid-in-C2x
-   usages, in C2X mode.  */
+/* Test compatibility of prototyped function types without arguments and with
+   variable arguments (C2x made the case of types affected by default argument
+   promotions compatible, before removing unprototyped functions completely).
+   Test always-invalid-in-C2x usages, in C2X mode.  */
 /* { dg-do compile } */
 /* { dg-options "-std=c2x -pedantic-errors" } */
 
 void f1 (); /* { dg-message "previous declaration" } */
 void f1 (int, ...); /* { dg-error "conflicting types" } */
-/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */
 
 void f2 (int, ...); /* { dg-message "previous declaration" } */
 void f2 (); /* { dg-error "conflicting types" } */
-/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */
 
 void f3 (); /* { dg-message "previous declaration" } */
 void f3 (char, ...); /* { dg-error "conflicting types" } */
-/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */
 
 void f4 (char, ...); /* { dg-message "previous declaration" } */
 void f4 (); /* { dg-error "conflicting types" } */
-/* { dg-message "ellipsis" "" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/c2x-unproto-3.c b/gcc/testsuite/gcc.dg/c2x-unproto-3.c
new file mode 100644 (file)
index 0000000..762f8b2
--- /dev/null
@@ -0,0 +1,20 @@
+/* Test that declaring a function with () is the same as (void) in C2X.  Valid
+   use cases.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wstrict-prototypes" } */
+
+void f1 ();
+void f1 (void);
+
+void f2 (void);
+void f2 ();
+
+typedef void T1 ();
+typedef void T1 (void);
+
+void f3 ();
+
+_Static_assert (_Generic (f3,
+                         void (*) (int) : 1,
+                         void (*) (void) : 2,
+                         default : 3) == 2);
diff --git a/gcc/testsuite/gcc.dg/c2x-unproto-4.c b/gcc/testsuite/gcc.dg/c2x-unproto-4.c
new file mode 100644 (file)
index 0000000..fceff22
--- /dev/null
@@ -0,0 +1,15 @@
+/* Test that declaring a function with () is the same as (void) in C2X.
+   Invalid use cases.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+void f1 (); /* { dg-message "previous declaration" } */
+void f1 (int); /* { dg-error "conflicting types" } */
+
+void f2 (); /* { dg-message "declared here" } */
+
+void
+f3 (void)
+{
+  f2 (1); /* { dg-error "too many arguments" } */
+}