static void emitGlobalDtorWithCXAAtExit(CodeGenFunction &CGF,
llvm::FunctionCallee dtor,
llvm::Constant *addr, bool TLS) {
+ assert((TLS || CGF.getTypes().getCodeGenOpts().CXAAtExit) &&
+ "__cxa_atexit is disabled");
const char *Name = "__cxa_atexit";
if (TLS) {
const llvm::Triple &T = CGF.getTarget().getTriple();
if (D.isNoDestroy(CGM.getContext()))
return;
- // Use __cxa_atexit if available.
- if (CGM.getCodeGenOpts().CXAAtExit)
+ // emitGlobalDtorWithCXAAtExit will emit a call to either __cxa_thread_atexit
+ // or __cxa_atexit depending on whether this VarDecl is a thread-local storage
+ // or not. CXAAtExit controls only __cxa_atexit, so use it if it is enabled.
+ // We can always use __cxa_thread_atexit.
+ if (CGM.getCodeGenOpts().CXAAtExit || D.getTLSKind())
return emitGlobalDtorWithCXAAtExit(CGF, dtor, addr, D.getTLSKind());
- if (D.getTLSKind())
- CGM.ErrorUnsupported(&D, "non-trivial TLS destruction");
-
// In Apple kexts, we want to add a global destructor entry.
// FIXME: shouldn't this be guarded by some variable?
if (CGM.getLangOpts().AppleKext) {
// RUN: -triple x86_64-linux-gnu 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=CHECK --check-prefix=DARWIN %s
+// RUN: %clang_cc1 -std=c++11 -fno-use-cxa-atexit -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -fno-use-cxa-atexit -emit-llvm %s -O2 -disable-llvm-passes -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=CHECK --check-prefix=LINUX --check-prefix=CHECK-OPT %s
+// RUN: %clang_cc1 -std=c++11 -fno-use-cxa-atexit -femulated-tls -emit-llvm %s -o - \
+// RUN: -triple x86_64-linux-gnu 2>&1 | FileCheck --check-prefix=CHECK --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -fno-use-cxa-atexit -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=CHECK --check-prefix=DARWIN %s
+
int f();
int g();