|
@@ -2284,8 +2284,19 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
|
|
llvm::Type *dtorTy =
|
|
llvm::Type *dtorTy =
|
|
llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
|
|
llvm::FunctionType::get(CGF.VoidTy, CGF.Int8PtrTy, false)->getPointerTo();
|
|
|
|
|
|
|
|
+ // Preserve address space of addr.
|
|
|
|
+ auto AddrAS = addr ? addr->getType()->getPointerAddressSpace() : 0;
|
|
|
|
+ auto AddrInt8PtrTy =
|
|
|
|
+ AddrAS ? CGF.Int8Ty->getPointerTo(AddrAS) : CGF.Int8PtrTy;
|
|
|
|
+
|
|
|
|
+ // Create a variable that binds the atexit to this shared object.
|
|
|
|
+ llvm::Constant *handle =
|
|
|
|
+ CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
|
|
|
|
+ auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
|
|
|
|
+ GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
|
|
|
+
|
|
// extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
|
|
// extern "C" int __cxa_atexit(void (*f)(void *), void *p, void *d);
|
|
- llvm::Type *paramTys[] = { dtorTy, CGF.Int8PtrTy, CGF.Int8PtrTy };
|
|
|
|
|
|
+ llvm::Type *paramTys[] = {dtorTy, AddrInt8PtrTy, handle->getType()};
|
|
llvm::FunctionType *atexitTy =
|
|
llvm::FunctionType *atexitTy =
|
|
llvm::FunctionType::get(CGF.IntTy, paramTys, false);
|
|
llvm::FunctionType::get(CGF.IntTy, paramTys, false);
|
|
|
|
|
|
@@ -2294,12 +2305,6 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
|
|
if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
|
|
if (llvm::Function *fn = dyn_cast<llvm::Function>(atexit.getCallee()))
|
|
fn->setDoesNotThrow();
|
|
fn->setDoesNotThrow();
|
|
|
|
|
|
- // Create a variable that binds the atexit to this shared object.
|
|
|
|
- llvm::Constant *handle =
|
|
|
|
- CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
|
|
|
|
- auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
|
|
|
|
- GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
|
|
|
|
-
|
|
|
|
if (!addr)
|
|
if (!addr)
|
|
// addr is null when we are trying to register a dtor annotated with
|
|
// addr is null when we are trying to register a dtor annotated with
|
|
// __attribute__((destructor)) in a constructor function. Using null here is
|
|
// __attribute__((destructor)) in a constructor function. Using null here is
|
|
@@ -2309,7 +2314,7 @@ static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
|
|
|
|
|
|
llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
|
|
llvm::Value *args[] = {llvm::ConstantExpr::getBitCast(
|
|
cast<llvm::Constant>(dtor.getCallee()), dtorTy),
|
|
cast<llvm::Constant>(dtor.getCallee()), dtorTy),
|
|
- llvm::ConstantExpr::getBitCast(addr, CGF.Int8PtrTy),
|
|
|
|
|
|
+ llvm::ConstantExpr::getBitCast(addr, AddrInt8PtrTy),
|
|
handle};
|
|
handle};
|
|
CGF.EmitNounwindRuntimeCall(atexit, args);
|
|
CGF.EmitNounwindRuntimeCall(atexit, args);
|
|
}
|
|
}
|