From: Chris Lattner Date: Sun, 22 Mar 2009 21:56:56 +0000 (+0000) Subject: switch getBuiltinLibFunction to use the new GetOrCreateLLVMFunction X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b808c952bbff821dce727dd801a1098d64394f98;p=clang switch getBuiltinLibFunction to use the new GetOrCreateLLVMFunction functionality, fixing a crash on the attached testcase. Eliminate the BuiltinFunctions cache, as it can contain dangling pointers. This fixes a bunch of valgrind errors on test/CodeGen/builtins.c git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67484 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 9bb12900fa..92af03ea89 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -929,18 +929,9 @@ void CodeGenModule::UpdateCompletedType(const TagDecl *TD) { } -/// getBuiltinLibFunction +/// getBuiltinLibFunction - Given a builtin id for a function like +/// "__builtin_fabsf", return a Function* for "fabsf". llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) { - if (BuiltinID > BuiltinFunctions.size()) - BuiltinFunctions.resize(BuiltinID); - - // Cache looked up functions. Since builtin id #0 is invalid we don't reserve - // a slot for it. - assert(BuiltinID && "Invalid Builtin ID"); - llvm::Value *&FunctionSlot = BuiltinFunctions[BuiltinID-1]; - if (FunctionSlot) - return FunctionSlot; - assert((Context.BuiltinInfo.isLibFunction(BuiltinID) || Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) && "isn't a lib fn"); @@ -958,27 +949,10 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) { const llvm::FunctionType *Ty = cast(getTypes().ConvertType(Type)); - // FIXME: This has a serious problem with code like this: - // void abs() {} - // ... __builtin_abs(x); - // The two versions of abs will collide. The fix is for the builtin to win, - // and for the existing one to be turned into a constantexpr cast of the - // builtin. In the case where the existing one is a static function, it - // should just be renamed. - if (llvm::Function *Existing = getModule().getFunction(Name)) { - if (Existing->getFunctionType() == Ty && Existing->hasExternalLinkage()) - return FunctionSlot = Existing; - assert(Existing == 0 && "FIXME: Name collision"); - } - - llvm::GlobalValue *&ExistingFn = - GlobalDeclMap[getContext().Idents.get(Name).getName()]; - assert(!ExistingFn && "Asking for the same builtin multiple times?"); - + // Unique the name through the identifier table. + Name = getContext().Idents.get(Name).getName(); // FIXME: param attributes for sext/zext etc. - return FunctionSlot = ExistingFn = - llvm::Function::Create(Ty, llvm::Function::ExternalLinkage, Name, - &getModule()); + return GetOrCreateLLVMFunction(Name, Ty, 0); } llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys, diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index fdf5775170..a32774852d 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -137,11 +137,6 @@ class CodeGenModule : public BlockModule { /// CFConstantStringClassRef - Cached reference to the class for constant /// strings. This value has type int * but is actually an Obj-C class pointer. llvm::Constant *CFConstantStringClassRef; - - /// BuiltinFunctions - This is the cached set of Function*'s that have been - /// created for each builtin, indexed by the Builtin ID. This is null if the - /// Function* has not yet been created. - std::vector BuiltinFunctions; public: CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags, diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c index 07f3db9465..7a5e5d938d 100644 --- a/test/CodeGen/builtins.c +++ b/test/CodeGen/builtins.c @@ -112,3 +112,11 @@ int main() { return 0; } + + +void strcat() {} + +void foo() { + __builtin_strcat(0, 0); +} +