Hi Doug, Two points: --Would it be better if the C++ semantic checks were modified to work on the param types of the function type ? ParmVarDecls are not strictly needed except in the case of default args.
--The test case (along with some others) now crashes on both C++ and C on Windows. This is what happens: -ParmVarDecls are added to the FunctionDecl that has typedef as type. -When it's time to destroy the FunctionDecl, the destructor enters the ParmVarDecl-destroying-loop -FunctionDecl::param_end() sees that there are actually ParmVarDecls stored so it tries to return the correct iterator (before your commit it would just return 0x0 for a typedef'ed FunctionDecl). -FunctionDecl::getNumParams() tries to return the number of parameters. -Getting the param number involves first getting at the underlying FunctionType of the TypedefType. -In order to get at its unsugared type, the TypedefType needs to get the TypedefDecl::UnderlyingType -The TypedefDecl was previously destroyed and... crash! -Argiris Douglas Gregor wrote: > Author: dgregor > Date: Fri Oct 24 13:09:54 2008 > New Revision: 58100 > > URL: http://llvm.org/viewvc/llvm-project?rev=58100&view=rev > Log: > PR2942: FunctionDecls by typedef crash the C++ front-end > > Added: > cfe/trunk/test/SemaCXX/fntype-decl.cpp > Modified: > cfe/trunk/lib/Sema/SemaDecl.cpp > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=58100&r1=58099&r2=58100&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 24 13:09:54 2008 > @@ -781,13 +781,42 @@ > 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<ParmVarDecl*, 16> 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 > > Added: cfe/trunk/test/SemaCXX/fntype-decl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/fntype-decl.cpp?rev=58100&view=auto > > ============================================================================== > --- cfe/trunk/test/SemaCXX/fntype-decl.cpp (added) > +++ cfe/trunk/test/SemaCXX/fntype-decl.cpp Fri Oct 24 13:09:54 2008 > @@ -0,0 +1,5 @@ > +// RUN: clang -fsyntax-only -verify %s > + > +// PR2942 > +typedef void fn(int); > +fn f; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
