* c-typeck.c (convert_arguments): Take expression for called
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Oct 2004 22:16:29 +0000 (22:16 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Oct 2004 22:16:29 +0000 (22:16 +0000)
function rather than its name.  Handle ObjC selectors directly
rather than relying on warn_for_assignment to do so.  Call warning
directly rather than warn_for_assignment.  Use %qE in diagnostics.
Say "argument" rather than "arg" in diagnostics.
(build_function_call): Update call to convert_arguments.

testsuite:
* gcc.dg/Wconversion-2.c, gcc.dg/func-args-1.c: New tests.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@88630 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wconversion-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/func-args-1.c [new file with mode: 0644]

index 6ed9e99..d05f93d 100644 (file)
@@ -1,3 +1,12 @@
+2004-10-06  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+       * c-typeck.c (convert_arguments): Take expression for called
+       function rather than its name.  Handle ObjC selectors directly
+       rather than relying on warn_for_assignment to do so.  Call warning
+       directly rather than warn_for_assignment.  Use %qE in diagnostics.
+       Say "argument" rather than "arg" in diagnostics.
+       (build_function_call): Update call to convert_arguments.
+
 2004-10-06  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR debug/17787
index 27c8cd4..6d77233 100644 (file)
@@ -1976,7 +1976,7 @@ build_function_call (tree function, tree params)
      function prototype, or apply default promotions.  */
 
   coerced_params
-    = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
+    = convert_arguments (TYPE_ARG_TYPES (fntype), params, function, fundecl);
 
   /* Check that the arguments to the function are valid.  */
 
@@ -2014,7 +2014,8 @@ build_function_call (tree function, tree params)
    It may be 0, if that info is not available.
    It is used only for generating error messages.
 
-   NAME is an IDENTIFIER_NODE or 0.  It is used only for error messages.
+   FUNCTION is a tree for the called function.  It is used only for
+   error messages, where it is formatted with %qE.
 
    This is also where warnings about wrong number of args are generated.
 
@@ -2022,11 +2023,25 @@ build_function_call (tree function, tree params)
    with the elements of the list in the TREE_VALUE slots of those nodes.  */
 
 static tree
-convert_arguments (tree typelist, tree values, tree name, tree fundecl)
+convert_arguments (tree typelist, tree values, tree function, tree fundecl)
 {
   tree typetail, valtail;
   tree result = NULL;
   int parmnum;
+  tree selector;
+  tree name = NULL_TREE;
+
+  /* Determine the function name for the use of convert_for_assignment
+     and warn_for_assignment called from there.  */
+  if (TREE_CODE (function) == ADDR_EXPR
+      && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
+    {
+      function = TREE_OPERAND (function, 0);
+      name = DECL_NAME (function);
+    }
+
+  /* Handle an ObjC selector specially for diagnostics.  */
+  selector = objc_message_selector ();
 
   /* Scan the given expressions and types, producing individual
      converted arguments and pushing them on RESULT in reverse order.  */
@@ -2037,17 +2052,21 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
     {
       tree type = typetail ? TREE_VALUE (typetail) : 0;
       tree val = TREE_VALUE (valtail);
+      tree rname = function;
+      int argnum = parmnum + 1;
 
       if (type == void_type_node)
        {
-         if (name)
-           error ("too many arguments to function %qs",
-                  IDENTIFIER_POINTER (name));
-         else
-           error ("too many arguments to function");
+         error ("too many arguments to function %qE", function);
          break;
        }
 
+      if (selector && argnum > 2)
+       {
+         rname = selector;
+         argnum -= 2;
+       }
+
       /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
       /* Do not use STRIP_NOPS here!  We do not want an enumerator with value 0
         to convert automatically to a pointer.  */
@@ -2078,22 +2097,34 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
 
                  if (INTEGRAL_TYPE_P (type)
                      && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
-                   warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
+                   warning ("passing argument %d of %qE as integer "
+                            "rather than floating due to prototype",
+                            argnum, rname);
                  if (INTEGRAL_TYPE_P (type)
                      && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
-                   warn_for_assignment ("%s as integer rather than complex due to prototype", (char *) 0, name, parmnum + 1);
+                   warning ("passing argument %d of %qE as integer "
+                            "rather than complex due to prototype",
+                            argnum, rname);
                  else if (TREE_CODE (type) == COMPLEX_TYPE
                           && TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
-                   warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
+                   warning ("passing argument %d of %qE as complex "
+                            "rather than floating due to prototype",
+                            argnum, rname);
                  else if (TREE_CODE (type) == REAL_TYPE
                           && INTEGRAL_TYPE_P (TREE_TYPE (val)))
-                   warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
+                   warning ("passing argument %d of %qE as floating "
+                            "rather than integer due to prototype",
+                            argnum, rname);
                  else if (TREE_CODE (type) == COMPLEX_TYPE
                           && INTEGRAL_TYPE_P (TREE_TYPE (val)))
-                   warn_for_assignment ("%s as complex rather than integer due to prototype", (char *) 0, name, parmnum + 1);
+                   warning ("passing argument %d of %qE as complex "
+                            "rather than integer due to prototype",
+                            argnum, rname);
                  else if (TREE_CODE (type) == REAL_TYPE
                           && TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
-                   warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
+                   warning ("passing argument %d of %qE as floating "
+                            "rather than complex due to prototype",
+                            argnum, rname);
                  /* ??? At some point, messages should be written about
                     conversions between complex types, but that's too messy
                     to do now.  */
@@ -2103,9 +2134,9 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
                      /* Warn if any argument is passed as `float',
                         since without a prototype it would be `double'.  */
                      if (formal_prec == TYPE_PRECISION (float_type_node))
-                       warn_for_assignment ("%s as %<float%> rather than "
-                                            "%<double%> due to prototype",
-                                            (char *) 0, name, parmnum + 1);
+                       warning ("passing argument %d of %qE as %<float%> "
+                                "rather than %<double%> due to prototype",
+                                argnum, rname);
                    }
                  /* Detect integer changing in width or signedness.
                     These warnings are only activated with
@@ -2123,7 +2154,8 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
                           and the actual arg is that enum type.  */
                        ;
                      else if (formal_prec != TYPE_PRECISION (type1))
-                       warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1);
+                       warning ("passing argument %d of %qE with different "
+                                "width due to prototype", argnum, rname);
                      else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
                        ;
                      /* Don't complain if the formal parameter type
@@ -2149,9 +2181,11 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
                               && TYPE_UNSIGNED (TREE_TYPE (val)))
                        ;
                      else if (TYPE_UNSIGNED (type))
-                       warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
+                       warning ("passing argument %d of %qE as unsigned "
+                                "due to prototype", argnum, rname);
                      else
-                       warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
+                       warning ("passing argument %d of %qE as signed "
+                                "due to prototype", argnum, rname);
                    }
                }
 
@@ -2180,13 +2214,7 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
     }
 
   if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
-    {
-      if (name)
-       error ("too few arguments to function %qs",
-              IDENTIFIER_POINTER (name));
-      else
-       error ("too few arguments to function");
-    }
+    error ("too few arguments to function %qE", function);
 
   return nreverse (result);
 }
index 8e23309..b867e20 100644 (file)
@@ -1,3 +1,7 @@
+2004-10-06  Joseph S. Myers  <jsm@polyomino.org.uk>
+
+       * gcc.dg/Wconversion-2.c, gcc.dg/func-args-1.c: New tests.
+
 2004-10-06  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR c++/17368
diff --git a/gcc/testsuite/gcc.dg/Wconversion-2.c b/gcc/testsuite/gcc.dg/Wconversion-2.c
new file mode 100644 (file)
index 0000000..320f41f
--- /dev/null
@@ -0,0 +1,64 @@
+/* Test messages for -Wconversion, including that they are not
+   pedwarns.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors -Wconversion" } */
+
+void fsc(signed char);
+void fsi(signed int);
+void fsll(signed long long);
+void fuc(unsigned char);
+void fui(unsigned int);
+void full(unsigned long long);
+void ff(float);
+void fld(long double);
+void fcf(_Complex float);
+
+struct s {
+  void (*fsc)(signed char);
+  void (*fsi)(signed int);
+  void (*fsll)(signed long long);
+  void (*fuc)(unsigned char);
+  void (*fui)(unsigned int);
+  void (*full)(unsigned long long);
+  void (*ff)(float);
+  void (*fld)(long double);
+  void (*fcf)(_Complex float);
+} x;
+
+signed char sc;
+signed int si;
+signed long long sll;
+unsigned char uc;
+unsigned int ui;
+unsigned long long ull;
+float f;
+long double ld;
+_Complex float cf;
+
+void
+g (void)
+{
+  fsi(f); /* { dg-warning "warning: passing argument 1 of 'fsi' as integer rather than floating due to prototype" } */
+  x.fsi(f); /* { dg-warning "warning: passing argument 1 of 'x.fsi' as integer rather than floating due to prototype" } */
+  fsi(cf); /* { dg-warning "warning: passing argument 1 of 'fsi' as integer rather than complex due to prototype" } */
+  x.fsi(cf); /* { dg-warning "warning: passing argument 1 of 'x.fsi' as integer rather than complex due to prototype" } */
+  fcf(f); /* { dg-warning "warning: passing argument 1 of 'fcf' as complex rather than floating due to prototype" } */
+  x.fcf(f); /* { dg-warning "warning: passing argument 1 of 'x.fcf' as complex rather than floating due to prototype" } */
+  fcf(si); /* { dg-warning "warning: passing argument 1 of 'fcf' as complex rather than integer due to prototype" } */
+  x.fcf(si); /* { dg-warning "warning: passing argument 1 of 'x.fcf' as complex rather than integer due to prototype" } */
+  ff(sc); /* { dg-warning "warning: passing argument 1 of 'ff' as floating rather than integer due to prototype" } */
+  x.ff(sc); /* { dg-warning "warning: passing argument 1 of 'x.ff' as floating rather than integer due to prototype" } */
+  ff(cf); /* { dg-warning "warning: passing argument 1 of 'ff' as floating rather than complex due to prototype" } */
+  x.ff(cf); /* { dg-warning "warning: passing argument 1 of 'x.ff' as floating rather than complex due to prototype" } */
+  ff(1.0); /* { dg-warning "warning: passing argument 1 of 'ff' as 'float' rather than 'double' due to prototype" } */
+  x.ff(1.0); /* { dg-warning "warning: passing argument 1 of 'x.ff' as 'float' rather than 'double' due to prototype" } */
+  fsll(sc); /* { dg-warning "warning: passing argument 1 of 'fsll' with different width due to prototype" } */
+  x.fsll(sc); /* { dg-warning "warning: passing argument 1 of 'x.fsll' with different width due to prototype" } */
+  fsc(sll); /* { dg-warning "warning: passing argument 1 of 'fsc' with different width due to prototype" } */
+  x.fsc(sll); /* { dg-warning "warning: passing argument 1 of 'x.fsc' with different width due to prototype" } */
+  fsi(ui); /* { dg-warning "warning: passing argument 1 of 'fsi' as signed due to prototype" } */
+  x.fsi(ui); /* { dg-warning "warning: passing argument 1 of 'x.fsi' as signed due to prototype" } */
+  full(sll); /* { dg-warning "warning: passing argument 1 of 'full' as unsigned due to prototype" } */
+  x.full(sll); /* { dg-warning "warning: passing argument 1 of 'x.full' as unsigned due to prototype" } */
+}
diff --git a/gcc/testsuite/gcc.dg/func-args-1.c b/gcc/testsuite/gcc.dg/func-args-1.c
new file mode 100644 (file)
index 0000000..306a5df
--- /dev/null
@@ -0,0 +1,53 @@
+/* Test messages for wrong number of arguments to function.  */
+/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void f0(void);
+void f1(int);
+void f1v(int, ...);
+void f2(int, int);
+void f2v(int, int, ...);
+
+struct s {
+  void (*f0)(void);
+  void (*f1)(int);
+  void (*f1v)(int, ...);
+  void (*f2)(int, int);
+  void (*f2v)(int, int, ...);
+} x;
+
+void
+g (int a)
+{
+  f0();
+  x.f0();
+  f0(a); /* { dg-error "error: too many arguments to function 'f0'" } */
+  x.f0(a); /* { dg-error "error: too many arguments to function 'x.f0'" } */
+  f0(a, a); /* { dg-error "error: too many arguments to function 'f0'" } */
+  x.f0(a, a); /* { dg-error "error: too many arguments to function 'x.f0'" } */
+  f1(); /* { dg-error "error: too few arguments to function 'f1'" } */
+  x.f1(); /* { dg-error "error: too few arguments to function 'x.f1'" } */
+  f1(a);
+  x.f1(a);
+  f1(a, a); /* { dg-error "error: too many arguments to function 'f1'" } */
+  x.f1(a, a); /* { dg-error "error: too many arguments to function 'x.f1'" } */
+  f1v(); /* { dg-error "error: too few arguments to function 'f1v'" } */
+  x.f1v(); /* { dg-error "error: too few arguments to function 'x.f1v'" } */
+  f1v(a);
+  x.f1v(a);
+  f1v(a, a);
+  x.f1v(a, a);
+  f2(a); /* { dg-error "error: too few arguments to function 'f2'" } */
+  x.f2(a); /* { dg-error "error: too few arguments to function 'x.f2'" } */
+  f2(a, a);
+  x.f2(a, a);
+  f2(a, a, a); /* { dg-error "error: too many arguments to function 'f2'" } */
+  x.f2(a, a, a); /* { dg-error "error: too many arguments to function 'x.f2'" } */
+  f2v(a); /* { dg-error "error: too few arguments to function 'f2v'" } */
+  x.f2v(a); /* { dg-error "error: too few arguments to function 'x.f2v'" } */
+  f2v(a, a);
+  x.f2v(a, a);
+  f2v(a, a, a);
+  x.f2v(a, a, a);
+}