From 6cbd3df095ab92e0637265e88fe9c093135cdb03 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 24 Oct 2008 18:09:54 +0000 Subject: [PATCH] PR2942: FunctionDecls by typedef crash the C++ front-end git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58100 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 31 ++++++++++++++++++++++++++++++- test/SemaCXX/fntype-decl.cpp | 5 +++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/SemaCXX/fntype-decl.cpp diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index df4ade090e..4c36b09af8 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -781,13 +781,42 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { Param->getType().getUnqualifiedType() != Context.VoidTy) { Diag(Param->getLocation(), diag::ext_param_typedef_of_void); } - } 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); } NewFD->setParams(&Params[0], Params.size()); + } else if (R->getAsTypedefType()) { + // When we're declaring a function with a typedef, as in the + // following example, we'll need to synthesize (unnamed) + // parameters for use in the declaration. + // + // @code + // typedef void fn(int); + // fn f; + // @endcode + const FunctionTypeProto *FT = R->getAsFunctionTypeProto(); + if (!FT) { + // This is a typedef of a function with no prototype, so we + // don't need to do anything. + } else if ((FT->getNumArgs() == 0) || + (FT->getNumArgs() == 1 && !FT->isVariadic() && + FT->getArgType(0)->isVoidType())) { + // This is a zero-argument function. We don't need to do anything. + } else { + // Synthesize a parameter for each argument type. + llvm::SmallVector Params; + for (FunctionTypeProto::arg_type_iterator ArgType = FT->arg_type_begin(); + ArgType != FT->arg_type_end(); ++ArgType) { + Params.push_back(ParmVarDecl::Create(Context, CurContext, + SourceLocation(), 0, + *ArgType, VarDecl::None, + 0, 0)); + } + + NewFD->setParams(&Params[0], Params.size()); + } } // Merge the decl with the existing one if appropriate. Since C functions diff --git a/test/SemaCXX/fntype-decl.cpp b/test/SemaCXX/fntype-decl.cpp new file mode 100644 index 0000000000..b54346624c --- /dev/null +++ b/test/SemaCXX/fntype-decl.cpp @@ -0,0 +1,5 @@ +// RUN: clang -fsyntax-only -verify %s + +// PR2942 +typedef void fn(int); +fn f; -- 2.40.0