This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for convert_for_assignment pedwarns and inlining


This patch makes convert_for_assignment generate warnings rather than
pedwarns for some implicit conversions arising through inlining.
(Ideally, inlining would not cause any such diagnostics at all; a
separate pass would have checked calls to unprototyped functions
against their definitions before passing the translation units to the
middle-end.)

This patch improves things, but there are still some bugs and
deficiencies in this area which I hope to fix:

* Where there are impossible conversions such as between a structure
  and an integer in the conversion of arguments to an unprototyped
  function being inlined, either the inlining should be disabled
  (leaving whatever form of runtime undefined behavior) or an abort
  should be generated after the evaluation of the expressions for the
  arguments and the called function.  Impossible conversions may
  include non-lvalue arrays in C90.  A warning, but not an error, is
  appropriate.

* These warnings are missing when first the unprototyped definition
  appears, then a call, then the prototype (though the prototype after
  unprototyped definition does get a warning);
  c_convert_parm_for_inlining wrongly assumes the conversion has been
  done in this case.

* As a corollary of that wrong assumption, ICEs can be triggered; for
  example,

    struct s { int a; };
    void f(x) int x; {}
    void g(struct s x) { f(x); }
    void f(int x);

  yields an ICE at -O3.

* Proper diagnosis of bad unprototyped function calls independent of
  where the definition and call are, independent of optimisation,
  would be a longer-term task (bug 14030) which I have no immediate
  plans to do anything on.  Optimisation might still show up more
  opportunities for warnings where the expression called wasn't
  originally simply the name of a function, but the cases likely to be
  encountered should be done independently of optimisation.

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-08  Joseph S. Myers  <jsm@polyomino.org.uk>

	* c-typeck.c (enum impl_conv): Add ic_argpass_nonproto.
	(convert_for_assignment): Handle ic_argpass_nonproto.  Add
	comments about its relevance to errors.
	(c_convert_parm_for_inlining): Use ic_argpass_nonproto.

testsuite:
2004-10-08  Joseph S. Myers  <jsm@polyomino.org.uk>

	* gcc.dg/assign-warn-3.c: New test.

diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2004-10-08 10:17:37.000000000 +0000
+++ GCC/gcc/c-typeck.c	2004-10-08 13:31:34.000000000 +0000
@@ -59,6 +59,7 @@ enum lvalue_use {
    diagnostic messages in convert_for_assignment.  */
 enum impl_conv {
   ic_argpass,
+  ic_argpass_nonproto,
   ic_assign,
   ic_init,
   ic_return
@@ -3435,7 +3436,7 @@ convert_for_assignment (tree type, tree 
   enum tree_code coder;
   tree rname = NULL_TREE;
 
-  if (errtype == ic_argpass)
+  if (errtype == ic_argpass || errtype == ic_argpass_nonproto)
     {
       tree selector;
       /* Change pointer to function to the function itself for
@@ -3464,6 +3465,9 @@ convert_for_assignment (tree type, tree 
       case ic_argpass:				\
 	pedwarn (AR, parmnum, rname);		\
 	break;					\
+      case ic_argpass_nonproto:			\
+	warning (AR, parmnum, rname);		\
+	break;					\
       case ic_assign:				\
 	pedwarn (AS);				\
 	break;					\
@@ -3509,6 +3513,11 @@ convert_for_assignment (tree type, tree 
 
   if (coder == VOID_TYPE)
     {
+      /* Except for passing an argument to an unprototyped function,
+	 this is a constraint violation.  When passing an argument to
+	 an unprototyped function, it is compile-time undefined;
+	 making it a constraint in that case was rejected in
+	 DR#252.  */
       error ("void value not ignored as it ought to be");
       return error_mark_node;
     }
@@ -3554,7 +3563,7 @@ convert_for_assignment (tree type, tree 
   /* Conversion to a transparent union from its member types.
      This applies only to function arguments.  */
   else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
-	   && errtype == ic_argpass)
+	   && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
     {
       tree memb_types;
       tree marginal_memb_type = 0;
@@ -3760,6 +3769,8 @@ convert_for_assignment (tree type, tree 
     }
   else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)
     {
+      /* ??? This should not be an error when inlining calls to
+	 unprototyped functions.  */
       error ("invalid use of non-lvalue array");
       return error_mark_node;
     }
@@ -3803,6 +3814,9 @@ convert_for_assignment (tree type, tree 
   switch (errtype)
     {
     case ic_argpass:
+    case ic_argpass_nonproto:
+      /* ??? This should not be an error when inlining calls to
+	 unprototyped functions.  */
       error ("incompatible type for argument %d of %qE", parmnum, rname);
       break;
     case ic_assign:
@@ -3837,7 +3851,7 @@ c_convert_parm_for_inlining (tree parm, 
 
   type = TREE_TYPE (parm);
   ret = convert_for_assignment (type, value,
-				ic_argpass, fn,
+				ic_argpass_nonproto, fn,
 				fn, argnum);
   if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
       && INTEGRAL_TYPE_P (type)
diff -rupN GCC.orig/gcc/testsuite/gcc.dg/assign-warn-3.c GCC/gcc/testsuite/gcc.dg/assign-warn-3.c
--- GCC.orig/gcc/testsuite/gcc.dg/assign-warn-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.dg/assign-warn-3.c	2004-10-08 13:44:56.000000000 +0000
@@ -0,0 +1,13 @@
+/* Test diagnostics for bad type conversion when inlining unprototyped
+   functions: should not be errors with -pedantic-errors.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "-O3 -std=c99 -pedantic-errors" } */
+
+/* This is valid to execute, so maybe shouldn't warn at all.  */
+void f0(x) signed char *x; { }
+void g0(unsigned char *x) { f0(x); } /* { dg-warning "warning: pointer targets in passing argument 1 of 'f0' differ in signedness" } */
+
+/* This is undefined on execution but still must compile.  */
+void f1(x) int *x; { }
+void g1(unsigned int *x) { f1(x); } /* { dg-warning "warning: pointer targets in passing argument 1 of 'f1' differ in signedness" } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]