Commit 03dafa61 by Joseph Myers Committed by Joseph Myers

c-typeck.c (convert_arguments): Take expression for called function rather than its name.

	* 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.

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

From-SVN: r88630
parent 75917fc0
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> 2004-10-06 Andrew Pinski <pinskia@physics.uc.edu>
PR debug/17787 PR debug/17787
......
...@@ -1976,7 +1976,7 @@ build_function_call (tree function, tree params) ...@@ -1976,7 +1976,7 @@ build_function_call (tree function, tree params)
function prototype, or apply default promotions. */ function prototype, or apply default promotions. */
coerced_params 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. */ /* Check that the arguments to the function are valid. */
...@@ -2014,7 +2014,8 @@ build_function_call (tree function, tree params) ...@@ -2014,7 +2014,8 @@ build_function_call (tree function, tree params)
It may be 0, if that info is not available. It may be 0, if that info is not available.
It is used only for generating error messages. 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. This is also where warnings about wrong number of args are generated.
...@@ -2022,11 +2023,25 @@ build_function_call (tree function, tree params) ...@@ -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. */ with the elements of the list in the TREE_VALUE slots of those nodes. */
static tree 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 typetail, valtail;
tree result = NULL; tree result = NULL;
int parmnum; 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 /* Scan the given expressions and types, producing individual
converted arguments and pushing them on RESULT in reverse order. */ converted arguments and pushing them on RESULT in reverse order. */
...@@ -2037,17 +2052,21 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl) ...@@ -2037,17 +2052,21 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
{ {
tree type = typetail ? TREE_VALUE (typetail) : 0; tree type = typetail ? TREE_VALUE (typetail) : 0;
tree val = TREE_VALUE (valtail); tree val = TREE_VALUE (valtail);
tree rname = function;
int argnum = parmnum + 1;
if (type == void_type_node) if (type == void_type_node)
{ {
if (name) error ("too many arguments to function %qE", function);
error ("too many arguments to function %qs",
IDENTIFIER_POINTER (name));
else
error ("too many arguments to function");
break; break;
} }
if (selector && argnum > 2)
{
rname = selector;
argnum -= 2;
}
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ /* 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 /* Do not use STRIP_NOPS here! We do not want an enumerator with value 0
to convert automatically to a pointer. */ to convert automatically to a pointer. */
...@@ -2078,22 +2097,34 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl) ...@@ -2078,22 +2097,34 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
if (INTEGRAL_TYPE_P (type) if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (TREE_TYPE (val)) == REAL_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) if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (TREE_TYPE (val)) == COMPLEX_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 else if (TREE_CODE (type) == COMPLEX_TYPE
&& TREE_CODE (TREE_TYPE (val)) == REAL_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 else if (TREE_CODE (type) == REAL_TYPE
&& INTEGRAL_TYPE_P (TREE_TYPE (val))) && 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 else if (TREE_CODE (type) == COMPLEX_TYPE
&& INTEGRAL_TYPE_P (TREE_TYPE (val))) && 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 else if (TREE_CODE (type) == REAL_TYPE
&& TREE_CODE (TREE_TYPE (val)) == COMPLEX_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 /* ??? At some point, messages should be written about
conversions between complex types, but that's too messy conversions between complex types, but that's too messy
to do now. */ to do now. */
...@@ -2103,9 +2134,9 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl) ...@@ -2103,9 +2134,9 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
/* Warn if any argument is passed as `float', /* Warn if any argument is passed as `float',
since without a prototype it would be `double'. */ since without a prototype it would be `double'. */
if (formal_prec == TYPE_PRECISION (float_type_node)) if (formal_prec == TYPE_PRECISION (float_type_node))
warn_for_assignment ("%s as %<float%> rather than " warning ("passing argument %d of %qE as %<float%> "
"%<double%> due to prototype", "rather than %<double%> due to prototype",
(char *) 0, name, parmnum + 1); argnum, rname);
} }
/* Detect integer changing in width or signedness. /* Detect integer changing in width or signedness.
These warnings are only activated with These warnings are only activated with
...@@ -2123,7 +2154,8 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl) ...@@ -2123,7 +2154,8 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
and the actual arg is that enum type. */ and the actual arg is that enum type. */
; ;
else if (formal_prec != TYPE_PRECISION (type1)) 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)) else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
; ;
/* Don't complain if the formal parameter type /* Don't complain if the formal parameter type
...@@ -2149,9 +2181,11 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl) ...@@ -2149,9 +2181,11 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
&& TYPE_UNSIGNED (TREE_TYPE (val))) && TYPE_UNSIGNED (TREE_TYPE (val)))
; ;
else if (TYPE_UNSIGNED (type)) 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 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) ...@@ -2180,13 +2214,7 @@ convert_arguments (tree typelist, tree values, tree name, tree fundecl)
} }
if (typetail != 0 && TREE_VALUE (typetail) != void_type_node) if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
{ error ("too few arguments to function %qE", function);
if (name)
error ("too few arguments to function %qs",
IDENTIFIER_POINTER (name));
else
error ("too few arguments to function");
}
return nreverse (result); return nreverse (result);
} }
......
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> 2004-10-06 Andrew Pinski <pinskia@physics.uc.edu>
PR c++/17368 PR c++/17368
......
/* 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" } */
}
/* 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment