зеркало из https://github.com/microsoft/clang-1.git
Do typechecking and codegen for K&R-style function declarations
correctly. Not a regression, but made more obvious by my recent fix which made function type compatibility checking a bit more strict. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55339 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c9e56b2a63
Коммит
eb4b7051a5
|
@ -138,10 +138,23 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
|
|||
AI->setName("agg.result");
|
||||
++AI;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
|
||||
assert(AI != CurFn->arg_end() && "Argument mismatch!");
|
||||
EmitParmDecl(*FD->getParamDecl(i), AI);
|
||||
|
||||
if (FD->getNumParams()) {
|
||||
const FunctionTypeProto* FProto = FD->getType()->getAsFunctionTypeProto();
|
||||
assert(FProto && "Function def must have prototype!");
|
||||
for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
|
||||
assert(AI != CurFn->arg_end() && "Argument mismatch!");
|
||||
const ParmVarDecl* CurParam = FD->getParamDecl(i);
|
||||
llvm::Value* V = AI;
|
||||
if (!getContext().typesAreCompatible(FProto->getArgType(i),
|
||||
CurParam->getType())) {
|
||||
// This must be a promotion, for something like
|
||||
// "void a(x) short x; {..."
|
||||
V = EmitScalarConversion(V, FProto->getArgType(i),
|
||||
CurParam->getType());
|
||||
}
|
||||
EmitParmDecl(*CurParam, V);
|
||||
}
|
||||
}
|
||||
GenerateFunction(FD->getBody());
|
||||
}
|
||||
|
|
|
@ -690,8 +690,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
|||
|
||||
// Copy the parameter declarations from the declarator D to
|
||||
// the function declaration NewFD, if they are available.
|
||||
if (D.getNumTypeObjects() > 0 &&
|
||||
D.getTypeObject(0).Fun.hasPrototype) {
|
||||
if (D.getNumTypeObjects() > 0) {
|
||||
DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
|
||||
|
||||
// Create Decl objects for each parameter, adding them to the
|
||||
|
@ -716,7 +715,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
|||
Diag(Param->getLocation(), diag::ext_param_typedef_of_void);
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
|
||||
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
|
||||
Params.push_back((ParmVarDecl *)FTI.ArgInfo[i].Param);
|
||||
}
|
||||
|
@ -1540,11 +1539,6 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
|
|||
FTI.ArgInfo[i].Param = ActOnParamDeclarator(FnBodyScope, ParamD);
|
||||
}
|
||||
}
|
||||
|
||||
// Since this is a function definition, act as though we have information
|
||||
// about the arguments.
|
||||
if (FTI.NumArgs)
|
||||
FTI.hasPrototype = true;
|
||||
} else {
|
||||
// FIXME: Diagnose arguments without names in C.
|
||||
}
|
||||
|
|
|
@ -397,14 +397,12 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
D.setInvalidType(true);
|
||||
}
|
||||
|
||||
if (!FTI.hasPrototype) {
|
||||
if (FTI.NumArgs == 0) {
|
||||
// Simple void foo(), where the incoming T is the result type.
|
||||
T = Context.getFunctionTypeNoProto(T);
|
||||
|
||||
} else if (FTI.ArgInfo[0].Param == 0) {
|
||||
// C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function definition.
|
||||
if (FTI.NumArgs != 0)
|
||||
Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
|
||||
|
||||
Diag(FTI.ArgInfo[0].IdentLoc, diag::err_ident_list_in_fn_declaration);
|
||||
} else {
|
||||
// Otherwise, we have a function with an argument list that is
|
||||
// potentially variadic.
|
||||
|
@ -458,6 +456,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
// Do not add 'void' to the ArgTys list.
|
||||
break;
|
||||
}
|
||||
} else if (!FTI.hasPrototype) {
|
||||
if (ArgTy->isPromotableIntegerType()) {
|
||||
ArgTy = Context.IntTy;
|
||||
} else if (const BuiltinType* BTy = ArgTy->getAsBuiltinType()) {
|
||||
if (BTy->getKind() == BuiltinType::Float)
|
||||
ArgTy = Context.DoubleTy;
|
||||
}
|
||||
}
|
||||
|
||||
ArgTys.push_back(ArgTy);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
// RUN: clang %s -emit-llvm -o - | grep "i32 @a(i32)"
|
||||
|
||||
int a();
|
||||
int a(x) short x; {return x;}
|
||||
|
Загрузка…
Ссылка в новой задаче