When calling a function without a prototype for which we have a
definition, warn if there are too many/too few function call arguments. llvm-svn: 68318
This commit is contained in:
parent
b0006ae76d
commit
d8e97def58
|
@ -1177,6 +1177,8 @@ def err_typecheck_call_too_few_args : Error<
|
||||||
"too few arguments to %select{function|block|method}0 call">;
|
"too few arguments to %select{function|block|method}0 call">;
|
||||||
def err_typecheck_call_too_many_args : Error<
|
def err_typecheck_call_too_many_args : Error<
|
||||||
"too many arguments to %select{function|block|method}0 call">;
|
"too many arguments to %select{function|block|method}0 call">;
|
||||||
|
def warn_call_wrong_number_of_arguments : Warning<
|
||||||
|
"too %select{few|many}0 arguments in call to %1">;
|
||||||
def err_deleted_function_use : Error<"attempt to use a deleted function">;
|
def err_deleted_function_use : Error<"attempt to use a deleted function">;
|
||||||
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
|
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
|
||||||
"cannot pass object of non-POD type %0 through variadic "
|
"cannot pass object of non-POD type %0 through variadic "
|
||||||
|
|
|
@ -2368,6 +2368,15 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
|
||||||
} else {
|
} else {
|
||||||
assert(isa<FunctionNoProtoType>(FuncT) && "Unknown FunctionType!");
|
assert(isa<FunctionNoProtoType>(FuncT) && "Unknown FunctionType!");
|
||||||
|
|
||||||
|
if (FDecl) {
|
||||||
|
// Check if we have too few/too many template arguments, based
|
||||||
|
// on our knowledge of the function definition.
|
||||||
|
const FunctionDecl *Def = 0;
|
||||||
|
if (FDecl->getBody(Def) && NumArgs != Def->param_size())
|
||||||
|
Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments)
|
||||||
|
<< (NumArgs > Def->param_size()) << FDecl << Fn->getSourceRange();
|
||||||
|
}
|
||||||
|
|
||||||
// Promote the arguments (C99 6.5.2.2p6).
|
// Promote the arguments (C99 6.5.2.2p6).
|
||||||
for (unsigned i = 0; i != NumArgs; i++) {
|
for (unsigned i = 0; i != NumArgs; i++) {
|
||||||
Expr *Arg = Args[i];
|
Expr *Arg = Args[i];
|
||||||
|
|
|
@ -9,6 +9,6 @@ int f3(y, x,
|
||||||
}
|
}
|
||||||
|
|
||||||
void f4(void) {
|
void f4(void) {
|
||||||
f3 (1, 1, 2, 3, 4);
|
f3 (1, 1, 2, 3, 4); // expected-warning{{too many arguments}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ int t9(int a, ); // expected-error {{expected parameter declarator}}
|
||||||
|
|
||||||
// PR2042
|
// PR2042
|
||||||
void t10(){}
|
void t10(){}
|
||||||
void t11(){t10(1);}
|
void t11(){t10(1);} // expected-warning{{too many arguments}}
|
||||||
|
|
||||||
// PR3208
|
// PR3208
|
||||||
void t12(int) {} // expected-error{{parameter name omitted}}
|
void t12(int) {} // expected-error{{parameter name omitted}}
|
||||||
|
|
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
// C DR #316, PR 3626.
|
// C DR #316, PR 3626.
|
||||||
void f0(a, b, c, d) int a,b,c,d; {}
|
void f0(a, b, c, d) int a,b,c,d; {}
|
||||||
void t0(void) { f0(1); }
|
void t0(void) {
|
||||||
|
f0(1); // expected-warning{{too few arguments}}
|
||||||
|
}
|
||||||
|
|
||||||
void f1(a, b) int a, b; {}
|
void f1(a, b) int a, b; {}
|
||||||
void t1(void) { f1(1, 2, 3); }
|
void t1(void) {
|
||||||
|
f1(1, 2, 3); // expected-warning{{too many arguments}}
|
||||||
|
}
|
||||||
|
|
||||||
void f2(float); // expected-note{{previous declaration is here}}
|
void f2(float); // expected-note{{previous declaration is here}}
|
||||||
void f2(x) float x; { } // expected-warning{{promoted type 'double' of K&R function parameter is not compatible with the parameter type 'float' declared in a previous prototype}}
|
void f2(x) float x; { } // expected-warning{{promoted type 'double' of K&R function parameter is not compatible with the parameter type 'float' declared in a previous prototype}}
|
||||||
|
|
Loading…
Reference in New Issue