diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2008-08-25 21:31:01 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2008-08-25 21:31:01 +0000 |
| commit | 3d421e190a7cc94664c47180b292ad51881b3247 (patch) | |
| tree | f38bd5c4676c786cb1b472307e3f5ccd61852ed9 /clang/lib | |
| parent | f00f1e50b52851453610dbd8ba8ca192400f7374 (diff) | |
| download | bcm5719-llvm-3d421e190a7cc94664c47180b292ad51881b3247.tar.gz bcm5719-llvm-3d421e190a7cc94664c47180b292ad51881b3247.zip | |
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.
llvm-svn: 55339
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 21 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 15 |
3 files changed, 29 insertions, 17 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index af63be73fe9..11fde873028 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/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/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 066969ce9e8..ad83908e451 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 820a1c85f06..c7876b1151a 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/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); |

