forked from OSchip/llvm-project
PR19254: If a thread_local data member of a class is accessed via member access
syntax, don't forget to run its initializer. llvm-svn: 204869
This commit is contained in:
parent
b220a129ca
commit
0f38374f71
|
@ -280,8 +280,9 @@ void CGCXXABI::EmitThreadLocalInitFuncs(
|
|||
llvm::Function *InitFunc) {
|
||||
}
|
||||
|
||||
LValue CGCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||
const DeclRefExpr *DRE) {
|
||||
LValue CGCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
|
||||
const VarDecl *VD,
|
||||
QualType LValType) {
|
||||
ErrorUnsupportedABI(CGF, "odr-use of thread_local global");
|
||||
return LValue();
|
||||
}
|
||||
|
|
|
@ -481,8 +481,9 @@ public:
|
|||
/// Emit a reference to a non-local thread_local variable (including
|
||||
/// triggering the initialization of all thread_local variables in its
|
||||
/// translation unit).
|
||||
virtual LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||
const DeclRefExpr *DRE);
|
||||
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
|
||||
const VarDecl *VD,
|
||||
QualType LValType);
|
||||
};
|
||||
|
||||
// Create an instance of a C++ ABI class:
|
||||
|
|
|
@ -1691,11 +1691,16 @@ EmitBitCastOfLValueToProperType(CodeGenFunction &CGF,
|
|||
|
||||
static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
|
||||
const Expr *E, const VarDecl *VD) {
|
||||
QualType T = E->getType();
|
||||
|
||||
// If it's thread_local, emit a call to its wrapper function instead.
|
||||
if (VD->getTLSKind() == VarDecl::TLS_Dynamic)
|
||||
return CGF.CGM.getCXXABI().EmitThreadLocalVarDeclLValue(CGF, VD, T);
|
||||
|
||||
llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
|
||||
llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
|
||||
V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy);
|
||||
CharUnits Alignment = CGF.getContext().getDeclAlign(VD);
|
||||
QualType T = E->getType();
|
||||
LValue LV;
|
||||
if (VD->getType()->isReferenceType()) {
|
||||
llvm::LoadInst *LI = CGF.Builder.CreateLoad(V);
|
||||
|
@ -1703,7 +1708,7 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
|
|||
V = LI;
|
||||
LV = CGF.MakeNaturalAlignAddrLValue(V, T);
|
||||
} else {
|
||||
LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
|
||||
LV = CGF.MakeAddrLValue(V, T, Alignment);
|
||||
}
|
||||
setObjCGCLValueClass(CGF.getContext(), E, LV);
|
||||
return LV;
|
||||
|
@ -1770,12 +1775,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|||
|
||||
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
|
||||
// Check if this is a global variable.
|
||||
if (VD->hasLinkage() || VD->isStaticDataMember()) {
|
||||
// If it's thread_local, emit a call to its wrapper function instead.
|
||||
if (VD->getTLSKind() == VarDecl::TLS_Dynamic)
|
||||
return CGM.getCXXABI().EmitThreadLocalDeclRefExpr(*this, E);
|
||||
if (VD->hasLinkage() || VD->isStaticDataMember())
|
||||
return EmitGlobalVarDeclLValue(*this, E, VD);
|
||||
}
|
||||
|
||||
bool isBlockVariable = VD->hasAttr<BlocksAttr>();
|
||||
|
||||
|
|
|
@ -214,8 +214,8 @@ public:
|
|||
void EmitThreadLocalInitFuncs(
|
||||
llvm::ArrayRef<std::pair<const VarDecl *, llvm::GlobalVariable *> > Decls,
|
||||
llvm::Function *InitFunc) override;
|
||||
LValue EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||
const DeclRefExpr *DRE) override;
|
||||
LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD,
|
||||
QualType LValType) override;
|
||||
|
||||
bool NeedsVTTParameter(GlobalDecl GD) override;
|
||||
};
|
||||
|
@ -1647,9 +1647,9 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
|
|||
}
|
||||
}
|
||||
|
||||
LValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
||||
const DeclRefExpr *DRE) {
|
||||
const VarDecl *VD = cast<VarDecl>(DRE->getDecl());
|
||||
LValue ItaniumCXXABI::EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF,
|
||||
const VarDecl *VD,
|
||||
QualType LValType) {
|
||||
QualType T = VD->getType();
|
||||
llvm::Type *Ty = CGF.getTypes().ConvertTypeForMem(T);
|
||||
llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty);
|
||||
|
@ -1660,10 +1660,9 @@ LValue ItaniumCXXABI::EmitThreadLocalDeclRefExpr(CodeGenFunction &CGF,
|
|||
|
||||
LValue LV;
|
||||
if (VD->getType()->isReferenceType())
|
||||
LV = CGF.MakeNaturalAlignAddrLValue(Val, T);
|
||||
LV = CGF.MakeNaturalAlignAddrLValue(Val, LValType);
|
||||
else
|
||||
LV = CGF.MakeAddrLValue(Val, DRE->getType(),
|
||||
CGF.getContext().getDeclAlign(VD));
|
||||
LV = CGF.MakeAddrLValue(Val, LValType, CGF.getContext().getDeclAlign(VD));
|
||||
// FIXME: need setObjCGCLValueClass?
|
||||
return LV;
|
||||
}
|
||||
|
|
|
@ -135,6 +135,16 @@ int PR15991() {
|
|||
return l();
|
||||
}
|
||||
|
||||
struct PR19254 {
|
||||
static thread_local int n;
|
||||
int f();
|
||||
};
|
||||
// CHECK: define {{.*}} @_ZN7PR192541fEv(
|
||||
int PR19254::f() {
|
||||
// CHECK: call void @_ZTHN7PR192541nE(
|
||||
return this->n;
|
||||
}
|
||||
|
||||
// CHECK: define {{.*}} @[[V_M_INIT:.*]]()
|
||||
// CHECK: load i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*)
|
||||
// CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0
|
||||
|
|
Loading…
Reference in New Issue