Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1235,6 +1235,7 @@ HelpText<"Don't use __cxa_atexit for calling destructors">; def fno_use_init_array : Flag<["-"], "fno-use-init-array">, Group, Flags<[CC1Option]>, HelpText<"Don't use .init_array instead of .ctors">; +def fno_destroy_globals : Flag<["-"], "fno-destroy-globals">, Group, Flags<[CC1Option]>; def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group; def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group; def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group; @@ -1465,6 +1466,8 @@ def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group; def fuse_init_array : Flag<["-"], "fuse-init-array">, Group, Flags<[CC1Option]>, HelpText<"Use .init_array instead of .ctors">; +def fdestroy_globals : Flag<["-"], "fdestroy-globals">, Group, Flags<[CC1Option]>, + HelpText<"Register global variables for destruction">; def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group; def fverbose_asm : Flag<["-"], "fverbose-asm">, Group; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group, Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -44,6 +44,7 @@ CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors. CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker ///< aliases to base ctors when possible. +CODEGENOPT(DestroyGlobals, 1, 1) ///< -fdestroy-globals CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled. Index: lib/CodeGen/CGDeclCXX.cpp =================================================================== --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -180,7 +180,7 @@ EmitDeclInit(*this, D, DeclAddr); if (CGM.isTypeConstant(D.getType(), true)) EmitDeclInvariant(*this, D, DeclPtr); - else + else if (CGM.getCodeGenOpts().DestroyGlobals) EmitDeclDestroy(*this, D, DeclAddr); return; } Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3697,6 +3697,11 @@ KernelOrKext) CmdArgs.push_back("-fno-use-cxa-atexit"); + // -fdestroy-globals=1 is default. + if (!Args.hasFlag(options::OPT_fdestroy_globals, + options::OPT_fno_destroy_globals, true)) + CmdArgs.push_back("-fno-destroy-globals"); + // -fms-extensions=0 is default. if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, IsWindowsMSVC)) Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -582,6 +582,7 @@ Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); + Opts.DestroyGlobals = !Args.hasArg(OPT_fno_destroy_globals); Opts.CodeModel = getCodeModel(Args, Diags); Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DisableFPElim = Index: test/Driver/fdestroy-globals.cpp =================================================================== --- /dev/null +++ test/Driver/fdestroy-globals.cpp @@ -0,0 +1,30 @@ +// RUN: %clang -fno-destroy-globals -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FLAG-DISABLE +// RUN: %clang -fdestroy-globals -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FLAG-ENABLE1 +// RUN: %clang -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FLAG-ENABLE2 + +// RUN: %clang_cc1 -fno-destroy-globals -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-CODE-DISABLE +// RUN: %clang_cc1 -fdestroy-globals -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-CODE-ENABLE + +// CHECK-FLAG-DISABLE: "-cc1" +// CHECK-FLAG-DISABLE: "-fno-destroy-globals" + +// CHECK-FLAG-ENABLE1: "-cc1" +// CHECK-FLAG-ENABLE1-NOT: "-fno-destroy-globals" + +// CHECK-FLAG-ENABLE2: "-cc1" +// CHECK-FLAG-ENABLE2-NOT: "-fno-destroy-globals" + +// CHECK-CODE-DISABLE-LABEL: define {{.*}} @__cxx_global_var_init +// CHECK-CODE-DISABLE: call void @_ZN1AC1Ev{{.*}} +// CHECK-CODE-DISABLE: ret void + +// CHECK-CODE-ENABLE-LABEL: define {{.*}} @__cxx_global_var_init +// CHECK-CODE-ENABLE: call void @_ZN1AC1Ev{{.*}} +// CHECK-CODE-ENABLE: %{{.*}} = call i32 @__cxa_atexit{{.*}}_ZN1AD1Ev +// CHECK-CODE-ENABLE: ret void + +struct A { + virtual ~A() {} +}; + +A a;