-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang] [MinGW] Explicitly always pass the -fno-use-init-array #68571
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
On MinGW targets, the .ctors section is always used for constructors. Make sure that all layers of code generation is aware of this, wherever it matters, by passing the -fno-use-init-array option, setting the TargetOptions field UseInitArray to false. This fixes llvm#55938.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver ChangesOn MinGW targets, the .ctors section is always used for constructors. Make sure that all layers of code generation is aware of this, wherever it matters, by passing the -fno-use-init-array option, setting the TargetOptions field UseInitArray to false. This fixes #55938. Full diff: https://github.com/llvm/llvm-project/pull/68571.diff 2 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 5872e13bda358f8..d3d829a8ddbdb95 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -709,6 +709,8 @@ void toolchains::MinGW::addClangTargetOptions(
}
}
+ CC1Args.push_back("-fno-use-init-array");
+
for (auto Opt : {options::OPT_mthreads, options::OPT_mwindows,
options::OPT_mconsole, options::OPT_mdll}) {
if (Arg *A = DriverArgs.getLastArgNoClaim(Opt))
diff --git a/clang/test/Driver/mingw.cpp b/clang/test/Driver/mingw.cpp
index 0f276820d0fff22..bb22a0652b486e1 100644
--- a/clang/test/Driver/mingw.cpp
+++ b/clang/test/Driver/mingw.cpp
@@ -77,3 +77,6 @@
// CHECK_NO_SUBSYS-NOT: "--subsystem"
// CHECK_SUBSYS_CONSOLE: "--subsystem" "console"
// CHECK_SUBSYS_WINDOWS: "--subsystem" "windows"
+
+// RUN: %clang -target i686-windows-gnu -### %s 2>&1 | FileCheck -check-prefix=CHECK_NO_INIT_ARRAY %s
+// CHECK_NO_INIT_ARRAY: "-fno-use-init-array"
|
This is an alternative to #68570. This has the upside that the |
We could go with a clang fix, but also make the backend report_fatal_error if you try to use llvm.ctors with UseInitArray on mingw. That keeps everything consistent while also making sure non-clang frontends don't miscompile. |
Hmm, interesting proposition... But wouldn't that essentially break every single invocation of |
Hmm... Maybe the backend should have some notion of a default ctors section. So if the frontend doesn't explicitly specify anything, the backend tries to pick the right default. |
Yep, this is kinda the same issue for lots of target specific options that are set as bools..., while the ideal I guess either would be an In this case, I would maybe suggest merging both this and #68570 - that should both fix behaviours and make clang aware of the reality, and leave the root design issue for someone else to take on... WDYT? |
Doesn't UseInitArray default to false in LLVM? Anyway, we already have ways to make booleans optional; it's just a matter of implementing a "default" state, which we already do for certain options like code models. I don't think there's any fundamental architectural work involved in doing that. (See various enums in TargetOptions.h) |
The class
Right, so adding an It sounds like a somewhat disruptive change for downstreams; I know we're not supposed to compromise upstream design too much around downstream concerns, but it feels somewhat like making more of a fuss than I wanted... |
It's only breaking for downstreams that were messing with the option in the first place. Searching GitHub, the only downstream I can find that actually touches it is rustc. I understand it's simpler to just override the behavior for MinGW, but I think it's really confusing to have an option in TargetOptions that's arbitrarily ignored by some targets (both for developers reading the code, and for users). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whatever we decide to do on the LLVM side, this seems fine for the clang side. It looks like clang uses the value of UseInitArray for some ObjC stuff, in addition to passing it to the backend, so we need the right value in clang in any case.
With such a definition, I wonder how to interpret it for MSVC targets; |
On targets that don't use the Unix .ctors/.init_array convention, the option doesn't make any sense, so we should just ignore it. For example, the AIX target overrides emitXXStructorList. |
Yes, this bit should be fine in any case.
Indeed, having the correct picture is good, if there's logic that depends on it. For the ObjC case, the code actually looks like this: if (CGM.getTriple().isOSBinFormatCOFF())
InitVar->setSection(".CRT$XCLz");
else
{
if (CGM.getCodeGenOpts().UseInitArray)
InitVar->setSection(".init_array");
else
InitVar->setSection(".ctors");
} So in that sense, it doesn't really matter here. (The |
On MinGW targets, the .ctors section is always used for constructors. When using the .ctors section, the constructors need to be emitted in reverse order to get them execute in the right order. (Constructors with a specific priority are sorted separately by the linker later.) In LLVM, in CodeGen/AsmPrinter/AsmPrinter.cpp, there's code that reverses them before writing them out, executed when using the .ctors section. This logic is done whenever TM.Options.UseInitArray is set to false. Thus, make sure to set UseInitArray to false for this target. This fixes #55938. (cherry picked from commit a2b8c49)
On MinGW targets, the .ctors section is always used for constructors.
Make sure that all layers of code generation is aware of this, wherever it matters, by passing the -fno-use-init-array option, setting the TargetOptions field UseInitArray to false.
This fixes #55938.