diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index af63be73fe..11fde87302 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -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()); } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 066969ce9e..ad83908e45 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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. } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 820a1c85f0..c7876b1151 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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); diff --git a/test/CodeGen/kr-func-promote.c b/test/CodeGen/kr-func-promote.c new file mode 100644 index 0000000000..a20532a976 --- /dev/null +++ b/test/CodeGen/kr-func-promote.c @@ -0,0 +1,5 @@ +// RUN: clang %s -emit-llvm -o - | grep "i32 @a(i32)" + +int a(); +int a(x) short x; {return x;} +