Commit 38927bf
Refine the conditions for the MSVC constinit workaround
As I understand it, the underlying limitation comes from Windows lacking a runtime relocation that can express pointers to symbols in a different dll. In particular, it seems the generated TcParseTable objects reference libprotobuf symbols under _pbi::TcParser. When libprotobuf is built as a dll, this breaks. See #10159.
There is already a workaround that suppresses all of PROTOBUF_CONSTINIT on MSVC. This is, as far as I can tell, both too broad and too narrow. It is too narrow by excluding clang, when the limitation is Windows-wide, not specific to MSVC. It is too broad by including non-PROTOBUF_USE_DLLS builds, when statically-linked libprotobuf is, as I understand it, fine.
This CL changes the condition to check for PROTOBUF_USE_DLLS && _WIN32, to reflect this being a Windows limitation, not a compiler limitation. As a result:
1. clang-cl + PROTOBUF_USE_DLLS now suppresses constinit. This is the configuration that is broken and should now build. This should be low risk. Turning off constinit should only make the compiler accept more things.
2. MSVC + non-PROTOBUF_USE_DLLS + C++20 restores constinit. If the above is correct, non-PROTOBUF_USE_DLLS never needed the workaround. This avoids regressing constinit on staticly-linked Windows. There is some risk here if I'm wrong and we needed the suppression more broadly.
_WIN32 would also cover MinGW and Cygwin, which were written differently. The MinGW suppression was added in #13240 and cited shared libraries, so it seems this is really the same error and now covered by the fixed condition.
The Cygwin suppression was aded in #9562 back in 2022, and it is unclear whether that was being built as a shared library. (The error about std::mutex is also odd but it seems to be an issue with constexpr and not constinit? That may be interesting for 7f431bb, but doesn't seem to be related to constinit specifically.) Regardless, there is now a GCC-wide suppression of constinit, so it is *at least* redundant with it, so I've removed it for now. Though if the GCC suppression is removed, we may later learn that Cygwin had a non-dll issue.
Finally, after 7f431bb, some of the PROTOBUF_CONSTINIT logic was a little odd. The version checks, for instance, are now all no-ops because the fallback case is the same. I've cleaned up that code a bit, but those aren't expected to change behavior.
(It's still arguably a workaround because constinit itself is supported by Windows. protobuf just doesn't generate constinit code in this configuration. A real fix might be to rework TcParseTable to avoid function pointers into libprotobuf? Possibly there are other issues to fix too? Not sure. Or perhaps to just declare this build configuration is only half-supported and has to suffer a static initializer.)
PiperOrigin-RevId: 8552540951 parent 1bc2c63 commit 38927bf
1 file changed
+13
-18
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
416 | 416 | | |
417 | 417 | | |
418 | 418 | | |
419 | | - | |
420 | | - | |
421 | | - | |
422 | | - | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
423 | 426 | | |
424 | | - | |
425 | 427 | | |
426 | 428 | | |
427 | | - | |
428 | 429 | | |
429 | | - | |
430 | | - | |
431 | | - | |
| 430 | + | |
432 | 431 | | |
433 | | - | |
| 432 | + | |
434 | 433 | | |
435 | 434 | | |
436 | 435 | | |
437 | 436 | | |
438 | | - | |
439 | | - | |
440 | | - | |
| 437 | + | |
| 438 | + | |
441 | 439 | | |
442 | 440 | | |
443 | | - | |
444 | | - | |
445 | | - | |
446 | | - | |
447 | | - | |
| 441 | + | |
| 442 | + | |
448 | 443 | | |
449 | 444 | | |
450 | 445 | | |
| |||
0 commit comments