@@ -334,6 +334,19 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
334
334
ArrayRef<llvm::Function *> CXXThreadLocalInits,
335
335
ArrayRef<const VarDecl *> CXXThreadLocalInitVars) override ;
336
336
337
+ bool mayNeedDestruction (const VarDecl *VD) const {
338
+ if (VD->needsDestruction (getContext ()))
339
+ return true ;
340
+
341
+ // If the variable has an incomplete class type (or array thereof), it
342
+ // might need destruction.
343
+ const Type *T = VD->getType ()->getBaseElementTypeUnsafe ();
344
+ if (T->getAs <RecordType>() && T->isIncompleteType ())
345
+ return true ;
346
+
347
+ return false ;
348
+ }
349
+
337
350
// / Determine whether we will definitely emit this variable with a constant
338
351
// / initializer, either because the language semantics demand it or because
339
352
// / we know that the initializer is a constant.
@@ -364,7 +377,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
364
377
// If we have the only definition, we don't need a thread wrapper if we
365
378
// will emit the value as a constant.
366
379
if (isUniqueGVALinkage (getContext ().GetGVALinkageForVariable (VD)))
367
- return !VD-> needsDestruction ( getContext () ) && InitDecl->evaluateValue ();
380
+ return !mayNeedDestruction (VD ) && InitDecl->evaluateValue ();
368
381
369
382
// Otherwise, we need a thread wrapper unless we know that every
370
383
// translation unit will emit the value as a constant. We rely on the
@@ -376,7 +389,7 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
376
389
377
390
bool usesThreadWrapperFunction (const VarDecl *VD) const override {
378
391
return !isEmittedWithConstantInitializer (VD) ||
379
- VD-> needsDestruction ( getContext () );
392
+ mayNeedDestruction (VD );
380
393
}
381
394
LValue EmitThreadLocalVarDeclLValue (CodeGenFunction &CGF, const VarDecl *VD,
382
395
QualType LValType) override ;
@@ -2963,7 +2976,7 @@ void ItaniumCXXABI::EmitThreadLocalInitFuncs(
2963
2976
// also when the symbol is weak.
2964
2977
if (CGM.getTriple ().isOSAIX () && VD->hasDefinition () &&
2965
2978
isEmittedWithConstantInitializer (VD, true ) &&
2966
- !VD-> needsDestruction ( getContext () )) {
2979
+ !mayNeedDestruction (VD )) {
2967
2980
// Init should be null. If it were non-null, then the logic above would
2968
2981
// either be defining the function to be an alias or declaring the
2969
2982
// function with the expectation that the definition of the variable
0 commit comments