forked from OSchip/llvm-project
When we're calling a function that we know based on its K&R-style
function definition, we should still use a prototype to type-check and convert the function arguments, if such a prototype exists. Fixes PR8314. llvm-svn: 117305
This commit is contained in:
parent
e137df2624
commit
8e09a72f13
|
@ -3836,24 +3836,51 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
|
|||
// on our knowledge of the function definition.
|
||||
const FunctionDecl *Def = 0;
|
||||
if (FDecl->hasBody(Def) && NumArgs != Def->param_size()) {
|
||||
const FunctionProtoType *Proto =
|
||||
Def->getType()->getAs<FunctionProtoType>();
|
||||
if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {
|
||||
const FunctionProtoType *Proto
|
||||
= Def->getType()->getAs<FunctionProtoType>();
|
||||
if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size()))
|
||||
Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments)
|
||||
<< (NumArgs > Def->param_size()) << FDecl << Fn->getSourceRange();
|
||||
}
|
||||
}
|
||||
|
||||
// If the function we're calling isn't a function prototype, but we have
|
||||
// a function prototype from a prior declaratiom, use that prototype.
|
||||
if (!FDecl->hasPrototype())
|
||||
Proto = FDecl->getType()->getAs<FunctionProtoType>();
|
||||
}
|
||||
|
||||
// Promote the arguments (C99 6.5.2.2p6).
|
||||
for (unsigned i = 0; i != NumArgs; i++) {
|
||||
Expr *Arg = Args[i];
|
||||
DefaultArgumentPromotion(Arg);
|
||||
if (RequireCompleteType(Arg->getSourceRange().getBegin(),
|
||||
Arg->getType(),
|
||||
PDiag(diag::err_call_incomplete_argument)
|
||||
<< Arg->getSourceRange()))
|
||||
return ExprError();
|
||||
|
||||
if (Proto && i < Proto->getNumArgs()) {
|
||||
if (RequireCompleteType(Arg->getSourceRange().getBegin(),
|
||||
Arg->getType(),
|
||||
PDiag(diag::err_call_incomplete_argument)
|
||||
<< Arg->getSourceRange()))
|
||||
return ExprError();
|
||||
|
||||
InitializedEntity Entity
|
||||
= InitializedEntity::InitializeParameter(Context,
|
||||
Proto->getArgType(i));
|
||||
ExprResult ArgE = PerformCopyInitialization(Entity,
|
||||
SourceLocation(),
|
||||
Owned(Arg));
|
||||
if (ArgE.isInvalid())
|
||||
return true;
|
||||
|
||||
Arg = ArgE.takeAs<Expr>();
|
||||
|
||||
} else {
|
||||
DefaultArgumentPromotion(Arg);
|
||||
|
||||
if (RequireCompleteType(Arg->getSourceRange().getBegin(),
|
||||
Arg->getType(),
|
||||
PDiag(diag::err_call_incomplete_argument)
|
||||
<< Arg->getSourceRange()))
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
TheCall->setArg(i, Arg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -Wconversion -fsyntax-only -verify %s
|
||||
|
||||
// C DR #316, PR 3626.
|
||||
void f0(a, b, c, d) int a,b,c,d; {}
|
||||
|
@ -27,3 +27,14 @@ char *rindex(s, c)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// PR8314
|
||||
void proto(int);
|
||||
void proto(x)
|
||||
int x;
|
||||
{
|
||||
}
|
||||
|
||||
void use_proto() {
|
||||
proto(42.0); // expected-warning{{implicit conversion turns floating-point number into integer: 'double' to 'int'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue