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>
PR debug/17787
......
......@@ -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);
}
......
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
......
/* 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