Patch for bug 16666

Joseph S. Myers joseph@codesourcery.com
Sat Oct 30 12:33:00 GMT 2004


This patch fixes bug 16666, concerning bad errors for old-style
definitions of built-in functions with argument types subject to
default promotions.  A GNU extension permits a prototype to override
the default promotions of argument types on old-style declarations:
this should apply whether or not the function is built in.  However, I
think this should only apply for a visible prototype, not an invisible
one (e.g. a built-in one).

This bug is a regression in 3.4 and 4.0, but given the changes in this
area since 3.4 I only propose to fix it for 4.0; certainly this patch
wouldn't be appropriate for 3.4.

A check for DECL_BUILT_IN before merging a prior prototype into a new
old-style definition may have made sense when the scope of built-in
functions was not properly distinguished from the file scope.  Now,
however, the type of the function in the file scope is exactly the
proper type from visible declarations there and whether the function
is also built-in is irrelevant to merging prototype information.
(That only the visible type is in the DECL is the difference from 3.4
which makes me consider the patch inappropriate for 3.4 branch.)

Notwithstanding the bug dependencies, this patch does not address bug
15698, although I hope to deal with that bug in a future patch by
arranging for the full type in the external scope to be compared
against an old-style definition.

That the diagnostic location for old-style declarations not matching a
prototype is the open brace rather than the line of the relevant
old-style declaration is sub-ideal, but is a pre-existing condition.

Bootstrapped with no regressions on i686-pc-linux-gnu.  Applied to
mainline.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2004-10-30  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/16666
	* c-decl.c (start_function): Don't check for DECL_BUILT_IN when
	determining whether to copy parameter types from a previous
	prototype declaration.

testsuite:
2004-10-30  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/16666
	* gcc.dg/dremf-type-compat-1.c, gcc.dg/dremf-type-compat-2.c,
	gcc.dg/dremf-type-compat-3.c, gcc.dg/dremf-type-compat-4.c,
	gcc.dg/old-style-prom-1.c, gcc.dg/old-style-prom-2.c,
	gcc.dg/old-style-prom-3.c: New tests.

diff -rupN GCC.orig/gcc/c-decl.c GCC/gcc/c-decl.c
--- GCC.orig/gcc/c-decl.c	2004-10-27 19:34:19.000000000 +0000
+++ GCC/gcc/c-decl.c	2004-10-28 23:05:11.000000000 +0000
@@ -5698,11 +5698,9 @@ start_function (struct c_declspecs *decl
   DECL_INITIAL (decl1) = error_mark_node;
 
   /* If this definition isn't a prototype and we had a prototype declaration
-     before, copy the arg type info from that prototype.
-     But not if what we had before was a builtin function.  */
+     before, copy the arg type info from that prototype.  */
   old_decl = lookup_name_in_scope (DECL_NAME (decl1), current_scope);
   if (old_decl != 0 && TREE_CODE (TREE_TYPE (old_decl)) == FUNCTION_TYPE
-      && !DECL_BUILT_IN (old_decl)
       && comptypes (TREE_TYPE (TREE_TYPE (decl1)),
 		    TREE_TYPE (TREE_TYPE (old_decl)))
       && TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-1.c GCC/gcc/testsuite/gcc.dg/dremf-type-compat-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/dremf-type-compat-1.c	2004-10-28 22:53:26.000000000 +0000
@@ -0,0 +1,16 @@
+/* Test for bogus diagnostics for dremf definition.  Although this
+   definition is formally incorrect in ISO C, a GNU extension permits
+   a prototype followed by unpromoted types in a function definition,
+   so it should be permitted when the function is built in.  Bug
+   16666.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+float dremf (float, float);
+
+float
+dremf (x, y)
+     float x, y;
+{
+  return x + y;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-2.c GCC/gcc/testsuite/gcc.dg/dremf-type-compat-2.c
--- GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/dremf-type-compat-2.c	2004-10-29 22:52:59.000000000 +0000
@@ -0,0 +1,18 @@
+/* Test for bogus diagnostics for dremf definition.  Although this
+   definition is formally incorrect in ISO C, a GNU extension permits
+   a prototype followed by unpromoted types in a function definition,
+   so it should be permitted when the function is built in.  Bug
+   16666.  Test with -pedantic, where the problem should still be
+   diagnosed.  */
+/* { dg-do compile } */
+/* { dg-options "-pedantic" } */
+
+float dremf (float, float); /* { dg-warning "warning: prototype declaration" } */
+
+float
+dremf (x, y)
+     float x;
+     float y;
+{ /* { dg-warning "warning: promoted argument '.' doesn't match prototype" } */
+  return x + y;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-3.c GCC/gcc/testsuite/gcc.dg/dremf-type-compat-3.c
--- GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/dremf-type-compat-3.c	2004-10-29 22:53:19.000000000 +0000
@@ -0,0 +1,18 @@
+/* Test for bogus diagnostics for dremf definition.  Although this
+   definition is formally incorrect in ISO C, a GNU extension permits
+   a prototype followed by unpromoted types in a function definition,
+   so it should be permitted when the function is built in.  Bug
+   16666.  Test with -pedantic-errors, where the problem should still
+   be diagnosed.  */
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+float dremf (float, float); /* { dg-error "error: prototype declaration" } */
+
+float
+dremf (x, y)
+     float x;
+     float y;
+{ /* { dg-error "error: promoted argument '.' doesn't match prototype" } */
+  return x + y;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-4.c GCC/gcc/testsuite/gcc.dg/dremf-type-compat-4.c
--- GCC.orig/gcc/testsuite/gcc.dg/dremf-type-compat-4.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/dremf-type-compat-4.c	2004-10-29 23:31:16.000000000 +0000
@@ -0,0 +1,13 @@
+/* Test for bogus diagnostics for dremf definition, as in bug 16666.
+   The GNU extension permitting a prototype to override the promotion
+   of old-style parameter declarations should only apply when the
+   prototype is visible, not for a built-in prototype.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+float
+dremf(x, y)
+     float x, y; /* { dg-warning "warning: conflicting types for built-in function 'dremf'" } */
+{
+  return x + y;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/old-style-prom-1.c GCC/gcc/testsuite/gcc.dg/old-style-prom-1.c
--- GCC.orig/gcc/testsuite/gcc.dg/old-style-prom-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/old-style-prom-1.c	2004-10-28 22:55:30.000000000 +0000
@@ -0,0 +1,13 @@
+/* Test for prototype followed by old-style definition, as in
+   dremf-type-compat-1.c but with a non-built-in function.  */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+float f (float, float);
+
+float
+f (x, y)
+     float x, y;
+{
+  return x + y;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/old-style-prom-2.c GCC/gcc/testsuite/gcc.dg/old-style-prom-2.c
--- GCC.orig/gcc/testsuite/gcc.dg/old-style-prom-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/old-style-prom-2.c	2004-10-29 22:53:44.000000000 +0000
@@ -0,0 +1,14 @@
+/* Test for prototype followed by old-style definition, as in
+   dremf-type-compat-2.c but with a non-built-in function.  */
+/* { dg-do compile } */
+/* { dg-options "-pedantic" } */
+
+float f (float, float); /* { dg-warning "warning: prototype declaration" } */
+
+float
+f (x, y)
+     float x;
+     float y;
+{ /* { dg-warning "warning: promoted argument '.' doesn't match prototype" } */
+  return x + y;
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/old-style-prom-3.c GCC/gcc/testsuite/gcc.dg/old-style-prom-3.c
--- GCC.orig/gcc/testsuite/gcc.dg/old-style-prom-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/old-style-prom-3.c	2004-10-29 22:54:05.000000000 +0000
@@ -0,0 +1,14 @@
+/* Test for prototype followed by old-style definition, as in
+   dremf-type-compat-3.c but with a non-built-in function.  */
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+float f (float, float); /* { dg-error "error: prototype declaration" } */
+
+float
+f (x, y)
+     float x;
+     float y;
+{ /* { dg-error "error: promoted argument '.' doesn't match prototype" } */
+  return x + y;
+}



More information about the Gcc-patches mailing list