[PATCH] D81313: Fix handling of constinit thread_locals with a forward-declared type.
James Y Knight via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 5 15:43:39 PDT 2020
jyknight created this revision.
jyknight added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
ItaniumCXXABI::usesThreadWrapperFunction calls
VarDecl::needsDestruction, which calls QualType::isDestructedType,
which checks CXXRecordDecl::hasTrivialDestructor -- but only if the
type has a definition.
Most (maybe all other?) callers of isDestructedType call it on a
complete type, but in this particular codepath, it can be called on an
incomplete type, and thus return false for a type which, when the
definition is available, does turn out to have a non-trivial
destructor.
FIXME: I'm not sure if this fix is the correct fix -- whether this
function ought to be changed like this, or if the fix belongs
somewhere else.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D81313
Files:
clang/lib/AST/Type.cpp
clang/test/CodeGenCXX/cxx2a-thread-local-constinit.cpp
Index: clang/test/CodeGenCXX/cxx2a-thread-local-constinit.cpp
===================================================================
--- clang/test/CodeGenCXX/cxx2a-thread-local-constinit.cpp
+++ clang/test/CodeGenCXX/cxx2a-thread-local-constinit.cpp
@@ -12,8 +12,9 @@
// LINUX-DAG: @d = thread_local global i32 0, align 4
// DARWIN-DAG: @d = internal thread_local global i32 0, align 4
// CHECK-DAG: @e = external thread_local global %struct.Destructed, align 4
-// CHECK-DAG: @e2 = thread_local global %struct.Destructed zeroinitializer, align 4
-// CHECK-DAG: @f = thread_local global i32 4, align 4
+// CHECK-DAG: @f = external thread_local global %struct.MaybeDestructed, align 1
+// CHECK-DAG: @g = thread_local global %struct.Destructed zeroinitializer, align 4
+// CHECK-DAG: @h = thread_local global i32 4, align 4
extern thread_local int a;
extern thread_local constinit int b;
@@ -74,13 +75,20 @@
// CHECK: }
int get_e() { return e.n; }
-// CHECK: define {{.*}}[[E2_INIT:@__cxx_global_var_init[^(]*]](
-// LINUX: call {{.*}} @__cxa_thread_atexit({{.*}} @_ZN10DestructedD1Ev {{.*}} @e2
-// DARWIN: call {{.*}} @_tlv_atexit({{.*}} @_ZN10DestructedD1Ev {{.*}} @e2
-thread_local constinit Destructed e2;
+struct MaybeDestructed; // forward-declared, can't tell if it has a destructor.
+extern thread_local constinit MaybeDestructed f;
+// CHECK-LABEL: define %struct.MaybeDestructed* @_Z5get_fv()
+// CHECK: call {{.*}}* @_ZTW1f()
+// CHECK: }
+MaybeDestructed* get_f() { return &f; }
+
+// CHECK: define {{.*}}[[G_INIT:@__cxx_global_var_init[^(]*]](
+// LINUX: call {{.*}} @__cxa_thread_atexit({{.*}} @_ZN10DestructedD1Ev {{.*}} @g
+// DARWIN: call {{.*}} @_tlv_atexit({{.*}} @_ZN10DestructedD1Ev {{.*}} @g
+thread_local constinit Destructed g;
-thread_local constinit int f = 4;
+thread_local constinit int h = 4;
// CHECK-LABEL: define {{.*}}__tls_init
// CHECK: call {{.*}} [[D_INIT]]
-// CHECK: call {{.*}} [[E2_INIT]]
+// CHECK: call {{.*}} [[G_INIT]]
Index: clang/lib/AST/Type.cpp
===================================================================
--- clang/lib/AST/Type.cpp
+++ clang/lib/AST/Type.cpp
@@ -4287,9 +4287,14 @@
const RecordDecl *RD = RT->getDecl();
if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
/// Check if this is a C++ object with a non-trivial destructor.
- if (CXXRD->hasDefinition() && !CXXRD->hasTrivialDestructor())
+ /// If the type is only forward-declared, assume it might need destruction.
+ if (!CXXRD->hasDefinition() || !CXXRD->hasTrivialDestructor())
return DK_cxx_destructor;
} else {
+ // FIXME: should this also return true for forward declared types? It
+ // seems a bit weird, as C doesn't support destructors...but objc-arc now
+ // does.
+
/// Check if this is a C struct that is non-trivial to destroy or an array
/// that contains such a struct.
if (RD->isNonTrivialToPrimitiveDestroy())
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81313.268955.patch
Type: text/x-patch
Size: 2955 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200605/33bc60e6/attachment.bin>
More information about the cfe-commits
mailing list