Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -43,7 +43,8 @@ CODEGENOPT(RegisterGlobalDtorsWithAtExit, 1, 1) ///< Use atexit or __cxa_atexit to register global destructors. CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker ///< aliases to base ctors when possible. -CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. +CODEGENOPT(DataSections , 1, 0) ///< Set by default, or when -f[no-]data-sections. +CODEGENOPT(HasExplicitDataSections, 1, 0) ///< Set when -f[no-]data-sections is set. CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block-section-names, ///< Produce unique section names with Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2000,7 +2000,9 @@ HelpText<"Place each function's basic blocks in unique sections (ELF Only) : all | labels | none | list=">, DocBrief<[{Generate labels for each basic block or place each basic block or a subset of basic blocks in its own section.}]>, Values<"all,labels,none,list=">; -defm data_sections : OptInFFlag<"data-sections", "Place each data in its own section">; +def fdata_sections : Flag<["-"], "fdata-sections">, Group, Flags<[CC1Option]>, + HelpText<"Place each data in its own section">; +def fno_data_sections : Flag<["-"], "fno-data-sections">, Group, Flags<[CC1Option]>; defm stack_size_section : OptInFFlag<"stack-size-section", "Emit section containing metadata on function stack sizes">; defm unique_basic_block_section_names : OptInFFlag<"unique-basic-block-section-names", Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -517,6 +517,7 @@ Options.EnableMachineFunctionSplitter = CodeGenOpts.SplitMachineFunctions; Options.FunctionSections = CodeGenOpts.FunctionSections; Options.DataSections = CodeGenOpts.DataSections; + Options.HasExplicitDataSections = CodeGenOpts.HasExplicitDataSections; Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames; Options.UniqueBasicBlockSectionNames = CodeGenOpts.UniqueBasicBlockSectionNames; Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -4906,8 +4906,13 @@ } } - if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections, - UseSeparateSections)) { + if (Arg *A = Args.getLastArg(options::OPT_fdata_sections, + options::OPT_fno_data_sections)) { + if (A->getOption().matches(options::OPT_fdata_sections)) + CmdArgs.push_back("-fdata-sections"); + else + CmdArgs.push_back("-fno-data-sections"); + } else if (UseSeparateSections) { CmdArgs.push_back("-fdata-sections"); } Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -991,6 +991,13 @@ Args.hasArg(OPT_ffunction_sections) || (Opts.BBSections != "none" && Opts.BBSections != "labels"); + if (Args.getLastArg(OPT_fdata_sections) || + Args.getLastArg(OPT_fno_data_sections)) { + Opts.HasExplicitDataSections = true; + Opts.DataSections = + Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false); + } + Opts.DataSections = Args.hasArg(OPT_fdata_sections); Opts.StackSizeSection = Args.hasArg(OPT_fstack_size_section); Opts.UniqueSectionNames = !Args.hasArg(OPT_fno_unique_section_names); Index: clang/test/Driver/function-sections.c =================================================================== --- clang/test/Driver/function-sections.c +++ clang/test/Driver/function-sections.c @@ -3,13 +3,15 @@ // CHECK-FS: -ffunction-sections // CHECK-NOFS-NOT: -ffunction-sections // CHECK-DS: -fdata-sections -// CHECK-NODS-NOT: -fdata-sections +// CHECK-NODS: -fno-data-sections +// CHECK-DS-DEFAULT-NOT: -fdata-sections +// CHECK-DS-DEFAULT-NOT: -fno-data-sections // CHECK-US-NOT: -fno-unique-section-names // CHECK-NOUS: -fno-unique-section-names // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ // RUN: -target i386-unknown-linux \ -// RUN: | FileCheck --check-prefix=CHECK-NOFS --check-prefix=CHECK-NODS %s +// RUN: | FileCheck --check-prefix=CHECK-NOFS --check-prefix=CHECK-DS-DEFAULT %s // RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \ // RUN: -target i386-unknown-linux \ Index: lld/COFF/LTO.cpp =================================================================== --- lld/COFF/LTO.cpp +++ lld/COFF/LTO.cpp @@ -66,6 +66,7 @@ // Always emit a section per function/datum with LTO. LLVM LTO should get most // of the benefit of linker GC, but there are still opportunities for ICF. c.Options.FunctionSections = true; + c.Options.HasExplicitDataSections = true; c.Options.DataSections = true; // Use static reloc model on 32-bit x86 because it usually results in more Index: lld/ELF/LTO.cpp =================================================================== --- lld/ELF/LTO.cpp +++ lld/ELF/LTO.cpp @@ -86,6 +86,7 @@ // Always emit a section per function/datum with LTO. c.Options.FunctionSections = true; + c.Options.HasExplicitDataSections = true; c.Options.DataSections = true; // Check if basic block sections must be used. Index: lld/wasm/LTO.cpp =================================================================== --- lld/wasm/LTO.cpp +++ lld/wasm/LTO.cpp @@ -45,6 +45,7 @@ // Always emit a section per function/data with LTO. c.Options.FunctionSections = true; + c.Options.HasExplicitDataSections = true; c.Options.DataSections = true; c.DisableVerify = config->disableVerify;