[Bug target/108673] ICE with -fstack-clash-protection and noreturn attribute on x86_64-w64-mingw32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108673 --- Comment #4 from Christian Franke --- I get similar results with x86_64-pc-cygwin-gcc (aka gcc) 11.3.0 and x86_64-w64-mingw32-gcc 11.3.0, both from current Cygwin distro and with x86_64-w64-mingw32-gcc (aka gcc) 12.2.0 from current MSYS2 distro.
[Bug target/108673] ICE with -fstack-clash-protection and noreturn attribute on x86_64-w64-mingw32
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108673 Christian Franke changed: What|Removed |Added CC||franke at computer dot org --- Comment #1 from Christian Franke --- Could also be reproduced with x86_64-pc-cygwin-gcc 11.3.0 and x86_64-w64-mingw32-gcc 11.3.0 from current Cygwin distribution: $ gcc -O1 -fstack-clash-protection -S f.c during RTL pass: final x.c: In function ‘foo’: x.c:5:1: internal compiler error: in seh_emit_stackalloc, at config/i386/winnt.c:1056 5 | } | ^ ... The error does not occur if -fipa-pure-const ("Discover which functions are pure or constant") is disabled: $ gcc -O3 -fno-ipa-pure-const -fstack-clash-protection -S f.c; echo $? 0 Assembly output looks sane then.
[Bug middle-end/97336] False positive -Wstring-compare warning for strncmp()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97336 --- Comment #2 from Christian Franke --- Sorry, but I disagree that this report is INVALID. Unlike for example -Wstringop-overflow, warnings like -Wstring-compare should IMO only occur if the warning condition holds for *all* function calls generated by loop unrolling. BTW, if the partial loop unrolling is done manually, the warning should occur, but does not: int f(const char * p, int n) { char buf[10] = {0, }; int i = 0; if (n <= 0) { if (!__builtin_strncmp(buf, "12345", 5) // <== no warning && (i == 5 || buf[5] == ' ')) // <== warning if removed return 1; } else { do { buf[i] = p[i]; i++; } while (i < (int)sizeof(buf)-1 && i < n); if (!__builtin_strncmp(buf, "12345", 5) && (i == 5 || buf[5] == ' ')) return 1; } return 0; } With the above code, the warning occurs if the condition "&& (i == 5 || buf[5] == ' ')" is removed. If this is done in the original testcase, the warning does no longer occur.
[Bug middle-end/97336] New: False positive -Wstring-compare warning for strncmp()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97336 Bug ID: 97336 Summary: False positive -Wstring-compare warning for strncmp() Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: franke at computer dot org Target Milestone: --- Testcase: $ uname -srvmo CYGWIN_NT-10.0 3.1.7(0.340/5/3) 2020-08-22 17:48 x86_64 Cygwin $ cygcheck -f /usr/bin/gcc gcc-core-10.2.0-1 $ gcc --version gcc (GCC) 10.2.0 ... $ cat test.c int f(const char * p, int n) { char buf[10] = {0, }; int i; for (i = 0; i < (int)sizeof(buf)-1 && i < n; i++) buf[i] = p[i]; if (!__builtin_strncmp(buf, "12345", 5) && (i == 5 || buf[5] == ' ')) return 1; return 0; } $ gcc -Wstring-compare -O2 -c test.c test.c: In function ‘f’: test.c:7:8: warning: ‘__builtin_strncmp’ of strings of length 0 and 5 and bound of 5 evaluates to nonzero [-Wstring-compare] 7 | if (!__builtin_strncmp(buf, "12345", 5) |^~ Apparently it is assumed that the copy loop is never executed. Any of the following single line changes removes the warning: { - char buf[10] = {0, }; + char buf[10]; __builtin_memset(buf, 0, sizeof(buf)); int i; if (!__builtin_strncmp(buf, "12345", 5) - && (i == 5 || buf[5] == ' ')) + && (buf[5] == ' ' || i == 5)) return 1; if (!__builtin_strncmp(buf, "12345", 5) - && (i == 5 || buf[5] == ' ')) + && (!buf[5] || buf[5] == ' ')) return 1;
[Bug other/91989] libssp/spp.c: __[stack_]chk_fail() may run arbitrary code if __builtin_trap() returns
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91989 --- Comment #2 from Christian Franke --- If the builtin is also noreturn on the other (non-x86) platforms, a cosmetic issue remains only: libssp/ssp.c contains dead code with a misleading comment which suggests that __builtin_trap() may return under some unknown circumstances. The section starting with 'Try very hard to exit. ...' could be replaced by __builtin_trap().
[Bug other/91989] New: libssp/spp.c: __[stack_]chk_fail() may run arbitrary code if __builtin_trap() returns
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91989 Bug ID: 91989 Summary: libssp/spp.c: __[stack_]chk_fail() may run arbitrary code if __builtin_trap() returns Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: franke at computer dot org Target Milestone: --- Issue found in MinGW-w64 GCC 7.4.0 from current Cygwin package, but still applies to current SVN trunk (r276567): The abort code used by __[stack_]chk_fail() assumes that something may prevent __builtin_trap() (and segfault) from working: libssp/ssp.c: static void fail (..) { ... /* Try very hard to exit. Note that signals may be blocked preventing the first two options from working. The use of volatile is here to prevent optimizers from "knowing" that __builtin_trap is called first, and that it doesn't return, and so "obviously" the rest of the code is dead. */ { volatile int state; for (state = 0; ; state++) switch (state) { case 0: __builtin_trap (); break; case 1: *(volatile int *)-1L = 0; break; case 2: _exit (127); break; } } } The volatile state variable only prevents that the loop is optimized away, but does not prevent that the compiler assumes an __attribute__((noreturn)) for __builtin_trap(): gcc/builtins.c: void expand_builtin_trap (void) { ... emit_barrier (); } Depending on how the optimizer moves code around, this may result in arbitrary code following __builtin_trap(). In libssp.a from Mingw-w64 GCC 7.0.3, the generated code is equivalent to: volatile int state; for (state = 0; ; state++) switch (state) { case 0: __builtin_trap (); // fall through ... case 2: _exit (127); break; case 1: *(volatile int *)-1L = 0; break; } In this case, we were lucky. But if gcc would decide to move 'case 0:' code to the end of the function, arbitrary code from start of next function would be executed. Conclusion: If there are runtime settings that let __buildin_trap() return, the compiler should not assume an __attribute__((noreturn)) for this builtin. If there are no such settings, the volatile loop in ssp.c is not needed.
[Bug libstdc++/86138] [7/8 Regression] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #25 from Christian Franke --- (In reply to Jonathan Wakely from comment #23) > What if you test with -D_GLIBCXX_ASSERTIONS ? > > (I expect you'll get a crash for either c++14 or c++17) Yes. Fixed with patch from r262167. New Cygwin package gcc-7.3.0-3 includes r261873 but not r262167.
[Bug libstdc++/86138] [7/8 Regression] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #18 from Christian Franke --- With patch from r261873, crash on -std=c++17 does no longer occur with testcase from comment #3. Same for a wchar_t version of the testcase. According to objdump -p, executable now imports _S_empty_rep_storage[] from cygstdc++-6.dll. No new regressions with -std=c++14, -static, -D_GLIBCXX_USE_CXX11_ABI.
[Bug libstdc++/86138] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #13 from Christian Franke --- This patch prevents duplicate _S_empty_rep_storage[] even on Cygwin (char only, wchar_t missing). Testcase works as expected then: --- basic_string.tcc.orig 2018-05-03 06:22:46.0 +0200 +++ basic_string.tcc2018-06-21 13:00:03.370070700 +0200 @@ -1597,7 +1597,8 @@ // Inhibit implicit instantiations for required instantiations, // which are defined via explicit instantiations elsewhere. -#if _GLIBCXX_EXTERN_TEMPLATE > 0 && __cplusplus <= 201402L +#if _GLIBCXX_EXTERN_TEMPLATE > 0 +#if __cplusplus <= 201402L extern template class basic_string; extern template basic_istream& @@ -1627,6 +1628,12 @@ basic_istream& getline(basic_istream&, wstring&); #endif + +#else + extern template +basic_string::size_type +basic_string::_Rep::_S_empty_rep_storage[]; +#endif #endif On Linux and other platforms using ELF the problem does not occur because template static data members use the GNU extension ".type ... @gnu_unique_object" (nm command prints 'u'). Are there possibly other platforms affected? For example: - ELF based platforms were dynamic linker does not support this GNU extension, or - non ELF based platforms without a similar feature.
[Bug libstdc++/86138] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #12 from Christian Franke --- (In reply to Jonathan Wakely from comment #7) > OK, so then this is the whack Windows linker model, where every DLL has its > own address space, and probably the same as PR 81522. Yes. Likely also affects MinGW libstdc++6.dll. > Does Cygwin default to _GLIBCXX_USE_CXX11_ABI=0? Yes. Possible fix for Cygwin: - Rebuild cygstdc++6.dll with C++17 enabled - Disable/Remove '__cplusplus <= 201402L' condition around the extern template block in this case.
[Bug libstdc++/86138] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #11 from Christian Franke --- (In reply to Jonathan Wakely from comment #8) > You still haven't explained why declaring the specialization is bogus. The > explicit specialization is defined at > https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/src/c%2B%2B98/ > istream-string.cc;h=feb3569c8be48539af52b66d6462c455dfd09a47;hb=HEAD#l120 I missed that. Forget the patch. Sorry for the noise.
[Bug libstdc++/86138] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #6 from Christian Franke --- (In reply to Jonathan Wakely from comment #4) > Could you please debug this to find where it's crashing and why? It segfaults with a bogus pointer below std::string::_Rep::_M_dispose(). A comparison of assembly output and object file symbols leads to the root of the problem: 1) -std=c++14: string::string() and getline() are called from cygstdc++6.dll. OK. 2) -std=c++17: getline() is called from cygstdc++6.dll. All code for string::string() is part of the executable. The empty string is initialized with the static std::string::_Rep::_S_empty_rep_storage[] from the executable. But getline() uses the string() implementation from the DLL which checks against the DLL version of _S_empty_rep_storage[] here: _M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT { #if _GLIBCXX_FULLY_DYNAMIC_STRING == 0 if (__builtin_expect(this != &_S_empty_rep(), false)) #endif { ... } This finally results in a bogus delete[] of the _S_empty_rep_storage[] from the executable. 2) -std=c++17 -static: The linker does not pull another _S_empty_rep_storage[] from the static library because it already exists in the object file. OK. This version of the testcase does not crash because _S_empty_rep_storage[] is not used: int main() { std::string line("x"); std::istringstream stream("*"); std::getline(stream, line, '\n'); return (int)line.c_str()[0]; }
[Bug libstdc++/86138] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #5 from Christian Franke --- (In reply to Jonathan Wakely from comment #4) > (In reply to Christian Franke from comment #3) > > > The extern templates are disabled because std::basic_string has additional > > > member functions in C++17 mode, and they're not instantiated in the > > > library. > > > By disabling the explicit instantiation declarations the compiler will > > > emit > > > definitions for the C++17-only member functions. > > This has no effect due to the bogus specialization in basic_string.h (see > > patch below). > > What's bogus about it? Here a simple example which demonstrates the same situation: $ cat bug.cpp template void f(T & x) { x = T(); } #ifndef FIXED template<> void f(int &); // no visible implementation => same effect as extern template below! #endif #if __cplusplus <= 201402L extern template void f(int &); #endif void call_f(int & i) { f(i); } $ g++ -std=c++14 -c -o bug-14.o bug.cpp $ g++ -std=c++17 -c -o bug-17.o bug.cpp $ g++ -std=c++17 -DFIXED -c -o bug-17-fixed.o bug.cpp $ diff -qs bug-14.o bug-17.o ; diff -qs bug-17.o bug-17-fixed.o Files bug-14.o and bug-17.o are identical Files bug-17.o and bug-17-fixed.o differ $ nm -C bug-17.o | grep ' [TU] ' U void f(int&) T call_f(int&) $ nm -C bug-17-fixed.o | grep ' [TU] ' T void f(int&) T call_f(int&) > This patch won't be accepted, it's papering over some other problem not > fixing anything. I disagree. This should be fixed anyway, see above.
[Bug libstdc++/86138] C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 --- Comment #3 from Christian Franke --- (In reply to Jonathan Wakely from comment #1) > Why is the one in the DLL not compatible? I don't know. > The extern templates are disabled because std::basic_string has additional > member functions in C++17 mode, and they're not instantiated in the library. > By disabling the explicit instantiation declarations the compiler will emit > definitions for the C++17-only member functions. This has no effect due to the bogus specialization in basic_string.h (see patch below). > As requested at https://gcc.gnu.org/bugs testcases need to be provided here, > not as URLs. Sorry. New testcase below: $ uname -srvmo CYGWIN_NT-10.0 2.10.0(0.325/5/3) 2018-02-02 15:16 x86_64 Cygwin $ g++ --version g++ (GCC) 7.3.0 $ cygcheck -f /bin/cygstdc++-6.dll libstdc++6-7.3.0-2 $ cat getlinetest.cpp #include int main() { std::string line; std::istringstream stream("*"); std::getline(stream, line, '\n'); return (int)line.c_str()[0]; } $ g++ -o getlinetest getlinetest.cpp && ./getlinetest; echo $? 42 $ g++ -std=c++17 -o getlinetest getlinetest.cpp && ./getlinetest; echo $? Aborted (core dumped) 134 $ g++ -std=c++17 -static -o getlinetest getlinetest.cpp && ./getlinetest;\ echo $? 42 Interestingly the statically linked version works. Is there possibly some template function called by getline() which is not C++17 compatible? In the static case the new version of this function from getline.o is used instead of the old one in the lib*.a file. Possible fix (char only, should also be done for wchar_t): $ cat basic_string.h.patch --- basic_string.h.orig 2018-05-03 06:22:46.0 +0200 +++ basic_string.h 2018-06-19 07:49:50.190322000 +0200 @@ -6329,11 +6329,6 @@ { return std::getline(__is, __str); } #endif - template<> -basic_istream& -getline(basic_istream& __in, basic_string& __str, - char __delim); - #ifdef _GLIBCXX_USE_WCHAR_T template<> basic_istream& $ (cd /usr/lib/gcc/x86_64-pc-cygwin/7.3.0/include/c++/bits && patch) \ < basic_string.h.patch patching file basic_string.h $ g++ -std=c++17 -o getlinetest getlinetest.cpp && ./getlinetest; echo $? 42
[Bug libstdc++/86138] New: C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138 Bug ID: 86138 Summary: C++17: getline(istream, string) crashes on Cygwin because incompatible C++14 function is called Product: gcc Version: 7.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: franke at computer dot org Target Milestone: --- The function std::getline(istream &, string &, char) crashes if build with Cygwin gcc-g++-7.3.0-2 and -std=gnu++17 enabled. This is because there is a bogus prototype specialization in basic_string.h: template<> basic_istream& getline(basic_istream& __in, basic_string& __str, char __delim); There is no implementation for this specialization. This has apparently the same effect as the 'extern template' which is disabled for C++17 in basic_string.tcc: #if _GLIBCXX_EXTERN_TEMPLATE > 0 && __cplusplus <= 201402L ... extern template basic_istream& getline(basic_istream&, string&, char); ... #endif As a consequence, no C++17 compatible code for this getline() is generated and the old getline() from cygstdc++-6.dll is called instead. AFAICS the above still holds for current SVN trunk release 261563. For a testcase and a proposed patch see: https://cygwin.com/ml/cygwin/2018-06/msg00125.html
[Bug c++/56747] New: throw segfaults on 64bit Cygwin if -O2 (-freorder-blocks) is used with g++ 4.8.0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56747 Bug #: 56747 Summary: throw segfaults on 64bit Cygwin if -O2 (-freorder-blocks) is used with g++ 4.8.0 Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: critical Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: fra...@computer.org The test program below segfaults during __cxa_throw if -O2 is used. The problem is possibly related to generation of unwinding-information in conjunction with -freorder-blocks optimization. Testcase: $ uname -srvmo CYGWIN_NT-6.1 1.7.18(0.263/5/3) 2013-03-26 14:56 x86_64 Cygwin $ g++ --version g++ (GCC) 4.8.0 $ cat throw.cc #include string static int main_worker(int argc) { std::string s[32]; if (argc 2) throw 42; return argc; } int main(int argc, char **argv) { try { return main_worker(argc); } catch (int i) { return i; } } $ g++ -O1 -o throw throw.cc $ ./throw; echo $? 42 $ g++ -O2 -o throw throw.cc $ ./throw; echo $? Segmentation fault 139 $ g++ -O2 -fno-reorder-blocks -o throw throw.cc $ ./throw; echo $? 42 $ g++ -O1 -freorder-blocks -g -o throw throw.cc $ ./throw; echo $? Segmentation fault 139 $ gdb throw ... (gdb) r Starting program: /tmp/throw/throw [New Thread 4164.0xe58] [New Thread 4164.0x7e8] gdb: unknown target exception 0x20474343 at 0x7fefd7c9e5d Program received signal ?, Unknown signal. 0x07fefd7c9e5d in RaiseException () from /cygdrive/c/Windows/system32/KERNELBASE.dll