Usaku NAKAMURA wrote:
> We know that this is a bug of gcc.
> ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33763 )

And I have a workaround that passes "make test" on my ubuntu intrepid box.


Index: branches/ruby_1_9_1/configure.in
===================================================================
--- branches/ruby_1_9_1/configure.in	(revision 21148)
+++ branches/ruby_1_9_1/configure.in	(working copy)
@@ -776,6 +776,68 @@
   yes) ac_cv_func_erf=no;;
 esac
 
+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33763
+# Ubuntu intrepid's libc6 2.8~20080505-0ubuntu7 has this problem.
+# Debian GNU/Linux Etch's libc6 2.3.6.ds1-13etch8 has no problem.
+AC_CACHE_CHECK(for broken ``extern inline'' of glibc-2.7,
+  rb_cv_broken_glibc_extern_inline,
+  [AC_TRY_COMPILE([
+typedef struct
+{
+  void *a;
+  void *b;
+} T;
+extern void *foo (const char *, const char *);
+extern void *bar (void *, const char *, T);
+extern int baz (const char *, int);
+
+extern inline __attribute__ ((always_inline, gnu_inline)) int
+baz (const char *x, int y)
+{
+  return 2;
+}
+
+int
+baz (const char *x, int y)
+{
+  return 1;
+}
+
+int xa, xb;
+
+static void *
+inl (const char *x, const char *y)
+{
+  T t = { &xa, &xb };
+  int *f = (int *) __builtin_malloc (sizeof (int));
+  const char *z;
+  int o = 0;
+  void *r = 0;
+
+  for (z = y; *z; z++)
+    {
+      if (*z == 'r')
+        o |= 1;
+      if (*z == 'w')
+        o |= 2;
+    }
+  if (o == 1)
+    *f = baz (x, 0);
+  if (o == 2)
+    *f = baz (x, 1);
+  if (o == 3)
+    *f = baz (x, 2);
+
+  if (o && *f > 0)
+    r = bar (f, "w", t);
+  return r;
+}],[inl("x", "y")],
+	rb_cv_broken_glibc_extern_inline=no,
+	rb_cv_broken_glibc_extern_inline=yes)])
+case $rb_cv_broken_glibc_extern_inline in
+  yes) AC_DEFINE(HAVE_BROKEN_EXTERN_INLINE);;
+esac
+
 AC_REPLACE_FUNCS(dup2 memmove strerror\
 		 strchr strstr crypt flock vsnprintf\
 		 isnan finite isinf hypot acosh erf tgamma lgamma_r cbrt \
Index: branches/ruby_1_9_1/ChangeLog
===================================================================
--- branches/ruby_1_9_1/ChangeLog	(revision 21148)
+++ branches/ruby_1_9_1/ChangeLog	(working copy)
@@ -1,3 +1,9 @@
+Mon Dec 29 16:03:03 2008  URABE Shyouhei  <shyouhei / ruby-lang.org>
+
+	* sprintf.c: detect broken gcc. [ruby-core:20944]
+
+	* configure.in: ditto.
+
 Sun Dec 28 18:36:33 2008  Yuki Sonoda (Yugui)  <yugui / yugui.jp>
 
 	* test/rubygems/test_gem_command.rb
Index: branches/ruby_1_9_1/sprintf.c
===================================================================
--- branches/ruby_1_9_1/sprintf.c	(revision 21148)
+++ branches/ruby_1_9_1/sprintf.c	(working copy)
@@ -25,6 +25,12 @@
 #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
 #define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n)))
 
+#ifdef HAVE_BROKEN_EXTERN_INLINE
+#undef snprintf
+/*  [ruby-core:20944] */
+#define snprintf rb_snprintf_evil_gcc4_and_glibc2_7_need_this_f_ing_workaround_
+#endif
+
 static void fmt_setup(char*,size_t,int,int,int,int);
 
 static char*
@@ -1082,7 +1088,9 @@
 # endif
 #endif
 #undef vsnprintf
+#ifndef HAVE_BROKEN_EXTERN_INLINE
 #undef snprintf
+#endif
 #define FLOATING_POINT 1
 #define BSD__dtoa ruby_dtoa
 #undef HAVE_VSNPRINTF