[Bug target/108673] ICE with -fstack-clash-protection and noreturn attribute on x86_64-w64-mingw32

2023-02-14 Thread franke at computer dot org via Gcc-bugs
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

2023-02-04 Thread franke at computer dot org via Gcc-bugs
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()

2020-10-09 Thread franke at computer dot org via Gcc-bugs
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()

2020-10-08 Thread franke at computer dot org via Gcc-bugs
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

2020-02-02 Thread franke at computer dot org
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

2019-10-04 Thread franke at computer dot org
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

2018-06-29 Thread franke at computer dot org
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

2018-06-22 Thread franke at computer dot org
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

2018-06-21 Thread franke at computer dot org
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

2018-06-20 Thread franke at computer dot org
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

2018-06-20 Thread franke at computer dot org
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

2018-06-19 Thread franke at computer dot org
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

2018-06-19 Thread franke at computer dot org
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

2018-06-19 Thread franke at computer dot org
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

2018-06-13 Thread franke at computer dot org
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

2013-03-26 Thread franke at computer dot org


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