Patchwork Fix libjava build on current git glibc (PR bootstrap/50888)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 23, 2011, 8:38 p.m.
Message ID <20111123203813.GE27242@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/127385/
State New
Headers show

Comments

Jakub Jelinek - Nov. 23, 2011, 8:38 p.m.
Hi!

As discussed in the PR, libjava fails to build against latest
glibc, because prims.cc is compiled with -fnon-call-exceptions,
uses ctype.h and libgcj isn't linked against -lsupc++ or -lstdc++.
isspace in latest glibc is a throw() inline that calls a throw()
function pointer.  Unfortunately, with -fnon-call-exceptions
the compiler doesn't have a guarantee that the function pointer
that is being called is always valid (it is in glibc) and thus adds
a __cxa_call_unexpected call if the call would throw and that symbol
isn't satisfied during linking of libgcj and apps against it.

In all locales on my box isspace is equivalent to POSIX locale isspace
(while iswspace is true also for various other characters, they are
always multi-byte and thus isspace which works on single byte only
isn't true for them), so this patch effectively makes no difference
in libgcj behavior.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.6?

2011-11-23  Jakub Jelinek  <jakub@redhat.com>

	PR bootstrap/50888
	* prims.cc: Don't include ctype.h.
	(c_isspace): Define.
	(next_property_key, next_property_value): Use it instead
	of isspace.


	Jakub
Tom Tromey - Nov. 23, 2011, 9:14 p.m.
>>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes:

Jakub> 2011-11-23  Jakub Jelinek  <jakub@redhat.com>
Jakub> 	PR bootstrap/50888
Jakub> 	* prims.cc: Don't include ctype.h.
Jakub> 	(c_isspace): Define.
Jakub> 	(next_property_key, next_property_value): Use it instead
Jakub> 	of isspace.

This is ok.

Tom
Tom Tromey - Nov. 23, 2011, 9:24 p.m.
>>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes:

Jakub> As discussed in the PR, libjava fails to build against latest
Jakub> glibc, because prims.cc is compiled with -fnon-call-exceptions,
Jakub> uses ctype.h and libgcj isn't linked against -lsupc++ or -lstdc++.
Jakub> isspace in latest glibc is a throw() inline that calls a throw()
Jakub> function pointer.  Unfortunately, with -fnon-call-exceptions
Jakub> the compiler doesn't have a guarantee that the function pointer
Jakub> that is being called is always valid (it is in glibc) and thus adds
Jakub> a __cxa_call_unexpected call if the call would throw and that symbol
Jakub> isn't satisfied during linking of libgcj and apps against it.

BTW, it seems odd to me that this function is marked throw() instead of
__attribute__((nothrow)).  The latter would avoid this problem entirely.

Tom
Jakub Jelinek - Nov. 24, 2011, 7:09 a.m.
On Wed, Nov 23, 2011 at 02:24:34PM -0700, Tom Tromey wrote:
> >>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes:
> 
> Jakub> As discussed in the PR, libjava fails to build against latest
> Jakub> glibc, because prims.cc is compiled with -fnon-call-exceptions,
> Jakub> uses ctype.h and libgcj isn't linked against -lsupc++ or -lstdc++.
> Jakub> isspace in latest glibc is a throw() inline that calls a throw()
> Jakub> function pointer.  Unfortunately, with -fnon-call-exceptions
> Jakub> the compiler doesn't have a guarantee that the function pointer
> Jakub> that is being called is always valid (it is in glibc) and thus adds
> Jakub> a __cxa_call_unexpected call if the call would throw and that symbol
> Jakub> isn't satisfied during linking of libgcj and apps against it.
> 
> BTW, it seems odd to me that this function is marked throw() instead of
> __attribute__((nothrow)).  The latter would avoid this problem entirely.

Well, appart from -fnon-call-exceptions it should make zero difference.
I guess glibc uses throw() because it is a C++ standard feature, not an
extension.

	Jakub

Patch

--- libjava/prims.cc.jj	2009-05-04 16:46:48.000000000 +0200
+++ libjava/prims.cc	2011-11-23 13:56:34.067198033 +0100
@@ -38,7 +38,6 @@  details.  */
 #endif
 
 #ifndef DISABLE_GETENV_PROPERTIES
-#include <ctype.h>
 #include <java-props.h>
 #define PROCESS_GCJ_PROPERTIES process_gcj_properties()
 #else
@@ -985,6 +984,8 @@  static java::lang::Thread *main_thread;
 
 #ifndef DISABLE_GETENV_PROPERTIES
 
+#define c_isspace(c) (memchr (" \t\n\r\v\f", c, 6) != NULL)
+
 static char *
 next_property_key (char *s, size_t *length)
 {
@@ -993,7 +994,7 @@  next_property_key (char *s, size_t *leng
   JvAssert (s);
 
   // Skip over whitespace
-  while (isspace (*s))
+  while (c_isspace (*s))
     s++;
 
   // If we've reached the end, return NULL.  Also return NULL if for
@@ -1005,7 +1006,7 @@  next_property_key (char *s, size_t *leng
 
   // Determine the length of the property key.
   while (s[l] != 0
-	 && ! isspace (s[l])
+	 && ! c_isspace (s[l])
 	 && s[l] != ':'
 	 && s[l] != '=')
     {
@@ -1027,19 +1028,19 @@  next_property_value (char *s, size_t *le
 
   JvAssert (s);
 
-  while (isspace (*s))
+  while (c_isspace (*s))
     s++;
 
   if (*s == ':'
       || *s == '=')
     s++;
 
-  while (isspace (*s))
+  while (c_isspace (*s))
     s++;
 
   // Determine the length of the property value.
   while (s[l] != 0
-	 && ! isspace (s[l])
+	 && ! c_isspace (s[l])
 	 && s[l] != ':'
 	 && s[l] != '=')
     {