From: Chris Lattner Date: Tue, 31 Mar 2009 22:37:52 +0000 (+0000) Subject: Change UsedArray to be a vector of WeakVH to fix a dangling pointer problem that... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=35f38a2c22d68c22e2dbe8e9ee84c120c8f327bb;p=clang Change UsedArray to be a vector of WeakVH to fix a dangling pointer problem that occurs when attribute(used) and asm renaming are used together. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68155 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 3de8156fe5..6c0cc7ef2b 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -320,8 +320,7 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { assert(!GV->isDeclaration() && "Only globals with definition can force usage."); - llvm::Type *i8PTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); - LLVMUsed.push_back(llvm::ConstantExpr::getBitCast(GV, i8PTy)); + LLVMUsed.push_back(GV); } void CodeGenModule::EmitLLVMUsed() { @@ -329,12 +328,21 @@ void CodeGenModule::EmitLLVMUsed() { if (LLVMUsed.empty()) return; - llvm::ArrayType *ATy = llvm::ArrayType::get(LLVMUsed[0]->getType(), - LLVMUsed.size()); + llvm::Type *i8PTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, LLVMUsed.size()); + + // Convert LLVMUsed to what ConstantArray needs. + std::vector UsedArray; + UsedArray.resize(LLVMUsed.size()); + for (unsigned i = 0, e = LLVMUsed.size(); i != e; ++i) { + UsedArray[i] = + llvm::ConstantExpr::getBitCast(cast(&*LLVMUsed[i]), i8PTy); + } + llvm::GlobalVariable *GV = new llvm::GlobalVariable(ATy, false, llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, LLVMUsed), + llvm::ConstantArray::get(ATy, UsedArray), "llvm.used", &getModule()); GV->setSection("llvm.metadata"); @@ -725,7 +733,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { Entry->replaceAllUsesWith(NewPtrForOldDecl); // Erase the old global, since it is no longer used. - // FIXME: What if it was attribute used? Dangling pointer from LLVMUsed. cast(Entry)->eraseFromParent(); } @@ -839,8 +846,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { Entry->replaceAllUsesWith(NewPtrForOldDecl); // Ok, delete the old function now, which is dead. - // FIXME: If it was attribute(used) the pointer will dangle from the - // LLVMUsed array! cast(Entry)->eraseFromParent(); Entry = NewFn; @@ -905,7 +910,6 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA, Entry->getType())); - // FIXME: What if it was attribute used? Dangling pointer from LLVMUsed. Entry->eraseFromParent(); } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index dbfbf028af..01b8d02fb8 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -21,6 +21,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Support/ValueHandle.h" #include namespace llvm { @@ -119,7 +120,7 @@ class CodeGenModule : public BlockModule { /// present in the object file; bitcast to i8*. This is used for /// forcing visibility of symbols which may otherwise be optimized /// out. - std::vector LLVMUsed; + std::vector LLVMUsed; /// GlobalCtors - Store the list of global constructors and their respective /// priorities to be emitted when the translation unit is complete. diff --git a/test/CodeGen/mangle.c b/test/CodeGen/mangle.c index 6571a4b787..b3affe9469 100644 --- a/test/CodeGen/mangle.c +++ b/test/CodeGen/mangle.c @@ -47,3 +47,8 @@ void test3() { void foo6() __asm__("var2"); void foo6() { } + + + +int foo7 __asm__("foo7") __attribute__((used)); +float foo8 __asm__("foo7") = 42;