[Bug c/95130] GCC ignoring attribute(format(gnu_printf)) on printf in mingw
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130 --- Comment #25 from Martin Storsjö --- (In reply to Andrew Pinski from comment #23) > Note since MSVC 2015 runtime, printf has support %ll so ms_printf should be > fixed to incldue that. > > https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification- > syntax-printf-and-wprintf-functions?view=msvc-140 > > I think for GCC 15, we should just update ms_printf to the 2015 version of > what is supported ... As long as GCC links against msvcrt.dll, distributed with the OS, the time since it's supported in MSVC doesn't affect things much though. But as Liu Hao noted, we already do support %lld in ms_printf since c51f1e7427e6a5ae2a6d82b5a790df77a3adc99a, since it apparently was supported in the OS provided msvcrt.dll since a number of versions anyway. (In reply to LIU Hao from comment #24) > `%L` (for floating-point specifiers) is not compatible between `ms_printf` > and `gnu_printf`. We do use gnu_printf for the UCRT printf functions (which is what MSVC ships since 2015) though, see e.g. https://github.com/mingw-w64/mingw-w64/commit/8565cdb729b96f1122b1e9c490a7baba7b788f18. But since the change in c51f1e7427e6a5ae2a6d82b5a790df77a3adc99a (released in GCC 12 already), we probably don't need this any longer. So I think it might be more correct to revert to ms_printf for UCRT, at least for GCC >= 12 - what do you think?
[Bug c/95130] GCC ignoring attribute(format(gnu_printf)) on printf in mingw
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130 --- Comment #8 from Martin Storsjö --- (In reply to Tomas Kalibera from comment #7) > I sent an updated version for the trunk, 12, 11 and 10 to the gcc-patches > mailing list in May: > > https://gcc.gnu.org/pipermail/gcc-patches/2022-May/594960.html > > The patches still apply to current 10,11,12 and trunk. Please see the email > linked above for more information. Did you notice the review comment in July, https://gcc.gnu.org/pipermail/gcc-patches/2022-July/59.html?
[Bug target/105506] Error building GCC 12.1.0 against MinGW-w64: fatal error: cannot execute 'cc1': CreateProcess: No such file or directory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105506 --- Comment #8 from Martin Storsjö --- (In reply to Brecht Sanders from comment #7) > So I guess the question that remains is: Where is -D__USE_MINGW_ACCES > missing in the configuration of GCC 12? > > It would seem to me the answer lies in code added since GCC 11 that contains > access()/X_OK. I bisected, and it seems like a build system adjustment makes it lose the flags that are added in config/mh-mingw (where they are added to CFLAGS, CXXFLAGS and a bunch of other *_CXXFLAGS). The built GCC reproduces the issue since this commit: https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=4a5e71f2348adcc49939804889d9f1a64d97005a Unfortunately, the build system changes here are slightly complex, so it's not entirely obvious to me where the flags that are added to CFLAGS/CXXFLAGS are lost. (Due to other commits around it, cross compiling GCC from linux to windows fails entirely, until a couple commits later though - https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=ab18659afc054434cef4d4757a3519f1100adc52 - but I tested the commit above with this one cherrypicked on top.)
[Bug target/105506] Error building GCC 12.1.0 against MinGW-w64: fatal error: cannot execute 'cc1': CreateProcess: No such file or directory
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105506 Martin Storsjö changed: What|Removed |Added CC||martin at martin dot st --- Comment #6 from Martin Storsjö --- This is an old longstanding issue that seems to have reappeared, but which has been fixed differently recently in the very latest mingw-w64 git. But first a brief history of the issue: GCC uses the access() function for checking whether a binary exists and is executable (with the X_OK flag as parameter). On Windows, there's no separate "execute" permission bit, but the X_OK bit (which isn't a documented parameter from Microsoft's side) used to be ignored. In Vista, msvcrt.dll's access() function suddenly stopped ignoring the bit that was used for X_OK (which mingw had decided to use for that purpose), and started erroring out when this bit was set. This was dealt with in 2007 in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=33281, by adding a reimplementation of the access() function in mingw. By defining __USE_MINGW_ACCESS, the access() function is redirected to the __mingw_access() function. GCC set -D__USE_MINGW_ACCESS when building on mingw to include this workaround. After some time, it seems like Microsoft reverted this behaviour in msvcrt.dll's access() function, because now it no longer seems like this behaviour is present, not on modern Windows 10, but not even on "modern" installations of Vista either. So the need for -D__USE_MINGW_ACCESS has vanished (and bitrotted in GCC somewhat). UCRT's access() function does have the same issue though - if passed the undocumented, mingw-invented X_OK bit, it errors out. As GCC did try to define __USE_MINGW_ACCESS, the workaround should have been picked up though, but as GCC's codebase had evolved, the define wasn't being set in all the cases where it might have been needed. This was fixed for GCC 11 in https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=89e95ad2e7679322b2f5ee9070ff2721d5ca1d6d (and later backported to GCC 9 and 10 in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101238). But apparently something has changed further in GCC 12, so that this define doesn't end up set in all the places where it needs to. (It'd be interesting to know why/where/when!) In mingw-w64, we decided to enable this workaround unconditionally for UCRT (as a more general fix for other audiences, although GCC is the only one I've heard of needing it) - skipping the UCRT provided access() function and always using the mingw reimplementation, see https://github.com/mingw-w64/mingw-w64/commit/bceadc54d8f32b3f14c69074892e2718eac08e3b. So to successfully build GCC 12 running on UCRT, you'd need to use another GCC install, with the very latest mingw-w64 (or an older release with that fix cherry-picked, plus the following Makefile.in update from https://github.com/mingw-w64/mingw-w64/commit/89bacd2be60fa92dd74d3b5f2074b06a32d8c784), to build GCC 12. Alternatively, see if you can manually pass -D__USE_MINGW_ACCESS to the GCC 12 build, if it'd end up in all the places where it's needed.
[Bug c/103956] New: [10 Regression] -Wstringop-overflow= false positive on -O3 for writes to array
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103956 Bug ID: 103956 Summary: [10 Regression] -Wstringop-overflow= false positive on -O3 for writes to array Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: martin at martin dot st Target Milestone: --- Since GCC 10.0, the following snippet produces warnings (various numbers of warnings with the same issue) for this reduced snippet: $ cat repro.c struct data { unsigned char array[10]; }; void copy(struct data *data, unsigned char *src, int n) { int i; for (i = 0; i < n; i++) data->array[i] = src[i]; } $ gcc -c -O3 repro.c repro.c: In function 'copy': repro.c:7:20: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 7 | data->array[i] = src[i]; | ~~~^~~~ repro.c:2:17: note: at offset 10 into destination object 'array' of size 10 2 | unsigned char array[10]; | ^ It doesn't reproduce at -O2. The issue is also testable on Compiler Explorer: https://godbolt.org/z/xsc3K37jK
[Bug target/103274] [10/11/12 regression] remaining -freorder-blocks-and-partition/ glitch with Windows SEH
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103274 --- Comment #11 from Martin Storsjö --- (In reply to Eric Botcazou from comment #10) > Thanks for reporting the problem. Thanks for the fix! I can confirm that the version of the patch backported on the gcc-10 branch fixes the testcase at least. Let's hope that it manages to fix all the instances of the issue in real-world use too.
[Bug target/103274] Remaining -freorder-blocks-and-partition/ glitch with Windows SEH
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103274 --- Comment #4 from Martin Storsjö --- Also for additional context; with GCC 9.x, this testcase had the needed nop instruction between "call" and ".seh_endproc". In GCC 10.x (regressed in https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=095f78c62157124ad479a3f98b6995ced090b807), -freorder-blocks-and-partition applies on this function and it gets split into a hot and cold part, and the needed "nop" instruction disappeared. If building with -fno-reorder-blocks-and-partition, the issue disappears and you get roughly the same output as in GCC 9.x This seems like the same issue as was fixed in https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=15278fb2877184c75a6ee3a6def09efbb191968b;hp=9d3b9a3e70e634c7c48bb12bb35ec8219024f98b - but that fix doesn't seem to help here, as builds of GCC that include that commit still are missing the nop between "call" and ".seh_endproc".
[Bug target/103274] Remaining -freorder-blocks-and-partition/ glitch with Windows SEH
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103274 Martin Storsjö changed: What|Removed |Added CC||martin at martin dot st --- Comment #3 from Martin Storsjö --- (In reply to Eric Botcazou from comment #1) > > -freorder-blocks-and-partition sometimes causes a function to end right in a > > (non-returning) call, but SEH needs at least one more instruction on x86_64. > > Seen in GCC 10.3, 11.2 and git master. Maybe [1] did not cover all the > > cases? > > SEH means "Structured Exception Handling" but there is no exception handling > in this chunk of program since it's written in C and compiled without > -fexceptions, so I'm not quite sure what you're expecting here. Even if it doesn't have explicit exception handling, there's still unwind information generated, and the needed "nop" instruction between the trailing "call" instruction and ".seh_endproc" is missing.
[Bug c/95130] New: GCC ignoring attribute(format(gnu_printf)) on printf in mingw
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130 Bug ID: 95130 Summary: GCC ignoring attribute(format(gnu_printf)) on printf in mingw Product: gcc Version: 9.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: martin at martin dot st Target Milestone: --- Since a long time (GCC 4.4?) GCC does support annotating functions with either the format attribute "gnu_printf" or "ms_printf" to distinguish between different format string interpretations. However, it seems like the attribute is ignored for the "printf" symbol; regardless what the function declaration says, GCC treats it as "ms_printf". This has become an issue now that mingw-w64 supports using the UCRT instead of msvcrt.dll, and in this case the stdio functions are declared with the gnu_printf attribute, and inttypes.h uses the same format specifiers as in GNU mode. A reproducible example of the problem: $ cat format.c __attribute__((__format__ (gnu_printf, 1, 2))) int printf (const char *__format, ...); __attribute__((__format__ (gnu_printf, 1, 2))) int othername (const char *__format, ...); void function(void) { long long unsigned x = 42; othername("%llu\n", x); printf("%llu\n", x); } $ x86_64-w64-mingw32-gcc -c -Wformat format.c format.c: In function 'function': format.c:7:15: warning: unknown conversion type character 'l' in format [-Wformat=] 7 | printf("%llu\n", x); | ^ format.c:7:12: warning: too many arguments for format [-Wformat-extra-args] 7 | printf("%llu\n", x); |^~~~ Note how both functions, printf and othername, are declare with identical gnu_printf format attributes - GCC does take this into account for "othername" and doesn't produce a warning, but GCC seems to disregard the attribute in the printf declaration and behave as if it was declared as ms_printf. If the printf function declaration is changed into a static inline function, the actual attribute used is honored though.
[Bug c++/89088] Dllexport for explicit template instantiation missing inline methods
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89088 --- Comment #1 from Martin Storsjö --- FWIW, Clang (when operating in MinGW mode, where it tries to follow what GCC does) also had the same issue. There this issue was fixed by making dllexport export inline methods as well, for template instantiations: https://github.com/llvm-project/clang/commit/2061b0cab0002c264af632bf5e6ba5306c589c94
[Bug c++/89087] Dllexport for explicit template instantiation with nested classes loses nested class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89087 --- Comment #1 from Martin Storsjö --- FWIW, Clang (when operating in MinGW mode, where it tries to follow what GCC does) also had the same issue. There this issue was fixed by emitting definitions for nested classes even if a template instantiation has been declared, like this: https://github.com/llvm-project/clang/commit/7331c3301af9628719664c9a4feea576df3994a9
[Bug c++/89088] New: Dllexport for explicit template instantiation missing inline methods
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89088 Bug ID: 89088 Summary: Dllexport for explicit template instantiation missing inline methods Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: martin at martin dot st Target Milestone: --- Created attachment 45538 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45538=edit Sample code showing the issue With dllexported explicit template instantiation, inline methods aren't exported, but callers still create undefined references to the inline methods, which fail due to the missing export. (This can be remedied by applying -Wl,--export-all-symbols to export all generated symbols, regardless of dllexport attributes.) Example: header.h: template struct C { void f(); void g() {} }; template void C::f() {} extern template class #ifdef DLLEXPORT __declspec(dllexport) #elif defined(DLLIMPORT) __declspec(dllimport) #endif C; lib.cpp: #define DLLEXPORT #include "header.h" template class C; caller.cpp: #define DLLIMPORT #include "header.h" int main(int argc, char* argv[]) { C a; a.g(); return 0; } Building of this fails in this way: $ make x86_64-w64-mingw32-g++-c -o caller.o caller.cpp x86_64-w64-mingw32-g++-c -o lib.o lib.cpp x86_64-w64-mingw32-g++ -shared -o lib.dll lib.o -Wl,--out-implib,liblib.dll.a x86_64-w64-mingw32-g++ -o caller.exe caller.o -L. -llib caller.o:caller.cpp:(.text+0x1c): undefined reference to `C::g()' collect2: error: ld returned 1 exit status Makefile:5: recipe for target 'caller.exe' failed make: *** [caller.exe] Error 1 The instantiation definition in lib.cpp emitted both methods, but only export the non-inline method: $ x86_64-w64-mingw32-nm lib.o T _ZN1CIcE1fEv T _ZN1CIcE1gEv $ x86_64-w64-mingw32-objdump -s lib.o Contents of section .drectve: 202d6578 706f7274 3a225f5a 4e314349 -export:"_ZN1CI 0010 63453166 45762200cE1fEv". However, despite this, the caller creates an undefined reference to the inline method: $ x86_64-w64-mingw32-nm caller.o T main U _ZN1CIcE1gEv
[Bug c++/89087] New: Dllexport for explicit template instantiation with nested classes loses nested class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89087 Bug ID: 89087 Summary: Dllexport for explicit template instantiation with nested classes loses nested class Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: martin at martin dot st Target Milestone: --- Created attachment 45537 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45537=edit Sample code showing the issue When an explicit template instantiation of a template class with a nested class is declared with the dllexport attribute, only members from the outer class actually gets the embedded export directive. A caller that sees the explicit template instantiation declaration won't emit those symbols but produce undefined references to them (both for the outer and inner class), relying on the template instantiation in a different translation unit. If relying on the dllexport attribute for exporting the relevant symbols, only the outer class' members are exported, and linking to the dll fais. To showcase the problem: header.h: template struct outer { void f(); struct inner { void f(); }; }; template void outer::f() {} template void outer::inner::f() {} extern template class #ifdef DLLEXPORT __declspec(dllexport) #elif defined(DLLIMPORT) __declspec(dllimport) #endif outer; lib.cpp: #define DLLEXPORT #include "header.h" template class outer; caller.cpp: #define DLLIMPORT #include "header.h" int main(int argc, char* argv[]) { outer a; a.f(); outer::inner b; b.f(); return 0; } Building this fails in this way: $ make x86_64-w64-mingw32-g++-c -o caller.o caller.cpp x86_64-w64-mingw32-g++-c -o lib.o lib.cpp x86_64-w64-mingw32-g++ -shared -o lib.dll lib.o -Wl,--out-implib,liblib.dll.a x86_64-w64-mingw32-g++ -o caller.exe caller.o -L. -llib caller.o:caller.cpp:(.text+0x28): undefined reference to `outer::inner::f()' collect2: error: ld returned 1 exit status Makefile:5: recipe for target 'caller.exe' failed make: *** [caller.exe] Error 1 The template instantiation in lib.cpp does get both outer and inner function definitions: $ x86_64-w64-mingw32-nm lib.o T _ZN5outerIcE1fEv T _ZN5outerIcE5inner1fEv And the caller gets undefined references to the same: $ x86_64-w64-mingw32-nm caller.o T main U _ZN5outerIcE1fEv U _ZN5outerIcE5inner1fEv But only the outer function actually ended up exported from the DLL: $ x86_64-w64-mingw32-objdump -s lib.o Contents of section .drectve: 202d6578 706f7274 3a225f5a 4e356f75 -export:"_ZN5ou 0010 74657249 63453166 45762200 terIcE1fEv". If the DLL is linked with -Wl,--export-all-symbols, both functions are exported from the DLL and linking succeeds. This is contrary to MSVC (which admittedly has got an entirely different C++ ABI). In MSVC, the caller emits the inner class' methods despite the explicit template instantiation (both when the template instantiation was marked dllimport, but also if dllimport is omitted): With dllimport: $ cl -nologo -c caller.cpp caller.cpp $ x86_64-w64-mingw32-nm caller.obj T ?f@inner@?$outer@D@@QEAAXXZ U __imp_?f@?$outer@D@@QEAAXXZ T main Without dllimport: $ cat caller.cpp | sed 's/^#def.*//' > caller-nodllimport.cpp $ ~/msvc2017/bin64/cl -nologo -c caller-nodllimport.cpp caller-nodllimport.cpp $ x86_64-w64-mingw32-nm caller-nodllimport.obj T ?f@inner@?$outer@D@@QEAAXXZ U ?f@?$outer@D@@QEAAXXZ T main To solve this (short of requiring using -Wl,--export-all-symbols on any library that uses explicit template instantiation with nested classes), the dllexport either needs to cover the nested class, or an explicit template instantiation should only be considered to cover the outer class.