diff --git a/.compat-gcc-32.metadata b/.compat-gcc-32.metadata new file mode 100644 index 0000000..72c60aa --- /dev/null +++ b/.compat-gcc-32.metadata @@ -0,0 +1,2 @@ +a84db98823c0ba09ce58bfef3b7b4d29face6b6b SOURCES/gcc-3.2.3-20040701.tar.bz2 +dc1cf5b69b132ba4995adf4427196d77dea11d30 SOURCES/libstdc++-3.3.4-20040818.tar.bz2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e7354d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +SOURCES/gcc-3.2.3-20040701.tar.bz2 +SOURCES/libstdc++-3.3.4-20040818.tar.bz2 diff --git a/SOURCES/compat-libstdc++33++-fully-dynamic-strings.patch b/SOURCES/compat-libstdc++33++-fully-dynamic-strings.patch new file mode 100644 index 0000000..9726836 --- /dev/null +++ b/SOURCES/compat-libstdc++33++-fully-dynamic-strings.patch @@ -0,0 +1,60 @@ +2004-10-28 Paolo Carlini + + PR libstdc++/16612 + * include/bits/basic_string.h (basic_string()): When + _GLIBCXX_FULLY_DYNAMIC_STRING is defined, don't deal with _S_empty_rep. + * include/bits/basic_string.tcc (_S_construct): Likewise. + +--- libstdc++33-v3/include/bits/basic_string.tcc.jj 2002-11-09 18:42:55.000000000 +0100 ++++ libstdc++33-v3/include/bits/basic_string.tcc 2004-11-12 14:17:19.946131774 +0100 +@@ -77,8 +77,10 @@ namespace std + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + input_iterator_tag) + { ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); ++#endif + // Avoid reallocation for common case. + _CharT __buf[100]; + size_type __i = 0; +@@ -137,11 +139,13 @@ namespace std + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + forward_iterator_tag) + { ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); ++#endif + + // NB: Not required, but considered best practice. +- if (__builtin_expect(__beg == _InIter(), 0)) ++ if (__builtin_expect(__beg == _InIter() && __beg != __end, 0)) + __throw_logic_error("attempt to create string with null pointer"); + + size_type __dnew = static_cast(std::distance(__beg, __end)); +@@ -166,8 +170,10 @@ namespace std + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); ++#endif + + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, __a); +--- libstdc++33-v3/include/bits/basic_string.h.jj 2002-05-22 15:39:29.000000000 +0200 ++++ libstdc++33-v3/include/bits/basic_string.h 2004-11-12 14:14:42.831975711 +0100 +@@ -923,7 +923,11 @@ namespace std + template + inline basic_string<_CharT, _Traits, _Alloc>:: + basic_string() ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { } ++#else ++ : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } ++#endif + + // operator+ + template diff --git a/SOURCES/compat-libstdc++33++-symver2.patch b/SOURCES/compat-libstdc++33++-symver2.patch new file mode 100644 index 0000000..e625dee --- /dev/null +++ b/SOURCES/compat-libstdc++33++-symver2.patch @@ -0,0 +1,36 @@ +2005-05-13 Jakub Jelinek + + * src/globals.cc (_GLIBCPP_ASM_SYMVER): For non-PIC, redefine to a + hidden alias. + * src/locale.cc (_GLIBCPP_ASM_SYMVER): Likewise. + +--- libstdc++33-v3/src/globals.cc.jj 2002-10-23 01:24:11.000000000 +0200 ++++ libstdc++33-v3/src/globals.cc 2005-05-13 12:30:26.000000000 +0200 +@@ -33,6 +33,12 @@ + #include + #include + ++#ifndef PIC ++# undef _GLIBCPP_ASM_SYMVER ++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \ ++ asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur); ++#endif ++ + // On AIX, and perhaps other systems, library initialization order is + // not guaranteed. For example, the static initializers for the main + // program might run before the static initializers for this library. +--- libstdc++33-v3/src/locale.cc.jj 2003-01-17 18:44:45.000000000 +0100 ++++ libstdc++33-v3/src/locale.cc 2005-05-13 13:02:36.000000000 +0200 +@@ -34,6 +34,12 @@ + #include + #include + ++#ifndef PIC ++# undef _GLIBCPP_ASM_SYMVER ++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \ ++ asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur); ++#endif ++ + namespace __gnu_cxx + { + // Defined in globals.cc. diff --git a/SOURCES/compat-libstdc++33-cxa_demangle-ambiguity.patch b/SOURCES/compat-libstdc++33-cxa_demangle-ambiguity.patch new file mode 100644 index 0000000..0689886 --- /dev/null +++ b/SOURCES/compat-libstdc++33-cxa_demangle-ambiguity.patch @@ -0,0 +1,49 @@ +2005-02-15 Jakub Jelinek + + PR libstdc++/19946 + * testsuite/demangle/abi_examples/01.cc (main): Adjust for 2005-02-13 + demangler change. + * testsuite/demangle/abi_examples/02.cc (main): Likewise. + +--- libstdc++33-v3/testsuite/demangle/abi_examples/01.cc.jj 2004-03-09 16:09:24.000000000 +0100 ++++ libstdc++33-v3/testsuite/demangle/abi_examples/01.cc 2005-02-14 09:05:09.383834357 +0100 +@@ -1,6 +1,6 @@ + // 2003-02-26 Benjamin Kosnik + +-// Copyright (C) 2003 Free Software Foundation, Inc. ++// Copyright (C) 2003, 2005 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +@@ -31,7 +31,9 @@ int main() + // extern "C" function + // extern "C" float f(void) { }; + // T f +- verify_demangle("f", "error code = -2: invalid mangled name"); ++ // f is ambiguous between "C" external name and internal built-in type ++ // name. The ambiguity is resolved to the built-in type name. ++ verify_demangle("f", "float"); + + return 0; + } +--- libstdc++33-v3/testsuite/demangle/abi_examples/02.cc.jj 2004-03-09 16:09:24.000000000 +0100 ++++ libstdc++33-v3/testsuite/demangle/abi_examples/02.cc 2005-02-14 09:05:59.661857808 +0100 +@@ -1,6 +1,6 @@ + // 2003-02-26 Benjamin Kosnik + +-// Copyright (C) 2003 Free Software Foundation, Inc. ++// Copyright (C) 2003, 2005 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +@@ -31,7 +31,9 @@ int main() + // or variable "f" + // int f; + // B f +- verify_demangle("f", "error code = -2: invalid mangled name"); ++ // f is ambiguous between variable external name and internal built-in type ++ // name. The ambiguity is resolved to the built-in type name. ++ verify_demangle("f", "float"); + + return 0; + } diff --git a/SOURCES/compat-libstdc++33-incdir.patch b/SOURCES/compat-libstdc++33-incdir.patch new file mode 100644 index 0000000..b64d8c5 --- /dev/null +++ b/SOURCES/compat-libstdc++33-incdir.patch @@ -0,0 +1,33 @@ +--- libstdc++33-v3/aclocal.m4.jj 2004-06-24 12:06:53.000000000 -0400 ++++ libstdc++33-v3/aclocal.m4 2004-10-14 12:58:50.000000000 -0400 +@@ -1956,7 +1956,7 @@ AC_MSG_RESULT($version_specific_libs) + + # Default case for install directory for include files. + if test $version_specific_libs = no && test $gxx_include_dir = no; then +- gxx_include_dir='$(prefix)'/include/c++/${gcc_version} ++ gxx_include_dir='$(prefix)'/include/c++/3.3.4 + fi + + # Version-specific runtime libs processing. +--- libstdc++33-v3/acinclude.m4.jj 2004-06-24 12:06:53.000000000 -0400 ++++ libstdc++33-v3/acinclude.m4 2004-10-14 12:59:32.000000000 -0400 +@@ -1944,7 +1944,7 @@ AC_MSG_RESULT($version_specific_libs) + + # Default case for install directory for include files. + if test $version_specific_libs = no && test $gxx_include_dir = no; then +- gxx_include_dir='$(prefix)'/include/c++/${gcc_version} ++ gxx_include_dir='$(prefix)'/include/c++/3.3.4 + fi + + # Version-specific runtime libs processing. +--- libstdc++33-v3/configure.jj 2004-10-14 12:35:55.000000000 -0400 ++++ libstdc++33-v3/configure 2004-10-14 13:00:05.000000000 -0400 +@@ -24109,7 +24109,7 @@ echo "$ac_t""$version_specific_libs" 1>& + + # Default case for install directory for include files. + if test $version_specific_libs = no && test $gxx_include_dir = no; then +- gxx_include_dir='$(prefix)'/include/c++/${gcc_version} ++ gxx_include_dir='$(prefix)'/include/c++/3.3.4 + fi + + # Version-specific runtime libs processing. diff --git a/SOURCES/compat-libstdc++33-ldbl.patch b/SOURCES/compat-libstdc++33-ldbl.patch new file mode 100644 index 0000000..3ed79c0 --- /dev/null +++ b/SOURCES/compat-libstdc++33-ldbl.patch @@ -0,0 +1,45 @@ +--- libstdc++33-v3/libmath/stubs.c.jj 2003-06-03 08:48:02.000000000 -0400 ++++ libstdc++33-v3/libmath/stubs.c 2006-08-21 09:18:10.000000000 -0400 +@@ -27,9 +27,29 @@ + invalidate any other reasons why the executable file might be covered by + the GNU General Public License. */ + ++#if defined __s390__ || defined __powerpc__ ++/* Lie. */ ++#define __LONG_DOUBLE_128__ 1 ++#endif ++ + #include + #include "config.h" + ++#if defined __s390__ || defined __powerpc__ ++#undef HAVE_ATAN2L ++#undef HAVE_COSHL ++#undef HAVE_COSL ++#undef HAVE_EXPL ++#undef HAVE_LOG10L ++#undef HAVE_LOGL ++#undef HAVE_POWL ++#undef HAVE_SINHL ++#undef HAVE_SINL ++#undef HAVE_SQRTL ++#undef HAVE_TANHL ++#undef HAVE_TANL ++#endif ++ + /* For targets which do not have support for long double versions, + we use the crude approximation. We'll do better later. */ + +@@ -137,6 +157,12 @@ hypotl(long double x, long double y) + x /= s; y /= s; + return s * sqrtl(x * x + y * y); + } ++#elif (defined __s390__ || defined __powerpc__) && defined HAVE_HYPOT ++long double ++hypotl(long double x, long double y) ++{ ++ return hypot((double) x, (double) y); ++} + #endif + + diff --git a/SOURCES/compat-libstdc++33-limits.patch b/SOURCES/compat-libstdc++33-limits.patch new file mode 100644 index 0000000..4803a55 --- /dev/null +++ b/SOURCES/compat-libstdc++33-limits.patch @@ -0,0 +1,2715 @@ +2004-10-14 Jakub Jelinek + + * include/std/std_limits.h: For GCC 3.2.x and earlier include + GCC 3.2.3 std_limits.h. + + Revert: + 2002-09-25 Benjamin Kosnik + + * include/Makefile.am (target_headers): Remove cpu_limits.h. + * include/Makefile.in: Regenerate. + * configure.in (CPU_LIMITS_INC_SRCDIR): Remove + * configure: Regenerate. + * configure.target (CPULIMITS): Remove. + + * config/os/solaris/solaris2.7/os_defines.h (__glibcpp_long_bits): + Remove. + * config/os/irix/irix6.5/os_defines.h + (__glibcpp_long_double_bits): Remove. + (__glibcpp_wchar_t_bits): Remove. + (__glibcpp_long_bits): Remove. + * config/os/irix/irix5.2/os_defines.h + (__glibcpp_long_double_bits): Remove. + (__glibcpp_long_bits): Remove. + * config/os/hpux/os_defines.h (__glibcpp_wchar_t_is_signed): Remove. + * config/os/bsd/freebsd/os_defines.h: + (__glibcpp_long_double_bits): Remove. + * config/os/aix/os_defines.h (__glibcpp_wchar_t_bits): Remove. + (__glibcpp_wchar_t_is_signed): Remove. + (__glibcpp_long_bits): Remove. + * config/os/gnu-linux/os_defines.h (__glibcpp_long_bits): Remove. + (__glibcpp_long_double_bits): Remove. + + * config/os/osf/osf5.0/cpu_limits.h: Remove. + * config/cpu/alpha/cpu_limits.h: Remove. + * config/cpu/arm/cpu_limits.h: Remove. + * config/cpu/cris/cpu_limits.h: Remove. + * config/cpu/generic/cpu_limits.h: Remove. + * config/cpu/generic/limits.h: Remove. + * config/cpu/ia64/cpu_limits.h: Remove. + * config/cpu/m68k/cpu_limits.h: Remove. + * config/cpu/mmix/cpu_limits.h: Remove. + * config/cpu/powerpc/cpu_limits.h: Remove. + * config/cpu/S390/cpu_limits.h: Remove. + +--- libstdc++33-v3/libmath/Makefile.in.jj 2003-03-17 14:07:39.000000000 -0500 ++++ libstdc++33-v3/libmath/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/libsupc++/Makefile.in.jj 2004-06-28 18:29:56.000000000 -0400 ++++ libstdc++33-v3/libsupc++/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -82,6 +82,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/src/Makefile.in.jj 2004-01-20 06:36:07.000000000 -0500 ++++ libstdc++33-v3/src/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -82,6 +82,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/config/os/bsd/freebsd/os_defines.h.jj 2003-05-15 18:08:04.000000000 -0400 ++++ libstdc++33-v3/config/os/bsd/freebsd/os_defines.h 2004-10-14 12:28:01.000000000 -0400 +@@ -41,4 +41,6 @@ + #define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_CHECK 1 + #define _GLIBCPP_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC defined _XOPEN_SOURCE + ++#define __glibcpp_long_double_bits __glibcpp_double_bits ++ + #endif +--- libstdc++33-v3/config/os/aix/os_defines.h.jj 2002-09-26 01:25:10.000000000 -0400 ++++ libstdc++33-v3/config/os/aix/os_defines.h 2004-10-14 12:28:01.000000000 -0400 +@@ -55,4 +55,13 @@ + #undef _G_USING_THUNKS + #define _G_USING_THUNKS 0 + ++#if !defined(_AIX51) || !defined(__64BIT__) ++#define __glibcpp_wchar_t_bits 16 ++#define __glibcpp_wchar_t_is_signed false ++#endif ++ ++#ifdef __64BIT__ ++#define __glibcpp_long_bits 64 ++#endif ++ + #endif +--- libstdc++33-v3/config/os/gnu-linux/os_defines.h.jj 2002-09-26 01:25:10.000000000 -0400 ++++ libstdc++33-v3/config/os/gnu-linux/os_defines.h 2004-10-14 12:52:11.000000000 -0400 +@@ -65,4 +65,95 @@ typedef __loff_t __off64_t; + #define __NO_STRING_INLINES + #endif + ++#if (defined(__hppa__) && defined(__LP64__)) || defined(__powerpc64__) || defined(__s390x__) || (defined(__sparc__) && defined(__arch64__)) ++#define __glibcpp_long_bits 64 ++#endif ++ ++#if defined(__hppa__) || (defined(__sparc__) && !defined(__arch64__)) ++#define __glibcpp_long_double_bits 64 ++#endif ++ ++/* RHEL3 hack. */ ++#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__IBMCPP__) \ ++ && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__) \ ++ || defined(__s390__) || defined(__s390x__) || defined(__powerpc__) \ ++ || defined(__powerpc64__)) ++#define __glibcpp_float_has_quiet_NaN true ++#define __glibcpp_float_has_signaling_NaN true ++#define __glibcpp_float_has_denorm denorm_present ++#define __glibcpp_float_has_infinity true ++#define __glibcpp_float_round_style round_to_nearest ++#define __glibcpp_float_is_iec559 true ++#define __glibcpp_double_has_quiet_NaN true ++#define __glibcpp_double_has_signaling_NaN true ++#define __glibcpp_double_has_denorm denorm_present ++#define __glibcpp_double_has_infinity true ++#define __glibcpp_double_round_style round_to_nearest ++#define __glibcpp_double_is_iec559 true ++#define __glibcpp_long_double_has_quiet_NaN true ++#define __glibcpp_long_double_has_signaling_NaN true ++#define __glibcpp_long_double_has_denorm denorm_present ++#define __glibcpp_long_double_has_infinity true ++#define __glibcpp_long_double_round_style round_to_nearest ++#define __glibcpp_long_double_is_iec559 true ++ ++#define __glibcpp_f32_round_error 0.5F ++#define __glibcpp_f64_round_error 0.5 ++#define __glibcpp_f80_round_error 0.5L ++#define __glibcpp_f96_round_error 0.5L ++#define __glibcpp_f128_round_error 0.5L ++ ++#define __glibcpp_float_infinity 1.0e+40F ++#define __glibcpp_double_infinity 1.0e+320 ++#define __glibcpp_long_double_infinity 1.0e+5000L ++ ++#define __glibcpp_float_denorm_min 1.40129846e-45F ++#define __glibcpp_double_denorm_min 4.9406564584124654e-324 ++ ++#define __glibcpp_float_quiet_NaN \ ++ (__extension__ ((union { unsigned int __l; float __d; }) \ ++ { __l: 0x7fc00000 }).__d) ++#define __glibcpp_double_quiet_NaN \ ++ (__extension__ ((union { unsigned long long __l; double __d; }) \ ++ { __l: 0x7ff8000000000000ULL }).__d) ++ ++#define __glibcpp_float_signaling_NaN \ ++ (__extension__ ({ union { unsigned int __l; float __d; } __u; \ ++ __u.__l = 0x7fa00000; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++#define __glibcpp_double_signaling_NaN \ ++ (__extension__ ({ union { unsigned long long __l; double __d; } __u; \ ++ __u.__l = 0x7ff4000000000000ULL; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++ ++#if __glibcpp_long_double_bits == 80 ++ ++#define __glibcpp_long_double_denorm_min 3.64519953188247460253e-4951L ++#define __glibcpp_long_double_quiet_NaN \ ++ (__extension__ ({ union { unsigned long long __l[2]; \ ++ long double __d; } __u; \ ++ __u.__l[0] = 0xcULL << 60; __u.__l[1] = 0x7fff; \ ++ __u.__d; })) ++#define __glibcpp_long_double_signaling_NaN \ ++ (__extension__ ({ union { unsigned long long __l[2]; \ ++ long double __d; } __u; \ ++ __u.__l[0] = 0xaULL << 60; __u.__l[1] = 0x7fff; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++ ++#else ++ ++#define __glibcpp_long_double_denorm_min 4.9406564584124654e-324L ++#define __glibcpp_long_double_quiet_NaN \ ++ (__extension__ ((union { unsigned long long __l; long double __d; }) \ ++ { __l: 0x7ff8000000000000ULL }).__d) ++#define __glibcpp_long_double_signaling_NaN \ ++ (__extension__ ({ union { unsigned long long __l; \ ++ long double __d; } __u; \ ++ __u.__l = 0x7ff4000000000000ULL; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++ ++#endif ++ ++#endif ++ + #endif +--- libstdc++33-v3/config/os/hpux/os_defines.h.jj 2003-09-04 08:39:34.000000000 -0400 ++++ libstdc++33-v3/config/os/hpux/os_defines.h 2004-10-14 12:28:01.000000000 -0400 +@@ -37,6 +37,8 @@ + #define __off64_t off64_t + #define __ssize_t ssize_t + ++#define __glibcpp_wchar_t_is_signed false ++ + // Use macro form of ctype functions to ensure __SB_masks is defined. + #define _SB_CTYPE_MACROS 1 + +--- libstdc++33-v3/config/os/irix/irix5.2/os_defines.h.jj 2002-09-26 01:25:11.000000000 -0400 ++++ libstdc++33-v3/config/os/irix/irix5.2/os_defines.h 2004-10-14 12:28:01.000000000 -0400 +@@ -51,5 +51,11 @@ + // GCC does not use thunks on IRIX. + #define _G_USING_THUNKS 0 + ++#define __glibcpp_long_double_bits 64 ++ ++#if __LONG_MAX__ > 2147483647 ++#define __glibcpp_long_bits 64 ++#endif ++ + #endif + +--- libstdc++33-v3/config/os/irix/irix6.5/os_defines.h.jj 2002-09-26 01:25:11.000000000 -0400 ++++ libstdc++33-v3/config/os/irix/irix6.5/os_defines.h 2004-10-14 12:28:01.000000000 -0400 +@@ -51,5 +51,12 @@ + // GCC does not use thunks on IRIX. + #define _G_USING_THUNKS 0 + ++#define __glibcpp_long_double_bits 64 ++ ++#if __LONG_MAX__ > 2147483647 ++#define __glibcpp_wchar_t_bits 64 ++#define __glibcpp_long_bits 64 ++#endif ++ + #endif + +--- libstdc++33-v3/config/os/solaris/solaris2.7/os_defines.h.jj 2002-09-26 01:25:11.000000000 -0400 ++++ libstdc++33-v3/config/os/solaris/solaris2.7/os_defines.h 2004-10-14 12:28:01.000000000 -0400 +@@ -39,5 +39,9 @@ + #define __off64_t off64_t + #define __ssize_t ssize_t + ++#if defined(__sparcv9) || defined(__arch64__) ++#define __glibcpp_long_bits 64 ++#endif ++ + #endif + +--- libstdc++33-v3/config/cpu/alpha/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/alpha/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,38 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#define __glibcpp_long_bits 64 ++ ++#define __glibcpp_long_double_bits 64 ++ ++#endif ++ ++ ++ +--- libstdc++33-v3/config/cpu/s390/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/s390/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,33 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#define __glibcpp_long_double_bits 64 ++ ++#endif +--- libstdc++33-v3/config/cpu/cris/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/cris/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,33 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#define __glibcpp_long_double_bits 64 ++ ++#endif +--- libstdc++33-v3/config/cpu/powerpc/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/powerpc/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,42 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#ifdef __powerpc64__ ++#define __glibcpp_long_bits 64 ++#endif ++ ++#ifndef __LONG_DOUBLE_128__ ++#define __glibcpp_long_double_bits 64 ++#endif ++ ++#endif ++ ++ ++ +--- libstdc++33-v3/config/cpu/i386/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/i386/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,33 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#define __glibcpp_long_double_bits 80 ++ ++#endif +--- libstdc++33-v3/config/cpu/m68k/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/m68k/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,35 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#define __glibcpp_long_double_bits 96 ++ ++#endif ++ ++ +--- libstdc++33-v3/config/cpu/ia64/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/ia64/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,36 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#define __glibcpp_long_bits 64 ++ ++// While sizeof(long double) == 16, the format is the same as the x86. ++#define __glibcpp_long_double_bits 80 ++ ++#endif +--- libstdc++33-v3/config/cpu/generic/cpu_limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/generic/cpu_limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,41 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++// Nothing is defined in the generic file. In that way, we fall back ++// on the defaults in std_limits.h. ++ ++// If you need to override these defaults, you can either use a ++// CPU-specific version (in which case you must modify ++// configure.target) or you must add the overrides to your ++// os_defines.h. In general, if all systems for your CPU use the ++// same values, it is best to use a cpu-specific configuration file. ++ ++#endif ++ +--- libstdc++33-v3/config/cpu/generic/limits.h.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/config/cpu/generic/limits.h 2004-10-14 12:28:01.000000000 -0400 +@@ -0,0 +1,40 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++// Nothing is defined in the generic file. In that way, we fall back ++// on the defaults in std_limits.h. ++ ++// If you need to override these defaults, you can either use a ++// CPU-specific version (in which case you must modify ++// configure.target) or you must add the overrides to your ++// os_defines.h. In general, if all systems for your CPU use the ++// same values, it is best to use a cpu-specific configuration file. ++ ++#endif +--- libstdc++33-v3/config/cpu/x86-64/cpu_limits.h.jj 2004-10-14 12:53:35.000000000 -0400 ++++ libstdc++33-v3/config/cpu/x86-64/cpu_limits.h 2004-10-14 12:53:42.000000000 -0400 +@@ -0,0 +1,37 @@ ++// Copyright (C) 2001 Free Software Foundation, Inc. ++// ++// This file is part of the GNU ISO C++ Library. This library is free ++// software; you can redistribute it and/or modify it under the ++// terms of the GNU General Public License as published by the ++// Free Software Foundation; either version 2, or (at your option) ++// any later version. ++ ++// This library is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++ ++// You should have received a copy of the GNU General Public License along ++// with this library; see the file COPYING. If not, write to the Free ++// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++ ++// As a special exception, you may use this file as part of a free software ++// library without restriction. Specifically, if other files instantiate ++// templates or use macros or inline functions from this file, or you compile ++// this file and link it with other files to produce an executable, this ++// file does not by itself cause the resulting executable to be covered by ++// the GNU General Public License. This exception does not however ++// invalidate any other reasons why the executable file might be covered by ++// the GNU General Public License. ++ ++#ifndef _GLIBCPP_CPU_LIMITS ++#define _GLIBCPP_CPU_LIMITS 1 ++ ++#ifdef __x86_64__ ++#define __glibcpp_long_bits 64 ++#endif ++ ++#define __glibcpp_long_double_bits 80 ++ ++#endif +--- libstdc++33-v3/libio/Makefile.in.jj 2003-03-17 14:07:38.000000000 -0500 ++++ libstdc++33-v3/libio/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/include/std/std_limits.h.jj 2002-12-19 06:44:30.000000000 -0500 ++++ libstdc++33-v3/include/std/std_limits.h 2004-10-14 12:51:05.000000000 -0400 +@@ -45,6 +45,1898 @@ + + #pragma GCC system_header + ++#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ <= 2) ++ ++#include ++#include ++ ++// ++// The numeric_limits<> traits document implementation-defined aspects ++// of fundamental arithmetic data types (integers and floating points). ++// From Standard C++ point of view, there are 13 such types: ++// * integers ++// bool (1) ++// char, signed char, unsigned char (3) ++// short, unsigned short (2) ++// int, unsigned (2) ++// long, unsigned long (2) ++// ++// * floating points ++// float (1) ++// double (1) ++// long double (1) ++// ++// GNU C++ undertstands (where supported by the host C-library) ++// * integer ++// long long, unsigned long long (2) ++// ++// which brings us to 15 fundamental arithmetic data types in GNU C++. ++// ++// ++// Since a numeric_limits<> is a bit tricky to get right, we rely on ++// an interface composed of macros which should be defined in config/os ++// or config/cpu when they differ from the generic (read arbitrary) ++// definitions given here. ++// ++ ++// These values can be overridden in the target configuration file. ++// The default values are appropriate for many 32-bit targets. ++ ++#ifndef __glibcpp_char_bits ++#define __glibcpp_char_bits 8 ++#endif ++#ifdef __CHAR_UNSIGNED__ ++#define __glibcpp_plain_char_is_signed false ++#else ++#define __glibcpp_plain_char_is_signed true ++#endif ++#ifndef __glibcpp_short_bits ++#define __glibcpp_short_bits 16 ++#endif ++#ifndef __glibcpp_int_bits ++#define __glibcpp_int_bits 32 ++#endif ++#ifndef __glibcpp_long_bits ++#define __glibcpp_long_bits 32 ++#endif ++#ifndef __glibcpp_wchar_t_bits ++#define __glibcpp_wchar_t_bits 32 ++#endif ++#ifndef __glibcpp_wchar_t_is_signed ++#define __glibcpp_wchar_t_is_signed true ++#endif ++#ifndef __glibcpp_long_long_bits ++#define __glibcpp_long_long_bits 64 ++#endif ++#ifndef __glibcpp_float_bits ++#define __glibcpp_float_bits 32 ++#endif ++#ifndef __glibcpp_double_bits ++#define __glibcpp_double_bits 64 ++#endif ++#ifndef __glibcpp_long_double_bits ++#define __glibcpp_long_double_bits 128 ++#endif ++ ++#ifndef __glibcpp_char_traps ++#define __glibcpp_char_traps true ++#endif ++#ifndef __glibcpp_short_traps ++#define __glibcpp_short_traps true ++#endif ++#ifndef __glibcpp_int_traps ++#define __glibcpp_int_traps true ++#endif ++#ifndef __glibcpp_long_traps ++#define __glibcpp_long_traps true ++#endif ++#ifndef __glibcpp_wchar_t_traps ++#define __glibcpp_wchar_t_traps true ++#endif ++#ifndef __glibcpp_long_long_traps ++#define __glibcpp_long_long_traps true ++#endif ++ ++// You should not need to define any macros below this point, unless ++// you have a machine with non-standard bit-widths. ++ ++// These values are the minimums and maximums for standard data types ++// of common widths. ++ ++#define __glibcpp_s8_max 127 ++#define __glibcpp_s8_min (-__glibcpp_s8_max - 1) ++#define __glibcpp_s8_digits 7 ++#define __glibcpp_s8_digits10 2 ++#define __glibcpp_u8_min 0U ++#define __glibcpp_u8_max (__glibcpp_s8_max * 2 + 1) ++#define __glibcpp_u8_digits 8 ++#define __glibcpp_u8_digits10 2 ++#define __glibcpp_s16_max 32767 ++#define __glibcpp_s16_min (-__glibcpp_s16_max - 1) ++#define __glibcpp_s16_digits 15 ++#define __glibcpp_s16_digits10 4 ++#define __glibcpp_u16_min 0U ++#define __glibcpp_u16_max (__glibcpp_s16_max * 2 + 1) ++#define __glibcpp_u16_digits 16 ++#define __glibcpp_u16_digits10 4 ++#define __glibcpp_s32_max 2147483647L ++#define __glibcpp_s32_min (-__glibcpp_s32_max - 1) ++#define __glibcpp_s32_digits 31 ++#define __glibcpp_s32_digits10 9 ++#define __glibcpp_u32_min 0UL ++#define __glibcpp_u32_max (__glibcpp_s32_max * 2U + 1) ++#define __glibcpp_u32_digits 32 ++#define __glibcpp_u32_digits10 9 ++#define __glibcpp_s64_max 9223372036854775807LL ++#define __glibcpp_s64_min (-__glibcpp_s64_max - 1) ++#define __glibcpp_s64_digits 63 ++#define __glibcpp_s64_digits10 18 ++#define __glibcpp_u64_min 0ULL ++#define __glibcpp_u64_max (__glibcpp_s64_max * 2ULL + 1) ++#define __glibcpp_u64_digits 64 ++#define __glibcpp_u64_digits10 19 ++ ++#define __glibcpp_f32_min 1.17549435e-38F ++#define __glibcpp_f32_max 3.40282347e+38F ++#define __glibcpp_f32_digits 24 ++#define __glibcpp_f32_digits10 6 ++#define __glibcpp_f32_radix 2 ++#define __glibcpp_f32_epsilon 1.19209290e-07F ++#ifndef __glibcpp_f32_round_error ++#define __glibcpp_f32_round_error 1.0F ++#endif ++#define __glibcpp_f32_min_exponent -125 ++#define __glibcpp_f32_min_exponent10 -37 ++#define __glibcpp_f32_max_exponent 128 ++#define __glibcpp_f32_max_exponent10 38 ++#define __glibcpp_f64_min 2.2250738585072014e-308 ++#define __glibcpp_f64_max 1.7976931348623157e+308 ++#define __glibcpp_f64_digits 53 ++#define __glibcpp_f64_digits10 15 ++#define __glibcpp_f64_radix 2 ++#define __glibcpp_f64_epsilon 2.2204460492503131e-16 ++#ifndef __glibcpp_f64_round_error ++#define __glibcpp_f64_round_error 1.0 ++#endif ++#define __glibcpp_f64_min_exponent -1021 ++#define __glibcpp_f64_min_exponent10 -307 ++#define __glibcpp_f64_max_exponent 1024 ++#define __glibcpp_f64_max_exponent10 308 ++#define __glibcpp_f80_min 3.36210314311209350626e-4932L ++#define __glibcpp_f80_max 1.18973149535723176502e+4932L ++#define __glibcpp_f80_digits 64 ++#define __glibcpp_f80_digits10 18 ++#define __glibcpp_f80_radix 2 ++#define __glibcpp_f80_epsilon 1.08420217248550443401e-19L ++#ifndef __glibcpp_f80_round_error ++#define __glibcpp_f80_round_error 1.0L ++#endif ++#define __glibcpp_f80_min_exponent -16381 ++#define __glibcpp_f80_min_exponent10 -4931 ++#define __glibcpp_f80_max_exponent 16384 ++#define __glibcpp_f80_max_exponent10 4932 ++#define __glibcpp_f96_min 1.68105157155604675313e-4932L ++#define __glibcpp_f96_max 1.18973149535723176502e+4932L ++#define __glibcpp_f96_digits 64 ++#define __glibcpp_f96_digits10 18 ++#define __glibcpp_f96_radix 2 ++#define __glibcpp_f96_epsilon 1.08420217248550443401e-19L ++#ifndef __glibcpp_f96_round_error ++#define __glibcpp_f96_round_error 1.0L ++#endif ++#define __glibcpp_f96_min_exponent -16382 ++#define __glibcpp_f96_min_exponent10 -4931 ++#define __glibcpp_f96_max_exponent 16384 ++#define __glibcpp_f96_max_exponent10 4932 ++#define __glibcpp_f128_min 3.362103143112093506262677817321752603E-4932L ++#define __glibcpp_f128_max 1.189731495357231765085759326628007016E+4932L ++#define __glibcpp_f128_digits 113 ++#define __glibcpp_f128_digits10 33 ++#define __glibcpp_f128_radix 2 ++#define __glibcpp_f128_epsilon 1.925929944387235853055977942584927319E-34L ++#ifndef __glibcpp_f128_round_error ++#define __glibcpp_f128_round_error 1.0L ++#endif ++#define __glibcpp_f128_min_exponent -16381 ++#define __glibcpp_f128_min_exponent10 -4931 ++#define __glibcpp_f128_max_exponent 16384 ++#define __glibcpp_f128_max_exponent10 4932 ++ ++// bool-specific hooks: ++// __glibcpp_bool_digits __glibcpp_int_traps __glibcpp_long_traps ++ ++#ifndef __glibcpp_bool_digits ++#define __glibcpp_bool_digits 1 ++#endif ++ ++// char. ++ ++#define __glibcpp_plain_char_traps true ++#define __glibcpp_signed_char_traps true ++#define __glibcpp_unsigned_char_traps true ++#ifndef __glibcpp_char_is_modulo ++#define __glibcpp_char_is_modulo true ++#endif ++#ifndef __glibcpp_signed_char_is_modulo ++#define __glibcpp_signed_char_is_modulo true ++#endif ++#if __glibcpp_char_bits == 8 ++#define __glibcpp_signed_char_min __glibcpp_s8_min ++#define __glibcpp_signed_char_max __glibcpp_s8_max ++#define __glibcpp_signed_char_digits __glibcpp_s8_digits ++#define __glibcpp_signed_char_digits10 __glibcpp_s8_digits10 ++#define __glibcpp_unsigned_char_min __glibcpp_u8_min ++#define __glibcpp_unsigned_char_max __glibcpp_u8_max ++#define __glibcpp_unsigned_char_digits __glibcpp_u8_digits ++#define __glibcpp_unsigned_char_digits10 __glibcpp_u8_digits10 ++#elif __glibcpp_char_bits == 16 ++#define __glibcpp_signed_char_min __glibcpp_s16_min ++#define __glibcpp_signed_char_max __glibcpp_s16_max ++#define __glibcpp_signed_char_digits __glibcpp_s16_digits ++#define __glibcpp_signed_char_digits10 __glibcpp_s16_digits10 ++#define __glibcpp_unsigned_char_min __glibcpp_u16_min ++#define __glibcpp_unsigned_char_max __glibcpp_u16_max ++#define __glibcpp_unsigned_char_digits __glibcpp_u16_digits ++#define __glibcpp_unsigned_char_digits10 __glibcpp_u16_digits10 ++#elif __glibcpp_char_bits == 32 ++#define __glibcpp_signed_char_min (signed char)__glibcpp_s32_min ++#define __glibcpp_signed_char_max (signed char)__glibcpp_s32_max ++#define __glibcpp_signed_char_digits __glibcpp_s32_digits ++#define __glibcpp_signed_char_digits10 __glibcpp_s32_digits10 ++#define __glibcpp_unsigned_char_min (unsigned char)__glibcpp_u32_min ++#define __glibcpp_unsigned_char_max (unsigned char)__glibcpp_u32_max ++#define __glibcpp_unsigned_char_digits __glibcpp_u32_digits ++#define __glibcpp_unsigned_char_digits10 __glibcpp_u32_digits10 ++#elif __glibcpp_char_bits == 64 ++#define __glibcpp_signed_char_min (signed char)__glibcpp_s64_min ++#define __glibcpp_signed_char_max (signed char)__glibcpp_s64_max ++#define __glibcpp_signed_char_digits __glibcpp_s64_digits ++#define __glibcpp_signed_char_digits10 __glibcpp_s64_digits10 ++#define __glibcpp_unsigned_char_min (unsigned char)__glibcpp_u64_min ++#define __glibcpp_unsigned_char_max (unsigned char)__glibcpp_u64_max ++#define __glibcpp_unsigned_char_digits __glibcpp_u64_digits ++#define __glibcpp_unsigned_char_digits10 __glibcpp_u64_digits10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++#if __glibcpp_plain_char_is_signed ++#define __glibcpp_char_min (char)__glibcpp_signed_char_min ++#define __glibcpp_char_max (char)__glibcpp_signed_char_max ++#define __glibcpp_char_digits __glibcpp_signed_char_digits ++#define __glibcpp_char_digits10 __glibcpp_signed_char_digits10 ++#else ++#define __glibcpp_char_min (char)__glibcpp_unsigned_char_min ++#define __glibcpp_char_max (char)__glibcpp_unsigned_char_max ++#define __glibcpp_char_digits __glibcpp_unsigned_char_digits ++#define __glibcpp_char_digits10 __glibcpp_unsigned_char_digits10 ++#endif ++ ++// short ++ ++#define __glibcpp_signed_short_traps true ++#define __glibcpp_unsigned_short_traps true ++#ifndef __glibcpp_signed_short_is_modulo ++#define __glibcpp_signed_short_is_modulo true ++#endif ++#if __glibcpp_short_bits == 8 ++#define __glibcpp_signed_short_min __glibcpp_s8_min ++#define __glibcpp_signed_short_max __glibcpp_s8_max ++#define __glibcpp_signed_short_digits __glibcpp_s8_digits ++#define __glibcpp_signed_short_digits10 __glibcpp_s8_digits10 ++#define __glibcpp_unsigned_short_min __glibcpp_u8_min ++#define __glibcpp_unsigned_short_max __glibcpp_u8_max ++#define __glibcpp_unsigned_short_digits __glibcpp_u8_digits ++#define __glibcpp_unsigned_short_digits10 __glibcpp_u8_digits10 ++#elif __glibcpp_short_bits == 16 ++#define __glibcpp_signed_short_min __glibcpp_s16_min ++#define __glibcpp_signed_short_max __glibcpp_s16_max ++#define __glibcpp_signed_short_digits __glibcpp_s16_digits ++#define __glibcpp_signed_short_digits10 __glibcpp_s16_digits10 ++#define __glibcpp_unsigned_short_min __glibcpp_u16_min ++#define __glibcpp_unsigned_short_max __glibcpp_u16_max ++#define __glibcpp_unsigned_short_digits __glibcpp_u16_digits ++#define __glibcpp_unsigned_short_digits10 __glibcpp_u16_digits10 ++#elif __glibcpp_short_bits == 32 ++#define __glibcpp_signed_short_min (short)__glibcpp_s32_min ++#define __glibcpp_signed_short_max (short)__glibcpp_s32_max ++#define __glibcpp_signed_short_digits __glibcpp_s32_digits ++#define __glibcpp_signed_short_digits10 __glibcpp_s32_digits10 ++#define __glibcpp_unsigned_short_min (unsigned short)__glibcpp_u32_min ++#define __glibcpp_unsigned_short_max (unsigned short)__glibcpp_u32_max ++#define __glibcpp_unsigned_short_digits __glibcpp_u32_digits ++#define __glibcpp_unsigned_short_digits10 __glibcpp_u32_digits10 ++#elif __glibcpp_short_bits == 64 ++#define __glibcpp_signed_short_min (short)__glibcpp_s64_min ++#define __glibcpp_signed_short_max (short)__glibcpp_s64_max ++#define __glibcpp_signed_short_digits __glibcpp_s64_digits ++#define __glibcpp_signed_short_digits10 __glibcpp_s64_digits10 ++#define __glibcpp_unsigned_short_min (unsigned short)__glibcpp_u64_min ++#define __glibcpp_unsigned_short_max (unsigned short)__glibcpp_u64_max ++#define __glibcpp_unsigned_short_digits __glibcpp_u64_digits ++#define __glibcpp_unsigned_short_digits10 __glibcpp_u64_digits10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// int ++ ++#define __glibcpp_signed_int_traps true ++#define __glibcpp_unsigned_int_traps true ++#ifndef __glibcpp_signed_int_is_modulo ++#define __glibcpp_signed_int_is_modulo true ++#endif ++#if __glibcpp_int_bits == 8 ++#define __glibcpp_signed_int_min __glibcpp_s8_min ++#define __glibcpp_signed_int_max __glibcpp_s8_max ++#define __glibcpp_signed_int_digits __glibcpp_s8_digits ++#define __glibcpp_signed_int_digits10 __glibcpp_s8_digits10 ++#define __glibcpp_unsigned_int_min __glibcpp_u8_min ++#define __glibcpp_unsigned_int_max __glibcpp_u8_max ++#define __glibcpp_unsigned_int_digits __glibcpp_u8_digits ++#define __glibcpp_unsigned_int_digits10 __glibcpp_u8_digits10 ++#elif __glibcpp_int_bits == 16 ++#define __glibcpp_signed_int_min __glibcpp_s16_min ++#define __glibcpp_signed_int_max __glibcpp_s16_max ++#define __glibcpp_signed_int_digits __glibcpp_s16_digits ++#define __glibcpp_signed_int_digits10 __glibcpp_s16_digits10 ++#define __glibcpp_unsigned_int_min __glibcpp_u16_min ++#define __glibcpp_unsigned_int_max __glibcpp_u16_max ++#define __glibcpp_unsigned_int_digits __glibcpp_u16_digits ++#define __glibcpp_unsigned_int_digits10 __glibcpp_u16_digits10 ++#elif __glibcpp_int_bits == 32 ++#define __glibcpp_signed_int_min (int)__glibcpp_s32_min ++#define __glibcpp_signed_int_max (int)__glibcpp_s32_max ++#define __glibcpp_signed_int_digits __glibcpp_s32_digits ++#define __glibcpp_signed_int_digits10 __glibcpp_s32_digits10 ++#define __glibcpp_unsigned_int_min (unsigned)__glibcpp_u32_min ++#define __glibcpp_unsigned_int_max (unsigned)__glibcpp_u32_max ++#define __glibcpp_unsigned_int_digits __glibcpp_u32_digits ++#define __glibcpp_unsigned_int_digits10 __glibcpp_u32_digits10 ++#elif __glibcpp_int_bits == 64 ++#define __glibcpp_signed_int_min (int)__glibcpp_s64_min ++#define __glibcpp_signed_int_max (int)__glibcpp_s64_max ++#define __glibcpp_signed_int_digits __glibcpp_s64_digits ++#define __glibcpp_signed_int_digits10 __glibcpp_s64_digits10 ++#define __glibcpp_unsigned_int_min (unsigned)__glibcpp_u64_min ++#define __glibcpp_unsigned_int_max (unsigned)__glibcpp_u64_max ++#define __glibcpp_unsigned_int_digits __glibcpp_u64_digits ++#define __glibcpp_unsigned_int_digits10 __glibcpp_u64_digits10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// long ++ ++#define __glibcpp_signed_long_traps true ++#define __glibcpp_unsigned_long_traps true ++#ifndef __glibcpp_signed_long_is_modulo ++#define __glibcpp_signed_long_is_modulo true ++#endif ++#if __glibcpp_long_bits == 8 ++#define __glibcpp_signed_long_min __glibcpp_s8_min ++#define __glibcpp_signed_long_max __glibcpp_s8_max ++#define __glibcpp_signed_long_digits __glibcpp_s8_digits ++#define __glibcpp_signed_long_digits10 __glibcpp_s8_digits10 ++#define __glibcpp_unsigned_long_min __glibcpp_u8_min ++#define __glibcpp_unsigned_long_max __glibcpp_u8_max ++#define __glibcpp_unsigned_long_digits __glibcpp_u8_digits ++#define __glibcpp_unsigned_long_digits10 __glibcpp_u8_digits10 ++#elif __glibcpp_long_bits == 16 ++#define __glibcpp_signed_long_min __glibcpp_s16_min ++#define __glibcpp_signed_long_max __glibcpp_s16_max ++#define __glibcpp_signed_long_digits __glibcpp_s16_digits ++#define __glibcpp_signed_long_digits10 __glibcpp_s16_digits10 ++#define __glibcpp_unsigned_long_min __glibcpp_u16_min ++#define __glibcpp_unsigned_long_max __glibcpp_u16_max ++#define __glibcpp_unsigned_long_digits __glibcpp_u16_digits ++#define __glibcpp_unsigned_long_digits10 __glibcpp_u16_digits10 ++#elif __glibcpp_long_bits == 32 ++#define __glibcpp_signed_long_min __glibcpp_s32_min ++#define __glibcpp_signed_long_max __glibcpp_s32_max ++#define __glibcpp_signed_long_digits __glibcpp_s32_digits ++#define __glibcpp_signed_long_digits10 __glibcpp_s32_digits10 ++#define __glibcpp_unsigned_long_min __glibcpp_u32_min ++#define __glibcpp_unsigned_long_max __glibcpp_u32_max ++#define __glibcpp_unsigned_long_digits __glibcpp_u32_digits ++#define __glibcpp_unsigned_long_digits10 __glibcpp_u32_digits10 ++#elif __glibcpp_long_bits == 64 ++#define __glibcpp_signed_long_min (long)__glibcpp_s64_min ++#define __glibcpp_signed_long_max (long)__glibcpp_s64_max ++#define __glibcpp_signed_long_digits __glibcpp_s64_digits ++#define __glibcpp_signed_long_digits10 __glibcpp_s64_digits10 ++#define __glibcpp_unsigned_long_min (unsigned long)__glibcpp_u64_min ++#define __glibcpp_unsigned_long_max (unsigned long)__glibcpp_u64_max ++#define __glibcpp_unsigned_long_digits __glibcpp_u64_digits ++#define __glibcpp_unsigned_long_digits10 __glibcpp_u64_digits10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// long long ++ ++#define __glibcpp_signed_long_long_traps true ++#define __glibcpp_signed_long_long_traps true ++#ifndef __glibcpp_signed_long_long_is_modulo ++#define __glibcpp_signed_long_long_is_modulo true ++#endif ++#if __glibcpp_long_long_bits == 8 ++#define __glibcpp_signed_long_long_min __glibcpp_s8_min ++#define __glibcpp_signed_long_long_max __glibcpp_s8_max ++#define __glibcpp_signed_long_long_digits __glibcpp_s8_digits ++#define __glibcpp_signed_long_long_digits10 __glibcpp_s8_digits10 ++#define __glibcpp_unsigned_long_long_min __glibcpp_u8_min ++#define __glibcpp_unsigned_long_long_max __glibcpp_u8_max ++#define __glibcpp_unsigned_long_long_digits __glibcpp_u8_digits ++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u8_digits10 ++#elif __glibcpp_long_long_bits == 16 ++#define __glibcpp_signed_long_long_min __glibcpp_s16_min ++#define __glibcpp_signed_long_long_max __glibcpp_s16_max ++#define __glibcpp_signed_long_long_digits __glibcpp_s16_digits ++#define __glibcpp_signed_long_long_digits10 __glibcpp_s16_digits10 ++#define __glibcpp_unsigned_long_long_min __glibcpp_u16_min ++#define __glibcpp_unsigned_long_long_max __glibcpp_u16_max ++#define __glibcpp_unsigned_long_long_digits __glibcpp_u16_digits ++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u16_digits10 ++#elif __glibcpp_long_long_bits == 32 ++#define __glibcpp_signed_long_long_min __glibcpp_s32_min ++#define __glibcpp_signed_long_long_max __glibcpp_s32_max ++#define __glibcpp_signed_long_long_digits __glibcpp_s32_digits ++#define __glibcpp_signed_long_long_digits10 __glibcpp_s32_digits10 ++#define __glibcpp_unsigned_long_long_min __glibcpp_u32_min ++#define __glibcpp_unsigned_long_long_max __glibcpp_u32_max ++#define __glibcpp_unsigned_long_long_digits __glibcpp_u32_digits ++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u32_digits10 ++#elif __glibcpp_long_long_bits == 64 ++#define __glibcpp_signed_long_long_min __glibcpp_s64_min ++#define __glibcpp_signed_long_long_max __glibcpp_s64_max ++#define __glibcpp_signed_long_long_digits __glibcpp_s64_digits ++#define __glibcpp_signed_long_long_digits10 __glibcpp_s64_digits10 ++#define __glibcpp_signed_long_long_traps true ++#define __glibcpp_unsigned_long_long_min __glibcpp_u64_min ++#define __glibcpp_unsigned_long_long_max __glibcpp_u64_max ++#define __glibcpp_unsigned_long_long_digits __glibcpp_u64_digits ++#define __glibcpp_unsigned_long_long_digits10 __glibcpp_u64_digits10 ++#define __glibcpp_unsigned_long_long_traps true ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// wchar_t ++ ++#define __glibcpp_wchar_t_traps true ++#ifndef __glibcpp_wchar_t_is_modulo ++#define __glibcpp_wchar_t_is_modulo true ++#endif ++#if __glibcpp_wchar_t_is_signed ++#if __glibcpp_wchar_t_bits == 8 ++#define __glibcpp_wchar_t_min __glibcpp_s8_min ++#define __glibcpp_wchar_t_max __glibcpp_s8_max ++#define __glibcpp_wchar_t_digits __glibcpp_s8_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_s8_digits10 ++#elif __glibcpp_wchar_t_bits == 16 ++#define __glibcpp_wchar_t_min __glibcpp_s16_min ++#define __glibcpp_wchar_t_max __glibcpp_s16_max ++#define __glibcpp_wchar_t_digits __glibcpp_s16_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_s16_digits10 ++#elif __glibcpp_wchar_t_bits == 32 ++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_s32_min ++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_s32_max ++#define __glibcpp_wchar_t_digits __glibcpp_s32_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_s32_digits10 ++#elif __glibcpp_wchar_t_bits == 64 ++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_s64_min ++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_s64_max ++#define __glibcpp_wchar_t_digits __glibcpp_s64_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_s64_digits10 ++#else ++// You must define these macros in the configuration file. ++#endif ++#else ++#if __glibcpp_wchar_t_bits == 8 ++#define __glibcpp_wchar_t_min __glibcpp_u8_min ++#define __glibcpp_wchar_t_max __glibcpp_u8_max ++#define __glibcpp_wchar_t_digits __glibcpp_u8_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_u8_digits10 ++#elif __glibcpp_wchar_t_bits == 16 ++#define __glibcpp_wchar_t_min __glibcpp_u16_min ++#define __glibcpp_wchar_t_max __glibcpp_u16_max ++#define __glibcpp_wchar_t_digits __glibcpp_u16_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_u16_digits10 ++#elif __glibcpp_wchar_t_bits == 32 ++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_u32_min ++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_u32_max ++#define __glibcpp_wchar_t_digits __glibcpp_u32_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_u32_digits10 ++#elif __glibcpp_wchar_t_bits == 64 ++#define __glibcpp_wchar_t_min (wchar_t)__glibcpp_u64_min ++#define __glibcpp_wchar_t_max (wchar_t)__glibcpp_u64_max ++#define __glibcpp_wchar_t_digits __glibcpp_u64_digits ++#define __glibcpp_wchar_t_digits10 __glibcpp_u64_digits10 ++#else ++// You must define these macros in the configuration file. ++#endif ++#endif ++ ++// float ++// ++ ++#if __glibcpp_float_bits == 32 ++#define __glibcpp_float_min __glibcpp_f32_min ++#define __glibcpp_float_max __glibcpp_f32_max ++#define __glibcpp_float_digits __glibcpp_f32_digits ++#define __glibcpp_float_digits10 __glibcpp_f32_digits10 ++#define __glibcpp_float_radix __glibcpp_f32_radix ++#define __glibcpp_float_epsilon __glibcpp_f32_epsilon ++#define __glibcpp_float_round_error __glibcpp_f32_round_error ++#define __glibcpp_float_min_exponent __glibcpp_f32_min_exponent ++#define __glibcpp_float_min_exponent10 __glibcpp_f32_min_exponent10 ++#define __glibcpp_float_max_exponent __glibcpp_f32_max_exponent ++#define __glibcpp_float_max_exponent10 __glibcpp_f32_max_exponent10 ++#elif __glibcpp_float_bits == 64 ++#define __glibcpp_float_min __glibcpp_f64_min ++#define __glibcpp_float_max __glibcpp_f64_max ++#define __glibcpp_float_digits __glibcpp_f64_digits ++#define __glibcpp_float_digits10 __glibcpp_f64_digits10 ++#define __glibcpp_float_radix __glibcpp_f64_radix ++#define __glibcpp_float_epsilon __glibcpp_f64_epsilon ++#define __glibcpp_float_round_error __glibcpp_f64_round_error ++#define __glibcpp_float_min_exponent __glibcpp_f64_min_exponent ++#define __glibcpp_float_min_exponent10 __glibcpp_f64_min_exponent10 ++#define __glibcpp_float_max_exponent __glibcpp_f64_max_exponent ++#define __glibcpp_float_max_exponent10 __glibcpp_f64_max_exponent10 ++#elif __glibcpp_float_bits == 80 ++#define __glibcpp_float_min __glibcpp_f80_min ++#define __glibcpp_float_max __glibcpp_f80_max ++#define __glibcpp_float_digits __glibcpp_f80_digits ++#define __glibcpp_float_digits10 __glibcpp_f80_digits10 ++#define __glibcpp_float_radix __glibcpp_f80_radix ++#define __glibcpp_float_epsilon __glibcpp_f80_epsilon ++#define __glibcpp_float_round_error __glibcpp_f80_round_error ++#define __glibcpp_float_min_exponent __glibcpp_f80_min_exponent ++#define __glibcpp_float_min_exponent10 __glibcpp_f80_min_exponent10 ++#define __glibcpp_float_max_exponent __glibcpp_f80_max_exponent ++#define __glibcpp_float_max_exponent10 __glibcpp_f80_max_exponent10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// FIXME: These are just stubs and inkorrect ++ ++#ifndef __glibcpp_float_has_infinity ++#define __glibcpp_float_has_infinity false ++#endif ++ ++#ifndef __glibcpp_float_has_quiet_NaN ++#define __glibcpp_float_has_quiet_NaN false ++#endif ++ ++#ifndef __glibcpp_float_has_signaling_NaN ++#define __glibcpp_float_has_signaling_NaN false ++#endif ++ ++#ifndef __glibcpp_float_has_denorm ++#define __glibcpp_float_has_denorm denorm_absent ++#endif ++ ++#ifndef __glibcpp_float_has_denorm_loss ++#define __glibcpp_float_has_denorm_loss false ++#endif ++ ++#ifndef __glibcpp_float_infinity ++#define __glibcpp_float_infinity 0.0F ++#endif ++ ++#ifndef __glibcpp_float_quiet_NaN ++#define __glibcpp_float_quiet_NaN 0.0F ++#endif ++ ++#ifndef __glibcpp_float_signaling_NaN ++#define __glibcpp_float_signaling_NaN 0.0F ++#endif ++ ++#ifndef __glibcpp_float_denorm_min ++#define __glibcpp_float_denorm_min 0.0F ++#endif ++ ++#ifndef __glibcpp_float_is_iec559 ++#define __glibcpp_float_is_iec559 false ++#endif ++ ++#ifndef __glibcpp_float_is_bounded ++#define __glibcpp_float_is_bounded true ++#endif ++ ++#ifndef __glibcpp_float_is_modulo ++#define __glibcpp_float_is_modulo false ++#endif ++ ++#ifndef __glibcpp_float_traps ++#define __glibcpp_float_traps false ++#endif ++ ++#ifndef __glibcpp_float_tinyness_before ++#define __glibcpp_float_tinyness_before false ++#endif ++ ++#ifndef __glibcpp_float_round_style ++#define __glibcpp_float_round_style round_toward_zero ++#endif ++ ++// double ++ ++#if __glibcpp_double_bits == 32 ++#define __glibcpp_double_min __glibcpp_f32_min ++#define __glibcpp_double_max __glibcpp_f32_max ++#define __glibcpp_double_digits __glibcpp_f32_digits ++#define __glibcpp_double_digits10 __glibcpp_f32_digits10 ++#define __glibcpp_double_radix __glibcpp_f32_radix ++#define __glibcpp_double_epsilon __glibcpp_f32_epsilon ++#define __glibcpp_double_round_error __glibcpp_f32_round_error ++#define __glibcpp_double_min_exponent __glibcpp_f32_min_exponent ++#define __glibcpp_double_min_exponent10 __glibcpp_f32_min_exponent10 ++#define __glibcpp_double_max_exponent __glibcpp_f32_max_exponent ++#define __glibcpp_double_max_exponent10 __glibcpp_f32_max_exponent10 ++#elif __glibcpp_double_bits == 64 ++#define __glibcpp_double_min __glibcpp_f64_min ++#define __glibcpp_double_max __glibcpp_f64_max ++#define __glibcpp_double_digits __glibcpp_f64_digits ++#define __glibcpp_double_digits10 __glibcpp_f64_digits10 ++#define __glibcpp_double_radix __glibcpp_f64_radix ++#define __glibcpp_double_epsilon __glibcpp_f64_epsilon ++#define __glibcpp_double_round_error __glibcpp_f64_round_error ++#define __glibcpp_double_min_exponent __glibcpp_f64_min_exponent ++#define __glibcpp_double_min_exponent10 __glibcpp_f64_min_exponent10 ++#define __glibcpp_double_max_exponent __glibcpp_f64_max_exponent ++#define __glibcpp_double_max_exponent10 __glibcpp_f64_max_exponent10 ++#elif __glibcpp_double_bits == 80 ++#define __glibcpp_double_min __glibcpp_f80_min ++#define __glibcpp_double_max __glibcpp_f80_max ++#define __glibcpp_double_digits __glibcpp_f80_digits ++#define __glibcpp_double_digits10 __glibcpp_f80_digits10 ++#define __glibcpp_double_radix __glibcpp_f80_radix ++#define __glibcpp_double_epsilon __glibcpp_f80_epsilon ++#define __glibcpp_double_round_error __glibcpp_f80_round_error ++#define __glibcpp_double_min_exponent __glibcpp_f80_min_exponent ++#define __glibcpp_double_min_exponent10 __glibcpp_f80_min_exponent10 ++#define __glibcpp_double_max_exponent __glibcpp_f80_max_exponent ++#define __glibcpp_double_max_exponent10 __glibcpp_f80_max_exponent10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// FIXME: These are just stubs and inkorrect ++ ++#ifndef __glibcpp_double_has_infinity ++#define __glibcpp_double_has_infinity false ++#endif ++ ++#ifndef __glibcpp_double_has_quiet_NaN ++#define __glibcpp_double_has_quiet_NaN false ++#endif ++ ++#ifndef __glibcpp_double_has_signaling_NaN ++#define __glibcpp_double_has_signaling_NaN false ++#endif ++ ++#ifndef __glibcpp_double_has_denorm ++#define __glibcpp_double_has_denorm denorm_absent ++#endif ++ ++#ifndef __glibcpp_double_has_denorm_loss ++#define __glibcpp_double_has_denorm_loss false ++#endif ++ ++#ifndef __glibcpp_double_infinity ++#define __glibcpp_double_infinity 0.0 ++#endif ++ ++#ifndef __glibcpp_double_quiet_NaN ++#define __glibcpp_double_quiet_NaN 0.0 ++#endif ++ ++#ifndef __glibcpp_double_signaling_NaN ++#define __glibcpp_double_signaling_NaN 0.0 ++#endif ++ ++#ifndef __glibcpp_double_denorm_min ++#define __glibcpp_double_denorm_min 0.0 ++#endif ++ ++#ifndef __glibcpp_double_is_iec559 ++#define __glibcpp_double_is_iec559 false ++#endif ++ ++#ifndef __glibcpp_double_is_bounded ++#define __glibcpp_double_is_bounded true ++#endif ++ ++#ifndef __glibcpp_double_is_modulo ++#define __glibcpp_double_is_modulo false ++#endif ++ ++#ifndef __glibcpp_double_traps ++#define __glibcpp_double_traps false ++#endif ++ ++#ifndef __glibcpp_double_tinyness_before ++#define __glibcpp_double_tinyness_before false ++#endif ++ ++#ifndef __glibcpp_double_round_style ++#define __glibcpp_double_round_style round_toward_zero ++#endif ++ ++// long double ++ ++#if __glibcpp_long_double_bits == 32 ++#define __glibcpp_long_double_min __glibcpp_f32_min ++#define __glibcpp_long_double_max __glibcpp_f32_max ++#define __glibcpp_long_double_digits __glibcpp_f32_digits ++#define __glibcpp_long_double_digits10 __glibcpp_f32_digits10 ++#define __glibcpp_long_double_radix __glibcpp_f32_radix ++#define __glibcpp_long_double_epsilon __glibcpp_f32_epsilon ++#define __glibcpp_long_double_round_error __glibcpp_f32_round_error ++#define __glibcpp_long_double_min_exponent __glibcpp_f32_min_exponent ++#define __glibcpp_long_double_min_exponent10 __glibcpp_f32_min_exponent10 ++#define __glibcpp_long_double_max_exponent __glibcpp_f32_max_exponent ++#define __glibcpp_long_double_max_exponent10 __glibcpp_f32_max_exponent10 ++#elif __glibcpp_long_double_bits == 64 ++#define __glibcpp_long_double_min __glibcpp_f64_min ++#define __glibcpp_long_double_max __glibcpp_f64_max ++#define __glibcpp_long_double_digits __glibcpp_f64_digits ++#define __glibcpp_long_double_digits10 __glibcpp_f64_digits10 ++#define __glibcpp_long_double_radix __glibcpp_f64_radix ++#define __glibcpp_long_double_epsilon __glibcpp_f64_epsilon ++#define __glibcpp_long_double_round_error __glibcpp_f64_round_error ++#define __glibcpp_long_double_min_exponent __glibcpp_f64_min_exponent ++#define __glibcpp_long_double_min_exponent10 __glibcpp_f64_min_exponent10 ++#define __glibcpp_long_double_max_exponent __glibcpp_f64_max_exponent ++#define __glibcpp_long_double_max_exponent10 __glibcpp_f64_max_exponent10 ++#elif __glibcpp_long_double_bits == 80 ++#define __glibcpp_long_double_min __glibcpp_f80_min ++#define __glibcpp_long_double_max __glibcpp_f80_max ++#define __glibcpp_long_double_digits __glibcpp_f80_digits ++#define __glibcpp_long_double_digits10 __glibcpp_f80_digits10 ++#define __glibcpp_long_double_radix __glibcpp_f80_radix ++#define __glibcpp_long_double_epsilon __glibcpp_f80_epsilon ++#define __glibcpp_long_double_round_error __glibcpp_f80_round_error ++#define __glibcpp_long_double_min_exponent __glibcpp_f80_min_exponent ++#define __glibcpp_long_double_min_exponent10 __glibcpp_f80_min_exponent10 ++#define __glibcpp_long_double_max_exponent __glibcpp_f80_max_exponent ++#define __glibcpp_long_double_max_exponent10 __glibcpp_f80_max_exponent10 ++#elif __glibcpp_long_double_bits == 96 ++#define __glibcpp_long_double_min __glibcpp_f96_min ++#define __glibcpp_long_double_max __glibcpp_f96_max ++#define __glibcpp_long_double_digits __glibcpp_f96_digits ++#define __glibcpp_long_double_digits10 __glibcpp_f96_digits10 ++#define __glibcpp_long_double_radix __glibcpp_f96_radix ++#define __glibcpp_long_double_epsilon __glibcpp_f96_epsilon ++#define __glibcpp_long_double_round_error __glibcpp_f96_round_error ++#define __glibcpp_long_double_min_exponent __glibcpp_f96_min_exponent ++#define __glibcpp_long_double_min_exponent10 __glibcpp_f96_min_exponent10 ++#define __glibcpp_long_double_max_exponent __glibcpp_f96_max_exponent ++#define __glibcpp_long_double_max_exponent10 __glibcpp_f96_max_exponent10 ++#elif __glibcpp_long_double_bits == 128 ++#define __glibcpp_long_double_min __glibcpp_f128_min ++#define __glibcpp_long_double_max __glibcpp_f128_max ++#define __glibcpp_long_double_digits __glibcpp_f128_digits ++#define __glibcpp_long_double_digits10 __glibcpp_f128_digits10 ++#define __glibcpp_long_double_radix __glibcpp_f128_radix ++#define __glibcpp_long_double_epsilon __glibcpp_f128_epsilon ++#define __glibcpp_long_double_round_error __glibcpp_f128_round_error ++#define __glibcpp_long_double_min_exponent __glibcpp_f128_min_exponent ++#define __glibcpp_long_double_min_exponent10 __glibcpp_f128_min_exponent10 ++#define __glibcpp_long_double_max_exponent __glibcpp_f128_max_exponent ++#define __glibcpp_long_double_max_exponent10 __glibcpp_f128_max_exponent10 ++#else ++// You must define these macros in the configuration file. ++#endif ++ ++// FIXME: These are just stubs and inkorrect ++ ++#ifndef __glibcpp_long_double_has_infinity ++#define __glibcpp_long_double_has_infinity false ++#endif ++ ++#ifndef __glibcpp_long_double_has_quiet_NaN ++#define __glibcpp_long_double_has_quiet_NaN false ++#endif ++ ++#ifndef __glibcpp_long_double_has_signaling_NaN ++#define __glibcpp_long_double_has_signaling_NaN false ++#endif ++ ++#ifndef __glibcpp_long_double_has_denorm ++#define __glibcpp_long_double_has_denorm denorm_absent ++#endif ++ ++#ifndef __glibcpp_long_double_has_denorm_loss ++#define __glibcpp_long_double_has_denorm_loss false ++#endif ++ ++#ifndef __glibcpp_long_double_infinity ++#define __glibcpp_long_double_infinity 0.0L ++#endif ++ ++#ifndef __glibcpp_long_double_quiet_NaN ++#define __glibcpp_long_double_quiet_NaN 0.0L ++#endif ++ ++#ifndef __glibcpp_long_double_signaling_NaN ++#define __glibcpp_long_double_signaling_NaN 0.0L ++#endif ++ ++#ifndef __glibcpp_long_double_denorm_min ++#define __glibcpp_long_double_denorm_min 0.0L ++#endif ++ ++#ifndef __glibcpp_long_double_is_iec559 ++#define __glibcpp_long_double_is_iec559 false ++#endif ++ ++#ifndef __glibcpp_long_double_is_bounded ++#define __glibcpp_long_double_is_bounded true ++#endif ++ ++#ifndef __glibcpp_long_double_is_modulo ++#define __glibcpp_long_double_is_modulo false ++#endif ++ ++#ifndef __glibcpp_long_double_traps ++#define __glibcpp_long_double_traps false ++#endif ++ ++#ifndef __glibcpp_long_double_tinyness_before ++#define __glibcpp_long_double_tinyness_before false ++#endif ++ ++#ifndef __glibcpp_long_double_round_style ++#define __glibcpp_long_double_round_style round_toward_zero ++#endif ++ ++ ++namespace std ++{ ++ enum float_round_style ++ { ++ round_indeterminate = -1, ++ round_toward_zero = 0, ++ round_to_nearest = 1, ++ round_toward_infinity = 2, ++ round_toward_neg_infinity = 3 ++ }; ++ ++ enum float_denorm_style ++ { ++ denorm_indeterminate = -1, ++ denorm_absent = 0, ++ denorm_present = 1 ++ }; ++ ++ // ++ // The primary class traits ++ // ++ struct __numeric_limits_base ++ { ++ static const bool is_specialized = false; ++ ++ static const int digits = 0; ++ static const int digits10 = 0; ++ static const bool is_signed = false; ++ static const bool is_integer = false; ++ static const bool is_exact = false; ++ static const int radix = 0; ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = false; ++ static const bool is_modulo = false; ++ ++ static const bool traps = false; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++ template ++ struct numeric_limits : public __numeric_limits_base ++ { ++ static _Tp min() throw() { return static_cast<_Tp>(0); } ++ static _Tp max() throw() { return static_cast<_Tp>(0); } ++ static _Tp epsilon() throw() { return static_cast<_Tp>(0); } ++ static _Tp round_error() throw() { return static_cast<_Tp>(0); } ++ static _Tp infinity() throw() { return static_cast<_Tp>(0); } ++ static _Tp quiet_NaN() throw() { return static_cast<_Tp>(0); } ++ static _Tp signaling_NaN() throw() { return static_cast<_Tp>(0); } ++ static _Tp denorm_min() throw() { return static_cast<_Tp>(0); } ++ }; ++ ++ // Now there follow 15 explicit specializations. Yes, 15. Make sure ++ // you get the count right. ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static bool min() throw() ++ { return false; } ++ ++ static bool max() throw() ++ { return true; } ++ ++ static const int digits = __glibcpp_bool_digits; ++ static const int digits10 = 0; ++ static const bool is_signed = false; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static bool epsilon() throw() ++ { return false; } ++ static bool round_error() throw() ++ { return false; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static bool infinity() throw() ++ { return false; } ++ static bool quiet_NaN() throw() ++ { return false; } ++ static bool signaling_NaN() throw() ++ { return false; } ++ static bool denorm_min() throw() ++ { return false; } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = false; ++ ++ // It is not clear what it means for a boolean type to trap. ++ // This is a DR on the LWG issue list. Here, I use integer ++ // promotion semantics. ++ static const bool traps = __glibcpp_signed_int_traps ++ || __glibcpp_signed_long_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_bool_digits ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static char min() throw() ++ { return __glibcpp_char_min; } ++ static char max() throw() ++ { return __glibcpp_char_max; } ++ ++ static const int digits = __glibcpp_char_digits; ++ static const int digits10 = __glibcpp_char_digits10; ++ static const bool is_signed = __glibcpp_plain_char_is_signed; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static char epsilon() throw() ++ { return char(); } ++ static char round_error() throw() ++ { return char(); } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static char infinity() throw() ++ { return char(); } ++ static char quiet_NaN() throw() ++ { return char(); } ++ static char signaling_NaN() throw() ++ { return char(); } ++ static char denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_char_is_modulo; ++ ++ static const bool traps = __glibcpp_char_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_char_min ++#undef __glibcpp_char_max ++#undef __glibcpp_char_digits ++#undef __glibcpp_char_digits10 ++#undef __glibcpp_char_is_signed ++#undef __glibcpp_char_is_modulo ++#undef __glibcpp_char_traps ++ ++ ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static signed char min() throw() ++ { return __glibcpp_signed_char_min; } ++ static signed char max() throw() ++ { return __glibcpp_signed_char_max; } ++ ++ static const int digits = __glibcpp_signed_char_digits; ++ static const int digits10 = __glibcpp_signed_char_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static signed char epsilon() throw() ++ { return 0; } ++ static signed char round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static signed char infinity() throw() ++ { return static_cast(0); } ++ static signed char quiet_NaN() throw() ++ { return static_cast(0); } ++ static signed char signaling_NaN() throw() ++ { return static_cast(0); } ++ static signed char denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_signed_char_is_modulo; ++ ++ static const bool traps = __glibcpp_signed_char_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_signed_char_min ++#undef __glibcpp_signed_char_max ++#undef __glibcpp_signed_char_digits ++#undef __glibcpp_signed_char_digits10 ++#undef __glibcpp_signed_char_is_modulo ++#undef __glibcpp_signed_char_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static unsigned char min() throw() ++ { return 0; } ++ static unsigned char max() throw() ++ { return __glibcpp_unsigned_char_max; } ++ ++ static const int digits = __glibcpp_unsigned_char_digits; ++ static const int digits10 = __glibcpp_unsigned_char_digits10; ++ static const bool is_signed = false; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static unsigned char epsilon() throw() ++ { return 0; } ++ static unsigned char round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static unsigned char infinity() throw() ++ { return static_cast(0); } ++ static unsigned char quiet_NaN() throw() ++ { return static_cast(0); } ++ static unsigned char signaling_NaN() throw() ++ { return static_cast(0); } ++ static unsigned char denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = true; ++ ++ static const bool traps = __glibcpp_unsigned_char_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_unsigned_char_max ++#undef __glibcpp_unsigned_char_digits ++#undef __glibcpp_unsigned_char_digits10 ++#undef __glibcpp_unsigned_char_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static wchar_t min() throw() ++ { return __glibcpp_wchar_t_min; } ++ static wchar_t max() throw() ++ { return __glibcpp_wchar_t_max; } ++ ++ static const int digits = __glibcpp_wchar_t_digits; ++ static const int digits10 = __glibcpp_wchar_t_digits10; ++ static const bool is_signed = __glibcpp_wchar_t_is_signed; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static wchar_t epsilon() throw() ++ { return 0; } ++ static wchar_t round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static wchar_t infinity() throw() ++ { return wchar_t(); } ++ static wchar_t quiet_NaN() throw() ++ { return wchar_t(); } ++ static wchar_t signaling_NaN() throw() ++ { return wchar_t(); } ++ static wchar_t denorm_min() throw() ++ { return wchar_t(); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_wchar_t_is_modulo; ++ ++ static const bool traps = __glibcpp_wchar_t_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_wchar_t_min ++#undef __glibcpp_wchar_t_max ++#undef __glibcpp_wchar_t_digits ++#undef __glibcpp_wchar_t_digits10 ++#undef __glibcpp_wchar_t_is_signed ++#undef __glibcpp_wchar_t_is_modulo ++#undef __glibcpp_wchar_t_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static short min() throw() ++ { return __glibcpp_signed_short_min; } ++ static short max() throw() ++ { return __glibcpp_signed_short_max; } ++ ++ static const int digits = __glibcpp_signed_short_digits; ++ static const int digits10 = __glibcpp_signed_short_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static short epsilon() throw() ++ { return 0; } ++ static short round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static short infinity() throw() ++ { return short(); } ++ static short quiet_NaN() throw() ++ { return short(); } ++ static short signaling_NaN() throw() ++ { return short(); } ++ static short denorm_min() throw() ++ { return short(); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_signed_short_is_modulo; ++ ++ static const bool traps = __glibcpp_signed_short_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_signed_short_min ++#undef __glibcpp_signed_short_max ++#undef __glibcpp_signed_short_digits ++#undef __glibcpp_signed_short_digits10 ++#undef __glibcpp_signed_short_is_modulo ++#undef __glibcpp_signed_short_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static unsigned short min() throw() ++ { return 0; } ++ static unsigned short max() throw() ++ { return __glibcpp_unsigned_short_max; } ++ ++ static const int digits = __glibcpp_unsigned_short_digits; ++ static const int digits10 = __glibcpp_unsigned_short_digits10; ++ static const bool is_signed = false; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static unsigned short epsilon() throw() ++ { return 0; } ++ static unsigned short round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static unsigned short infinity() throw() ++ { return static_cast(0); } ++ static unsigned short quiet_NaN() throw() ++ { return static_cast(0); } ++ static unsigned short signaling_NaN() throw() ++ { return static_cast(0); } ++ static unsigned short denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = true; ++ ++ static const bool traps = __glibcpp_unsigned_short_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_unsigned_short_max ++#undef __glibcpp_unsigned_short_digits ++#undef __glibcpp_unsigned_short_digits10 ++#undef __glibcpp_unsigned_short_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static int min() throw() ++ { return __glibcpp_signed_int_min; } ++ static int max() throw() ++ { return __glibcpp_signed_int_max; } ++ ++ static const int digits = __glibcpp_signed_int_digits; ++ static const int digits10 = __glibcpp_signed_int_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static int epsilon() throw() ++ { return 0; } ++ static int round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static int infinity() throw() ++ { return static_cast(0); } ++ static int quiet_NaN() throw() ++ { return static_cast(0); } ++ static int signaling_NaN() throw() ++ { return static_cast(0); } ++ static int denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_signed_int_is_modulo; ++ ++ static const bool traps = __glibcpp_signed_int_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_signed_int_min ++#undef __glibcpp_signed_int_max ++#undef __glibcpp_signed_int_digits ++#undef __glibcpp_signed_int_digits10 ++#undef __glibcpp_signed_int_is_modulo ++#undef __glibcpp_signed_int_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static unsigned int min() throw() ++ { return 0; } ++ static unsigned int max() throw() ++ { return __glibcpp_unsigned_int_max; } ++ ++ static const int digits = __glibcpp_unsigned_int_digits; ++ static const int digits10 = __glibcpp_unsigned_int_digits10; ++ static const bool is_signed = false; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static unsigned int epsilon() throw() ++ { return 0; } ++ static unsigned int round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static unsigned int infinity() throw() ++ { return static_cast(0); } ++ static unsigned int quiet_NaN() throw() ++ { return static_cast(0); } ++ static unsigned int signaling_NaN() throw() ++ { return static_cast(0); } ++ static unsigned int denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = true; ++ ++ static const bool traps = __glibcpp_unsigned_int_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_unsigned_int_max ++#undef __glibcpp_unsigned_int_digits ++#undef __glibcpp_unsigned_int_digits10 ++#undef __glibcpp_unsigned_int_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static long min() throw() ++ { return __glibcpp_signed_long_min; } ++ static long max() throw() ++ { return __glibcpp_signed_long_max; } ++ ++ static const int digits = __glibcpp_signed_long_digits; ++ static const int digits10 = __glibcpp_signed_long_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static long epsilon() throw() ++ { return 0; } ++ static long round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static long infinity() throw() ++ { return static_cast(0); } ++ static long quiet_NaN() throw() ++ { return static_cast(0); } ++ static long signaling_NaN() throw() ++ { return static_cast(0); } ++ static long denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_signed_long_is_modulo; ++ ++ static const bool traps = __glibcpp_signed_long_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_signed_long_min ++#undef __glibcpp_signed_long_max ++#undef __glibcpp_signed_long_digits ++#undef __glibcpp_signed_long_digits10 ++#undef __glibcpp_signed_long_is_modulo ++#undef __glibcpp_signed_long_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static unsigned long min() throw() ++ { return 0; } ++ static unsigned long max() throw() ++ { return __glibcpp_unsigned_long_max; } ++ ++ static const int digits = __glibcpp_unsigned_long_digits; ++ static const int digits10 = __glibcpp_unsigned_long_digits10; ++ static const bool is_signed = false; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static unsigned long epsilon() throw() ++ { return 0; } ++ static unsigned long round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static unsigned long infinity() throw() ++ { return static_cast(0); } ++ static unsigned long quiet_NaN() throw() ++ { return static_cast(0); } ++ static unsigned long signaling_NaN() throw() ++ { return static_cast(0); } ++ static unsigned long denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = true; ++ ++ static const bool traps = __glibcpp_unsigned_long_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_unsigned_long_max ++#undef __glibcpp_unsigned_long_digits ++#undef __glibcpp_unsigned_long_digits10 ++#undef __glibcpp_unsigned_long_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static long long min() throw() ++ { return __glibcpp_signed_long_long_min; } ++ static long long max() throw() ++ { return __glibcpp_signed_long_long_max; } ++ ++ static const int digits = __glibcpp_signed_long_long_digits; ++ static const int digits10 = __glibcpp_signed_long_long_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static long long epsilon() throw() ++ { return 0; } ++ static long long round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static long long infinity() throw() ++ { return static_cast(0); } ++ static long long quiet_NaN() throw() ++ { return static_cast(0); } ++ static long long signaling_NaN() throw() ++ { return static_cast(0); } ++ static long long denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = __glibcpp_signed_long_long_is_modulo; ++ ++ static const bool traps = __glibcpp_signed_long_long_traps; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_signed_long_long_min ++#undef __glibcpp_signed_long_long_max ++#undef __glibcpp_signed_long_long_digits ++#undef __glibcpp_signed_long_long_digits10 ++#undef __glibcpp_signed_long_long_is_modulo ++#undef __glibcpp_signed_long_long_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static unsigned long long min() throw() ++ { return 0; } ++ static unsigned long long max() throw() ++ { return __glibcpp_unsigned_long_long_max; } ++ ++ static const int digits = __glibcpp_unsigned_long_long_digits; ++ static const int digits10 = __glibcpp_unsigned_long_long_digits10; ++ static const bool is_signed = false; ++ static const bool is_integer = true; ++ static const bool is_exact = true; ++ static const int radix = 2; ++ static unsigned long long epsilon() throw() ++ { return 0; } ++ static unsigned long long round_error() throw() ++ { return 0; } ++ ++ static const int min_exponent = 0; ++ static const int min_exponent10 = 0; ++ static const int max_exponent = 0; ++ static const int max_exponent10 = 0; ++ ++ static const bool has_infinity = false; ++ static const bool has_quiet_NaN = false; ++ static const bool has_signaling_NaN = false; ++ static const float_denorm_style has_denorm = denorm_absent; ++ static const bool has_denorm_loss = false; ++ ++ static unsigned long long infinity() throw() ++ { return static_cast(0); } ++ static unsigned long long quiet_NaN() throw() ++ { return static_cast(0); } ++ static unsigned long long signaling_NaN() throw() ++ { return static_cast(0); } ++ static unsigned long long denorm_min() throw() ++ { return static_cast(0); } ++ ++ static const bool is_iec559 = false; ++ static const bool is_bounded = true; ++ static const bool is_modulo = true; ++ ++ static const bool traps = true; ++ static const bool tinyness_before = false; ++ static const float_round_style round_style = round_toward_zero; ++ }; ++ ++#undef __glibcpp_unsigned_long_long_max ++#undef __glibcpp_unsigned_long_long_digits ++#undef __glibcpp_unsigned_long_long_digits10 ++#undef __glibcpp_unsigned_long_long_traps ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static float min() throw() ++ { return __glibcpp_float_min; } ++ static float max() throw() ++ { return __glibcpp_float_max; } ++ ++ static const int digits = __glibcpp_float_digits; ++ static const int digits10 = __glibcpp_float_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = false; ++ static const bool is_exact = false; ++ static const int radix = __glibcpp_float_radix; ++ static float epsilon() throw() ++ { return __glibcpp_float_epsilon; } ++ static float round_error() throw() ++ { return __glibcpp_float_round_error; } ++ ++ static const int min_exponent = __glibcpp_float_min_exponent; ++ static const int min_exponent10 = __glibcpp_float_min_exponent10; ++ static const int max_exponent = __glibcpp_float_max_exponent; ++ static const int max_exponent10 = __glibcpp_float_max_exponent10; ++ ++ static const bool has_infinity = __glibcpp_float_has_infinity; ++ static const bool has_quiet_NaN = __glibcpp_float_has_quiet_NaN; ++ static const bool has_signaling_NaN = __glibcpp_float_has_signaling_NaN; ++ static const float_denorm_style has_denorm = __glibcpp_float_has_denorm; ++ static const bool has_denorm_loss = __glibcpp_float_has_denorm_loss; ++ ++ static float infinity() throw() ++ { return __glibcpp_float_infinity; } ++ static float quiet_NaN() throw() ++ { return __glibcpp_float_quiet_NaN; } ++ static float signaling_NaN() throw() ++ { return __glibcpp_float_signaling_NaN; } ++ static float denorm_min() throw() ++ { return __glibcpp_float_denorm_min; } ++ ++ static const bool is_iec559 = __glibcpp_float_is_iec559; ++ static const bool is_bounded = __glibcpp_float_is_bounded; ++ static const bool is_modulo = __glibcpp_float_is_modulo; ++ ++ static const bool traps = __glibcpp_float_traps; ++ static const bool tinyness_before = __glibcpp_float_tinyness_before; ++ static const float_round_style round_style = __glibcpp_float_round_style; ++ }; ++ ++#undef __glibcpp_float_min ++#undef __glibcpp_float_max ++#undef __glibcpp_float_digits ++#undef __glibcpp_float_digits10 ++#undef __glibcpp_float_radix ++#undef __glibcpp_float_round_error ++#undef __glibcpp_float_min_exponent ++#undef __glibcpp_float_min_exponent10 ++#undef __glibcpp_float_max_exponent ++#undef __glibcpp_float_max_exponent10 ++#undef __glibcpp_float_has_infinity ++#undef __glibcpp_float_has_quiet_NaN ++#undef __glibcpp_float_has_signaling_NaN ++#undef __glibcpp_float_has_denorm ++#undef __glibcpp_float_has_denorm_loss ++#undef __glibcpp_float_infinity ++#undef __glibcpp_float_quiet_NaN ++#undef __glibcpp_float_signaling_NaN ++#undef __glibcpp_float_denorm_min ++#undef __glibcpp_float_is_iec559 ++#undef __glibcpp_float_is_bounded ++#undef __glibcpp_float_is_modulo ++#undef __glibcpp_float_traps ++#undef __glibcpp_float_tinyness_before ++#undef __glibcpp_float_round_style ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static double min() throw() ++ { return __glibcpp_double_min; } ++ static double max() throw() ++ { return __glibcpp_double_max; } ++ ++ static const int digits = __glibcpp_double_digits; ++ static const int digits10 = __glibcpp_double_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = false; ++ static const bool is_exact = false; ++ static const int radix = __glibcpp_double_radix; ++ static double epsilon() throw() ++ { return __glibcpp_double_epsilon; } ++ static double round_error() throw() ++ { return __glibcpp_double_round_error; } ++ ++ static const int min_exponent = __glibcpp_double_min_exponent; ++ static const int min_exponent10 = __glibcpp_double_min_exponent10; ++ static const int max_exponent = __glibcpp_double_max_exponent; ++ static const int max_exponent10 = __glibcpp_double_max_exponent10; ++ ++ static const bool has_infinity = __glibcpp_double_has_infinity; ++ static const bool has_quiet_NaN = __glibcpp_double_has_quiet_NaN; ++ static const bool has_signaling_NaN = __glibcpp_double_has_signaling_NaN; ++ static const float_denorm_style has_denorm = ++ __glibcpp_double_has_denorm; ++ static const bool has_denorm_loss = __glibcpp_double_has_denorm_loss; ++ ++ static double infinity() throw() ++ { return __glibcpp_double_infinity; } ++ static double quiet_NaN() throw() ++ { return __glibcpp_double_quiet_NaN; } ++ static double signaling_NaN() throw() ++ { return __glibcpp_double_signaling_NaN; } ++ static double denorm_min() throw() ++ { return __glibcpp_double_denorm_min; } ++ ++ static const bool is_iec559 = __glibcpp_double_is_iec559; ++ static const bool is_bounded = __glibcpp_double_is_bounded; ++ static const bool is_modulo = __glibcpp_double_is_modulo; ++ ++ static const bool traps = __glibcpp_double_traps; ++ static const bool tinyness_before = __glibcpp_double_tinyness_before; ++ static const float_round_style round_style = ++ __glibcpp_double_round_style; ++ }; ++ ++#undef __glibcpp_double_min ++#undef __glibcpp_double_max ++#undef __glibcpp_double_digits ++#undef __glibcpp_double_digits10 ++#undef __glibcpp_double_radix ++#undef __glibcpp_double_round_error ++#undef __glibcpp_double_min_exponent ++#undef __glibcpp_double_min_exponent10 ++#undef __glibcpp_double_max_exponent ++#undef __glibcpp_double_max_exponent10 ++#undef __glibcpp_double_has_infinity ++#undef __glibcpp_double_has_quiet_NaN ++#undef __glibcpp_double_has_signaling_NaN ++#undef __glibcpp_double_has_denorm ++#undef __glibcpp_double_has_denorm_loss ++#undef __glibcpp_double_infinity ++#undef __glibcpp_double_quiet_NaN ++#undef __glibcpp_double_signaling_NaN ++#undef __glibcpp_double_denorm_min ++#undef __glibcpp_double_is_iec559 ++#undef __glibcpp_double_is_bounded ++#undef __glibcpp_double_is_modulo ++#undef __glibcpp_double_traps ++#undef __glibcpp_double_tinyness_before ++#undef __glibcpp_double_round_style ++ ++ ++ template<> ++ struct numeric_limits ++ { ++ static const bool is_specialized = true; ++ ++ static long double min() throw() ++ { return __glibcpp_long_double_min; } ++ static long double max() throw() ++ { return __glibcpp_long_double_max; } ++ ++ static const int digits = __glibcpp_long_double_digits; ++ static const int digits10 = __glibcpp_long_double_digits10; ++ static const bool is_signed = true; ++ static const bool is_integer = false; ++ static const bool is_exact = false; ++ static const int radix = __glibcpp_long_double_radix; ++ static long double epsilon() throw() ++ { return __glibcpp_long_double_epsilon; } ++ static long double round_error() throw() ++ { return __glibcpp_long_double_round_error; } ++ ++ static const int min_exponent = __glibcpp_long_double_min_exponent; ++ static const int min_exponent10 = __glibcpp_long_double_min_exponent10; ++ static const int max_exponent = __glibcpp_long_double_max_exponent; ++ static const int max_exponent10 = __glibcpp_long_double_max_exponent10; ++ ++ static const bool has_infinity = __glibcpp_long_double_has_infinity; ++ static const bool has_quiet_NaN = __glibcpp_long_double_has_quiet_NaN; ++ static const bool has_signaling_NaN = ++ __glibcpp_long_double_has_signaling_NaN; ++ static const float_denorm_style has_denorm = ++ __glibcpp_long_double_has_denorm; ++ static const bool has_denorm_loss = ++ __glibcpp_long_double_has_denorm_loss; ++ ++ static long double infinity() throw() ++ { return __glibcpp_long_double_infinity; } ++ static long double quiet_NaN() throw() ++ { return __glibcpp_long_double_quiet_NaN; } ++ static long double signaling_NaN() throw() ++ { return __glibcpp_long_double_signaling_NaN; } ++ static long double denorm_min() throw() ++ { return __glibcpp_long_double_denorm_min; } ++ ++ static const bool is_iec559 = __glibcpp_long_double_is_iec559; ++ static const bool is_bounded = __glibcpp_long_double_is_bounded; ++ static const bool is_modulo = __glibcpp_long_double_is_modulo; ++ ++ static const bool traps = __glibcpp_long_double_traps; ++ static const bool tinyness_before = __glibcpp_long_double_tinyness_before; ++ static const float_round_style round_style = ++ __glibcpp_long_double_round_style; ++ }; ++ ++#undef __glibcpp_long_double_min ++#undef __glibcpp_long_double_max ++#undef __glibcpp_long_double_digits ++#undef __glibcpp_long_double_digits10 ++#undef __glibcpp_long_double_radix ++#undef __glibcpp_long_double_round_error ++#undef __glibcpp_long_double_min_exponent ++#undef __glibcpp_long_double_min_exponent10 ++#undef __glibcpp_long_double_max_exponent ++#undef __glibcpp_long_double_max_exponent10 ++#undef __glibcpp_long_double_has_infinity ++#undef __glibcpp_long_double_has_quiet_NaN ++#undef __glibcpp_long_double_has_signaling_NaN ++#undef __glibcpp_long_double_has_denorm ++#undef __glibcpp_long_double_has_denorm_loss ++#undef __glibcpp_long_double_infinity ++#undef __glibcpp_long_double_quiet_NaN ++#undef __glibcpp_long_double_signaling_NaN ++#undef __glibcpp_long_double_denorm_min ++#undef __glibcpp_long_double_is_iec559 ++#undef __glibcpp_long_double_is_bounded ++#undef __glibcpp_long_double_is_modulo ++#undef __glibcpp_long_double_traps ++#undef __glibcpp_long_double_tinyness_before ++#undef __glibcpp_long_double_round_style ++ ++} // namespace std ++ ++#else ++ + #include + + // +@@ -1050,4 +2942,6 @@ namespace std + #undef __glibcpp_digits + #undef __glibcpp_digits10 + ++#endif // GCC 3.3+ ++ + #endif // _CPP_NUMERIC_LIMITS +--- libstdc++33-v3/include/Makefile.am.jj 2003-08-12 10:15:25.000000000 -0400 ++++ libstdc++33-v3/include/Makefile.am 2004-10-14 12:28:42.000000000 -0400 +@@ -316,7 +316,8 @@ target_headers = \ + ${target_srcdir}/ctype_inline.h \ + ${target_srcdir}/ctype_noninline.h \ + ${target_srcdir}/os_defines.h \ +- ${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h ++ ${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h \ ++ ${glibcpp_srcdir}/@CPU_LIMITS_INC_SRCDIR@/cpu_limits.h + + # Non-installed target_header files. + target_headers_noinst = \ +--- libstdc++33-v3/include/Makefile.in.jj 2003-08-12 10:15:25.000000000 -0400 ++++ libstdc++33-v3/include/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +@@ -429,7 +430,8 @@ target_headers = \ + ${target_srcdir}/ctype_inline.h \ + ${target_srcdir}/ctype_noninline.h \ + ${target_srcdir}/os_defines.h \ +- ${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h ++ ${glibcpp_srcdir}/@ATOMICITY_INC_SRCDIR@/atomicity.h \ ++ ${glibcpp_srcdir}/@CPU_LIMITS_INC_SRCDIR@/cpu_limits.h + + + # Non-installed target_header files. +--- libstdc++33-v3/po/Makefile.in.jj 2003-03-17 14:07:39.000000000 -0500 ++++ libstdc++33-v3/po/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/testsuite/Makefile.in.jj 2003-12-19 04:18:29.000000000 -0500 ++++ libstdc++33-v3/testsuite/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/Makefile.in.jj 2003-07-09 05:08:57.000000000 -0400 ++++ libstdc++33-v3/Makefile.in 2004-10-14 12:28:01.000000000 -0400 +@@ -83,6 +83,7 @@ CMESSAGES_H = @CMESSAGES_H@ + CMONEY_CC = @CMONEY_CC@ + CNUMERIC_CC = @CNUMERIC_CC@ + CPP = @CPP@ ++CPU_LIMITS_INC_SRCDIR = @CPU_LIMITS_INC_SRCDIR@ + CSTDIO_H = @CSTDIO_H@ + CTIME_CC = @CTIME_CC@ + CTIME_H = @CTIME_H@ +--- libstdc++33-v3/configure.jj 2004-08-18 03:44:22.000000000 -0400 ++++ libstdc++33-v3/configure 2004-10-14 12:35:55.000000000 -0400 +@@ -23989,6 +23989,7 @@ fi + # uses it, and it only gets used in this file.) + OS_INC_SRCDIR=config/${os_include_dir} + ATOMICITY_INC_SRCDIR=config/${ATOMICITYH} ++CPU_LIMITS_INC_SRCDIR=config/${CPULIMITSH} + + + +@@ -24442,6 +24443,7 @@ s%@GLIBCPP_TEST_ABI_TRUE@%$GLIBCPP_TEST_ + s%@GLIBCPP_TEST_ABI_FALSE@%$GLIBCPP_TEST_ABI_FALSE%g + s%@OS_INC_SRCDIR@%$OS_INC_SRCDIR%g + s%@ATOMICITY_INC_SRCDIR@%$ATOMICITY_INC_SRCDIR%g ++s%@CPU_LIMITS_INC_SRCDIR@%$CPU_LIMITS_INC_SRCDIR%g + s%@GLIBCPP_IS_CROSS_COMPILING@%$GLIBCPP_IS_CROSS_COMPILING%g + s%@CANADIAN_TRUE@%$CANADIAN_TRUE%g + s%@CANADIAN_FALSE@%$CANADIAN_FALSE%g +--- libstdc++33-v3/configure.in.jj 2004-08-18 03:44:22.000000000 -0400 ++++ libstdc++33-v3/configure.in 2004-10-14 12:35:27.000000000 -0400 +@@ -451,8 +451,10 @@ GLIBCPP_CONFIGURE_TESTSUITE + # uses it, and it only gets used in this file.) + OS_INC_SRCDIR=config/${os_include_dir} + ATOMICITY_INC_SRCDIR=config/${ATOMICITYH} ++CPU_LIMITS_INC_SRCDIR=config/${CPULIMITSH} + AC_SUBST(OS_INC_SRCDIR) + AC_SUBST(ATOMICITY_INC_SRCDIR) ++AC_SUBST(CPU_LIMITS_INC_SRCDIR) + + # Set up cross-compile flags + AC_SUBST(GLIBCPP_IS_CROSS_COMPILING) dnl Unused so far. +--- libstdc++33-v3/configure.target.jj 2003-10-23 11:45:20.000000000 -0400 ++++ libstdc++33-v3/configure.target 2004-10-14 12:34:27.000000000 -0400 +@@ -32,6 +32,8 @@ + # + # ATOMICITYH location of atomicity.h, + # defaults to cpu_include_dir ++# CPULIMITSH location of cpu_limits.h, ++# defaults to cpu_include_dir + # + # It possibly modifies the following variables: + # +@@ -198,3 +200,45 @@ case "${target}" in + abi_baseline_pair="sparc-freebsd5" + ;; + esac ++ ++# Set CPULIMITSH to the directory where the configuration-dependent ++# cpu_limits.h can be found. ++# THIS TABLE IS SORTED. KEEP IT THAT WAY. ++case "${target}" in ++ *-*-hpux*) ++ CPULIMITSH=os/hpux ++ ;; ++ alpha*-*-*osf5*) ++ CPULIMITSH=os/osf/osf5.0 ++ ;; ++ alpha*-*-*) ++ CPULIMITSH=cpu/alpha ++ ;; ++ cris-*-*) ++ CPULIMITSH=cpu/cris ++ ;; ++ ia64-*-*) ++ CPULIMITSH=cpu/ia64 ++ ;; ++ i?86-*-*) ++ CPULIMITSH=cpu/i386 ++ ;; ++ m68k-*-* | m680[246]0-*-*) ++ CPULIMITSH=cpu/m68k ++ ;; ++ mmix-*-*) ++ CPULIMITSH=cpu/mmix ++ ;; ++ powerpc*-*-* | rs6000-*-*) ++ CPULIMITSH=cpu/powerpc ++ ;; ++ s390-*-* | s390x-*-*) ++ CPULIMITSH=cpu/s390 ++ ;; ++ x86_64-*-*) ++ CPULIMITSH=cpu/x86-64 ++ ;; ++ *) ++ CPULIMITSH=cpu/generic ++ ;; ++esac diff --git a/SOURCES/compat-libstdc++33-symver.patch b/SOURCES/compat-libstdc++33-symver.patch new file mode 100644 index 0000000..0112c61 --- /dev/null +++ b/SOURCES/compat-libstdc++33-symver.patch @@ -0,0 +1,98 @@ +2004-07-13 Jakub Jelinek + + * acinclude.m4 (glibcpp_shared_libgcc): Correct + glibcpp_shared_libgcc test for multilibs. + * aclocal.m4: Rebuilt. + * configure: Rebuilt. + +--- libstdc++33-v3/acinclude.m4.jj 2004-06-24 18:06:53.000000000 +0200 ++++ libstdc++33-v3/acinclude.m4 2004-08-18 10:28:50.333384148 +0200 +@@ -2294,6 +2294,23 @@ if test $enable_symvers != no; then + CFLAGS=' -lgcc_s' + AC_TRY_LINK(, [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no) + CFLAGS="$ac_save_CFLAGS" ++ if test $glibcpp_shared_libgcc = no; then ++ cat > conftest.c <&1 >/dev/null \ ++ | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'` ++changequote([,])dnl ++ rm -f conftest.c conftest.so ++ if test x${glibcpp_libgcc_s_suffix+set} = xset; then ++ CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix" ++ AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes) ++ CFLAGS="$ac_save_CFLAGS" ++ fi ++ fi + AC_MSG_RESULT($glibcpp_shared_libgcc) + fi + +--- libstdc++33-v3/aclocal.m4.jj 2004-06-24 18:06:53.000000000 +0200 ++++ libstdc++33-v3/aclocal.m4 2004-08-18 10:30:06.361019696 +0200 +@@ -2306,6 +2306,23 @@ if test $enable_symvers != no; then + CFLAGS=' -lgcc_s' + AC_TRY_LINK(, [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no) + CFLAGS="$ac_save_CFLAGS" ++ if test $glibcpp_shared_libgcc = no; then ++ cat > conftest.c <&1 >/dev/null \ ++ | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'` ++changequote([,])dnl ++ rm -f conftest.c conftest.so ++ if test x${glibcpp_libgcc_s_suffix+set} = xset; then ++ CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix" ++ AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes) ++ CFLAGS="$ac_save_CFLAGS" ++ fi ++ fi + AC_MSG_RESULT($glibcpp_shared_libgcc) + fi + +--- libstdc++33-v3/configure.jj 2004-08-18 09:44:22.000000000 +0200 ++++ libstdc++33-v3/configure 2004-08-18 10:31:41.502299528 +0200 +@@ -23563,6 +23563,36 @@ else + fi + rm -f conftest* + CFLAGS="$ac_save_CFLAGS" ++ if test $glibcpp_shared_libgcc = no; then ++ cat > conftest.c <&1 >/dev/null \ ++ | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'` ++ rm -f conftest.c conftest.so ++ if test x${glibcpp_libgcc_s_suffix+set} = xset; then ++ CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix" ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++ rm -rf conftest* ++ glibcpp_shared_libgcc=yes ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++fi ++rm -f conftest* ++ CFLAGS="$ac_save_CFLAGS" ++ fi ++ fi + echo "$ac_t""$glibcpp_shared_libgcc" 1>&6 + fi + diff --git a/SOURCES/compat-libstdc++33-v3.patch b/SOURCES/compat-libstdc++33-v3.patch new file mode 100644 index 0000000..57552ad --- /dev/null +++ b/SOURCES/compat-libstdc++33-v3.patch @@ -0,0 +1,204 @@ +--- Makefile.in 2003-02-03 23:58:12.000000000 +0100 ++++ Makefile.in 2004-10-14 17:42:45.175884656 +0200 +@@ -785,6 +785,7 @@ INSTALL_X11_MODULES = \ + # using $(TARGET_FLAGS_TO_PASS). + ALL_TARGET_MODULES = \ + all-target-libstdc++-v3 \ ++ all-target-libstdc++33-v3 \ + all-target-librx \ + all-target-newlib \ + all-target-libf2c \ +@@ -808,6 +809,7 @@ ALL_TARGET_MODULES = \ + # are compiled using the target tools. + CONFIGURE_TARGET_MODULES = \ + configure-target-libstdc++-v3 \ ++ configure-target-libstdc++33-v3 \ + configure-target-librx \ + configure-target-newlib \ + configure-target-libf2c \ +@@ -831,6 +833,7 @@ CONFIGURE_TARGET_MODULES = \ + # compiled using $(TARGET_FLAGS_TO_PASS). + CHECK_TARGET_MODULES = \ + check-target-libstdc++-v3 \ ++ check-target-libstdc++33-v3 \ + check-target-newlib \ + check-target-libf2c \ + check-target-libobjc \ +@@ -847,6 +850,7 @@ CHECK_TARGET_MODULES = \ + # compiled using $(TARGET_FLAGS_TO_PASS). + INSTALL_TARGET_MODULES = \ + install-target-libstdc++-v3 \ ++ install-target-libstdc++33-v3 \ + install-target-newlib \ + install-target-libf2c \ + install-target-libobjc \ +@@ -934,6 +938,7 @@ CLEAN_MODULES = \ + # All of the target modules that can be cleaned + CLEAN_TARGET_MODULES = \ + clean-target-libstdc++-v3 \ ++ clean-target-libstdc++33-v3 \ + clean-target-librx \ + clean-target-newlib \ + clean-target-libf2c \ +@@ -1659,6 +1664,7 @@ check-c++: + $(SET_LIB_PATH) \ + (cd gcc; $(MAKE) $(GCC_FLAGS_TO_PASS) check-c++); \ + $(MAKE) check-target-libstdc++-v3; \ ++ $(MAKE) check-target-libstdc++33-v3; \ + else \ + true; \ + fi +@@ -1703,7 +1709,7 @@ install-dosrel-fake: + + ALL_GCC = all-gcc + ALL_GCC_C = $(ALL_GCC) all-target-newlib all-target-libgloss +-ALL_GCC_CXX = $(ALL_GCC_C) all-target-libstdc++-v3 ++ALL_GCC_CXX = $(ALL_GCC_C) all-target-libstdc++-v3 all-target-libstdc++33-v3 + + # This is a list of inter-dependencies among modules. + all-apache: +@@ -1747,7 +1753,7 @@ all-gdb: all-libiberty all-opcodes all-b + all-gettext: + all-gnuserv: + configure-target-gperf: $(ALL_GCC_CXX) +-all-target-gperf: configure-target-gperf all-target-libiberty all-target-libstdc++-v3 ++all-target-gperf: configure-target-gperf all-target-libiberty all-target-libstdc++-v3 all-target-libstdc++33-v3 + all-gprof: all-libiberty all-bfd all-opcodes all-intl + all-grep: all-libiberty + all-grez: all-libiberty all-bfd all-opcodes +@@ -1776,6 +1782,8 @@ configure-target-librx: $(ALL_GCC_C) + all-target-librx: configure-target-librx + configure-target-libstdc++-v3: $(ALL_GCC_C) + all-target-libstdc++-v3: configure-target-libstdc++-v3 all-target-libiberty ++configure-target-libstdc++33-v3: $(ALL_GCC_C) ++all-target-libstdc++33-v3: configure-target-libstdc++33-v3 all-target-libiberty + configure-target-libstub: $(ALL_GCC_C) + all-target-libstub: configure-target-libstub + all-libtool: +--- configure.in.jj 2002-09-24 09:06:53.000000000 -0400 ++++ configure.in 2004-10-14 17:53:05.746097559 -0400 +@@ -50,7 +50,7 @@ fi + + libstdcxx_version="target-libstdc++-v3" + # Don't use libstdc++-v3's flags to configure/build itself. +-libstdcxx_flags='`case $$dir in libstdc++-v3 | libjava) ;; *) test ! -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags || $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags --build-includes;; esac` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs' ++libstdcxx_flags='`case $$dir in libstdc++-v3 | libstdc++33-v3 | libjava) ;; *) test ! -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags || $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/testsuite_flags --build-includes;; esac` `test x"$$dir" = xlibstdc++33-v3 && echo "-L$$r/$(TARGET_SUBDIR)/libstdc++33-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++33-v3/src/.libs" || echo "-L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs"`' + + # these tools are built for the host environment + # Note, the powerpc-eabi build depends on sim occurring before gdb in order to +@@ -72,6 +72,7 @@ target_libs="target-libiberty \ + target-newlib \ + target-librx \ + ${libstdcxx_version} \ ++ target-libstdc++33-v3 \ + target-libf2c \ + ${libgcj} + target-libobjc" +@@ -884,7 +885,7 @@ case "${target}" in + mcore-*-pe*) + # The EPOC C++ environment does not support exceptions or rtti, + # and so building libstdc++-v3 tends not to always work. +- noconfigdirs="$noconfigdirs target-libstdc++-v3" ++ noconfigdirs="$noconfigdirs target-libstdc++-v3 target-libstdc++33-v3" + ;; + mmix-*-*) + noconfigdirs="$noconfigdirs ${libgcj}" +@@ -1557,7 +1558,7 @@ elif test -d ${topsrcdir}/gcc; then + # We add -shared-libgcc to CXX_FOR_TARGET whenever we use xgcc instead + # of g++ for linking C++ or Java, because g++ has -shared-libgcc by + # default whereas gcc does not. +- CXX_FOR_TARGET='$$r/gcc/`case $$dir in libstdc++-v3 | libjava) echo xgcc -shared-libgcc ;; *) echo g++ ;; esac` -B$$r/gcc/ -nostdinc++ '$libstdcxx_flags ++ CXX_FOR_TARGET='$$r/gcc/`case $$dir in libstdc++-v3 | libstdc++33-v3 | libjava) echo xgcc -shared-libgcc ;; *) echo g++ ;; esac` -B$$r/gcc/ -nostdinc++ '$libstdcxx_flags + elif test "$host" = "$target"; then + CXX_FOR_TARGET='$(CXX)' + else +--- libstdc++33-v3/acinclude.m4.jj 2004-10-14 17:08:50.000000000 -0400 ++++ libstdc++33-v3/acinclude.m4 2004-10-14 17:08:50.000000000 -0400 +@@ -72,7 +72,7 @@ AC_DEFUN(GLIBCPP_CONFIGURE, [ + AC_ARG_WITH(cross-host, + [ --with-cross-host=HOST configuring with a cross compiler]) + +- glibcpp_basedir=$srcdir/$toprel/$1/libstdc++-v3 ++ glibcpp_basedir=$srcdir/$toprel/$1/libstdc++33-v3 + AC_SUBST(glibcpp_basedir) + + # Never versions of autoconf add an underscore to these functions. +--- libstdc++33-v3/aclocal.m4.jj 2004-10-14 17:09:05.000000000 -0400 ++++ libstdc++33-v3/aclocal.m4 2004-10-14 17:09:05.000000000 -0400 +@@ -84,7 +84,7 @@ AC_DEFUN(GLIBCPP_CONFIGURE, [ + AC_ARG_WITH(cross-host, + [ --with-cross-host=HOST configuring with a cross compiler]) + +- glibcpp_basedir=$srcdir/$toprel/$1/libstdc++-v3 ++ glibcpp_basedir=$srcdir/$toprel/$1/libstdc++33-v3 + AC_SUBST(glibcpp_basedir) + + # Never versions of autoconf add an underscore to these functions. +--- libstdc++33-v3/configure.jj 2004-10-14 17:09:31.000000000 -0400 ++++ libstdc++33-v3/configure 2004-10-14 17:09:31.000000000 -0400 +@@ -922,7 +922,7 @@ if test "${with_cross_host+set}" = set; + fi + + +- glibcpp_basedir=$srcdir/$toprel/./libstdc++-v3 ++ glibcpp_basedir=$srcdir/$toprel/./libstdc++33-v3 + + + # Never versions of autoconf add an underscore to these functions. +--- libstdc++33-v3/testsuite/18_support/numeric_limits.cc.jj 2002-12-19 06:44:30.000000000 -0500 ++++ libstdc++33-v3/testsuite/18_support/numeric_limits.cc 2004-10-15 05:12:43.000000000 -0400 +@@ -260,6 +260,10 @@ bool test03() + { + bool test = true; + ++#ifndef __CHAR_BIT__ ++ #define __CHAR_BIT__ 8 ++#endif ++ + VERIFY( std::numeric_limits::digits10 == 0 ); + if (__CHAR_BIT__ == 8) + { +--- libstdc++33-v3/testsuite/lib/libstdc++-v3-dg.exp.jj 2003-12-19 04:18:43.000000000 -0500 ++++ libstdc++33-v3/testsuite/lib/libstdc++-v3-dg.exp 2004-10-15 05:04:58.000000000 -0400 +@@ -49,7 +49,7 @@ proc libstdc++-v3-init { args } { + global original_ld_library_path + global tool_root_dir + +- set blddir [lookfor_file [get_multilibs] libstdc++-v3] ++ set blddir [lookfor_file [get_multilibs] libstdc++33-v3] + + # By default, we assume we want to run program images. + global dg-do-what-default +--- libstdc++33-v3/testsuite_flags.in.jj 2003-05-15 18:08:03.000000000 -0400 ++++ libstdc++33-v3/testsuite_flags.in 2004-10-15 04:56:36.000000000 -0400 +@@ -43,7 +43,7 @@ case ${query} in + echo ${CXX} + ;; + --build-cxx) +- CXX_build="@glibcpp_CXX@ ${PCHFLAGS}" ++ CXX_build=`echo "@glibcpp_CXX@ ${PCHFLAGS}" | sed 's,libstdc++-v3,libstdc++33-v3,g'` + CXX=`echo "$CXX_build" | sed 's,gcc/xgcc ,gcc/g++ ,'` + echo ${CXX} + ;; +--- libstdc++33-v3/Makefile.am.jj 2003-07-09 05:08:57.000000000 -0400 ++++ libstdc++33-v3/Makefile.am 2004-10-15 09:20:31.000000000 -0400 +@@ -136,7 +136,7 @@ AM_MAKEFLAGS = \ + "includedir=$(includedir)" \ + "prefix=$(prefix)" \ + "tooldir=$(tooldir)" \ +- "gxx_include_dir=$(gxx_include_dir)" \ ++ "gxx_include_dir=@gxx_include_dir@" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "LD=$(LD)" \ +--- libstdc++33-v3/Makefile.in.jj 2004-10-14 12:28:01.000000000 -0400 ++++ libstdc++33-v3/Makefile.in 2004-10-15 09:20:55.000000000 -0400 +@@ -195,7 +195,7 @@ AM_MAKEFLAGS = \ + "includedir=$(includedir)" \ + "prefix=$(prefix)" \ + "tooldir=$(tooldir)" \ +- "gxx_include_dir=$(gxx_include_dir)" \ ++ "gxx_include_dir=@gxx_include_dir@" \ + "AR=$(AR)" \ + "AS=$(AS)" \ + "LD=$(LD)" \ diff --git a/SOURCES/dummylib.sh b/SOURCES/dummylib.sh new file mode 100755 index 0000000..f36c602 --- /dev/null +++ b/SOURCES/dummylib.sh @@ -0,0 +1,50 @@ +#!/bin/sh +if [ $# -lt 3 ]; then echo Usage: dummylib.sh orig_lib_path dummy_lib_path mapfile; exit 1; fi +TMPDIR=`mktemp -d dummylib.sh.XXXXXX` || exit 1 +F=`file -L $1` +C= +S=8 +case "$F" in + *ELF\ 64-bit*shared\ object*x86-64*) C=-m64;; + *ELF\ 32-bit*shared\ object*80?86*) C=-m32; S=4;; + *ELF\ 64-bit*shared\ object*PowerPC*) C=-m64;; + *ELF\ 32-bit*shared\ object*PowerPC*) C=-m32; S=4;; + *ELF\ 64-bit*shared\ object*cisco*) C=-m64;; + *ELF\ 32-bit*shared\ object*cisco*) C=-m32; S=4;; + *ELF\ 64-bit*shared\ object*IA-64*) C=;; + *ELF\ 64-bit*shared\ object*Alpha*) C=;; + *ELF\ 64-bit*shared\ object*390*) C=-m64;; + *ELF\ 32-bit*shared\ object*390*) C=-m31; S=4;; + *ELF\ 64-bit*shared\ object*SPARC*) C=-m64;; + *ELF\ 32-bit*shared\ object*SPARC*) C=-m32; S=4;; + *ELF\ 64-bit*shared\ object*Alpha*) C=;; +esac +readelf -Ws $1 | awk ' +/\.dynsym.* contains/ { start=1 } +/^$/ { start=0 } +/ WEAK.* UND [^@]*$/ { if (start) { + print ".data"; print ".weak " $8; print ".balign 8" + print ".'$S'byte " $8 +} } +/ UND / { next } +/@/ { if (start) { + fn=$8 + intfn="HACK" hack+0 + hack++ + if ($4 ~ /FUNC/) { print ".text"; size=16; print ".type " intfn ",@function" } + else if ($4 ~ /OBJECT/) { print ".data"; size=$3; print ".type " intfn ",@object" } + else if ($4 ~ /NOTYPE/) { print ".data"; size=$3 } + else exit(1); + print ".globl " intfn + if ($5 ~ /WEAK/) { print ".weak " intfn } + else if ($5 !~ /GLOBAL/) exit(1); + print intfn ": .skip " size + print ".size " intfn "," size + print ".symver " intfn "," fn +} } +' > $TMPDIR/lib.s || exit +soname=`readelf -Wd $1 | grep SONAME | sed 's/^.*\[//;s/\].*$//'` +gcc $C -shared -Wl,-soname,$soname,-version-script,$3 \ + -o $2 $TMPDIR/lib.s -nostdlib +strip $2 +rm -rf $TMPDIR diff --git a/SOURCES/gcc32-CVE-2006-3619.patch b/SOURCES/gcc32-CVE-2006-3619.patch new file mode 100644 index 0000000..87e910e --- /dev/null +++ b/SOURCES/gcc32-CVE-2006-3619.patch @@ -0,0 +1,31 @@ +2006-07-17 Richard Guenther + + * jartool.c (extract_jar): Do not allow directory traversal + to parents of the extraction root. + +--- fastjar/jartool.c.jj 2006-07-11 10:53:39.000000000 +0200 ++++ fastjar/jartool.c 2006-07-18 13:49:39.000000000 +0200 +@@ -1736,6 +1736,7 @@ int extract_jar(int fd, char **files, in + const ub1 *start = filename; + char *tmp_buff; + struct stat sbuf; ++ int depth = 0; + + tmp_buff = malloc(sizeof(char) * strlen((const char *)filename)); + +@@ -1756,7 +1757,14 @@ int extract_jar(int fd, char **files, in + #ifdef DEBUG + printf("checking the existance of %s\n", tmp_buff); + #endif +- ++ if(strcmp(tmp_buff, "..") == 0){ ++ --depth; ++ if (depth < 0){ ++ fprintf(stderr, "Traversal to parent directories during unpacking!\n"); ++ exit(1); ++ } ++ } else if (strcmp(tmp_buff, ".") != 0) ++ ++depth; + if(stat(tmp_buff, &sbuf) < 0){ + if(errno != ENOENT){ + perror("stat"); diff --git a/SOURCES/gcc32-Winline-doc.patch b/SOURCES/gcc32-Winline-doc.patch new file mode 100644 index 0000000..6c31748 --- /dev/null +++ b/SOURCES/gcc32-Winline-doc.patch @@ -0,0 +1,35 @@ +2005-01-03 Jakub Jelinek + + * doc/invoke.texi (-Winline): Document that GCC 3.2.x only + uses this warning for frontends using RTL inliner. + * doc/extend.texi (Inline): Don't mention -Winline option. + +--- gcc/doc/extend.texi.jj 2003-09-16 16:57:45.000000000 +0200 ++++ gcc/doc/extend.texi 2005-01-03 12:26:25.917145090 +0100 +@@ -3396,14 +3396,11 @@ inc (int *a) + You can also make all ``simple enough'' functions inline with the option + @option{-finline-functions}. + +-@opindex Winline + Note that certain usages in a function definition can make it unsuitable + for inline substitution. Among these usages are: use of varargs, use of + alloca, use of variable sized data types (@pxref{Variable Length}), + use of computed goto (@pxref{Labels as Values}), use of nonlocal goto, +-and nested functions (@pxref{Nested Functions}). Using @option{-Winline} +-will warn when a function marked @code{inline} could not be substituted, +-and will give the reason for the failure. ++and nested functions (@pxref{Nested Functions}). + + Note that in C and Objective-C, unlike C++, the @code{inline} keyword + does not affect the linkage of the function. +--- gcc/doc/invoke.texi.jj 2004-07-01 12:34:04.000000000 +0200 ++++ gcc/doc/invoke.texi 2005-01-03 12:28:05.928165120 +0100 +@@ -2732,6 +2732,8 @@ code is to provide behavior which is sel + @item -Winline + @opindex Winline + Warn if a function can not be inlined and it was declared as inline. ++In GCC 3.2.x, this only works for languages using the RTL inliner, ++such as Java, for C, C++ and Objective-C this option has no effect. + + @item -Wlong-long + @opindex Wlong-long diff --git a/SOURCES/gcc32-bison-1.875c.patch b/SOURCES/gcc32-bison-1.875c.patch new file mode 100644 index 0000000..8e94bac --- /dev/null +++ b/SOURCES/gcc32-bison-1.875c.patch @@ -0,0 +1,61 @@ +--- gcc/cp/parse.y.jj 2003-01-17 12:33:10.000000000 -0500 ++++ gcc/cp/parse.y 2004-07-01 09:03:23.000000000 -0400 +@@ -44,6 +44,9 @@ Boston, MA 02111-1307, USA. */ + #include "except.h" + #include "toplev.h" + #include "ggc.h" ++#ifdef __GNUC__ ++#define YYMALLOC nonexistent ++#endif + + extern struct obstack permanent_obstack; + +--- gcc/java/parse.y.jj 2004-01-27 10:16:49.000000000 -0500 ++++ gcc/java/parse.y 2004-07-01 09:03:53.000000000 -0400 +@@ -65,6 +65,9 @@ definitions and other extensions. */ + #include "function.h" + #include "except.h" + #include "ggc.h" ++#ifdef __GNUC__ ++#define YYMALLOC nonexistent ++#endif + + #ifndef DIR_SEPARATOR + #define DIR_SEPARATOR '/' +--- gcc/java/parse-scan.y.jj 2001-04-04 18:12:39.000000000 -0400 ++++ gcc/java/parse-scan.y 2004-07-01 09:07:17.000000000 -0400 +@@ -43,6 +43,10 @@ definitions and other extensions. */ + #include "obstack.h" + #include "toplev.h" + ++#ifdef __GNUC__ ++#define YYMALLOC nonexistent ++#endif ++ + extern char *input_filename; + extern FILE *finput, *out; + +--- gcc/tradcif.y.jj 2002-02-04 05:41:44.000000000 -0500 ++++ gcc/tradcif.y 2004-07-01 08:55:51.000000000 -0400 +@@ -27,6 +27,9 @@ Foundation, 59 Temple Place - Suite 330, + #include "intl.h" + #include "tradcpp.h" + #include ++#ifdef __GNUC__ ++#define YYMALLOC nonexistent ++#endif + + static int yylex PARAMS ((void)); + static void yyerror PARAMS ((const char *msgid)) ATTRIBUTE_NORETURN; +--- gcc/c-parse.in.jj 2003-08-01 19:21:40.000000000 -0400 ++++ gcc/c-parse.in 2004-07-01 08:56:33.000000000 -0400 +@@ -47,6 +47,9 @@ end ifc + #include "output.h" + #include "toplev.h" + #include "ggc.h" ++#ifdef __GNUC__ ++#define YYMALLOC nonexistent ++#endif + + #ifdef MULTIBYTE_CHARS + #include diff --git a/SOURCES/gcc32-bison.patch b/SOURCES/gcc32-bison.patch new file mode 100644 index 0000000..aae49f1 --- /dev/null +++ b/SOURCES/gcc32-bison.patch @@ -0,0 +1,73 @@ +--- gcc/c-parse.in.jj 2009-03-09 14:27:38.000000000 +0100 ++++ gcc/c-parse.in 2009-03-09 14:33:29.000000000 +0100 +@@ -1713,7 +1713,7 @@ enum_head: + + structsp_attr: + struct_head identifier '{' +- { $$ = start_struct (RECORD_TYPE, $2); ++ { $$ = start_struct (RECORD_TYPE, $2); + /* Start scope of tag before parsing components. */ + } + component_decl_list '}' maybe_attribute +@@ -1723,7 +1723,7 @@ structsp_attr: + $3, chainon ($1, $5)); + } + | union_head identifier '{' +- { $$ = start_struct (UNION_TYPE, $2); } ++ { $$ = start_struct (UNION_TYPE, $2); } + component_decl_list '}' maybe_attribute + { $$ = finish_struct ($4, $5, chainon ($1, $7)); } + | union_head '{' component_decl_list '}' maybe_attribute +@@ -1731,12 +1731,12 @@ structsp_attr: + $3, chainon ($1, $5)); + } + | enum_head identifier '{' +- { $$ = start_enum ($2); } ++ { $$ = start_enum ($2); } + enumlist maybecomma_warn '}' maybe_attribute + { $$ = finish_enum ($4, nreverse ($5), + chainon ($1, $8)); } + | enum_head '{' +- { $$ = start_enum (NULL_TREE); } ++ { $$ = start_enum (NULL_TREE); } + enumlist maybecomma_warn '}' maybe_attribute + { $$ = finish_enum ($3, nreverse ($4), + chainon ($1, $7)); } +--- gcc/cp/parse.y.jj 2009-03-09 14:39:01.000000000 +0100 ++++ gcc/cp/parse.y 2009-03-09 14:41:58.000000000 +0100 +@@ -804,7 +804,7 @@ fndef: + + constructor_declarator: + nested_name_specifier SELFNAME '(' +- { $$ = begin_constructor_declarator ($1, $2); } ++ { $$ = begin_constructor_declarator ($1, $2); } + parmlist ')' cv_qualifiers exception_specification_opt + { $$ = make_call_declarator ($4, $5, $7, $8); } + | nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt +@@ -812,7 +812,7 @@ constructor_declarator: + $$ = make_call_declarator ($$, empty_parms (), $4, $5); + } + | global_scope nested_name_specifier SELFNAME '(' +- { $$ = begin_constructor_declarator ($2, $3); } ++ { $$ = begin_constructor_declarator ($2, $3); } + parmlist ')' cv_qualifiers exception_specification_opt + { $$ = make_call_declarator ($5, $6, $8, $9); } + | global_scope nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt +@@ -820,7 +820,7 @@ constructor_declarator: + $$ = make_call_declarator ($$, empty_parms (), $5, $6); + } + | nested_name_specifier self_template_type '(' +- { $$ = begin_constructor_declarator ($1, $2); } ++ { $$ = begin_constructor_declarator ($1, $2); } + parmlist ')' cv_qualifiers exception_specification_opt + { $$ = make_call_declarator ($4, $5, $7, $8); } + | nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt +@@ -828,7 +828,7 @@ constructor_declarator: + $$ = make_call_declarator ($$, empty_parms (), $4, $5); + } + | global_scope nested_name_specifier self_template_type '(' +- { $$ = begin_constructor_declarator ($2, $3); } ++ { $$ = begin_constructor_declarator ($2, $3); } + parmlist ')' cv_qualifiers exception_specification_opt + { $$ = make_call_declarator ($5, $6, $8, $9); } + | global_scope nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt diff --git a/SOURCES/gcc32-c++-friend-templ-member.patch b/SOURCES/gcc32-c++-friend-templ-member.patch new file mode 100644 index 0000000..46b0f4c --- /dev/null +++ b/SOURCES/gcc32-c++-friend-templ-member.patch @@ -0,0 +1,60 @@ +2004-08-06 Alexandre Oliva + + * parse.y (structsp): Skip typename_type obtained from a + class_head_decl, use the actual type. + +2004-08-09 Alexandre Oliva + + * g++.old-deja/g++.pt/crash43.C: Don't require error for legal + construct. + * g++.dg/template/friend0.C: New test. + +--- gcc/cp/parse.y.jj ++++ gcc/cp/parse.y +@@ -2371,6 +2374,13 @@ structsp: + | class_head_decl + { + $$.t = TREE_TYPE ($1.t); ++ /* class_head_decl always starts with an aggr, so ++ get rid of any implicit typename warnings we ++ might get from it. We can't remove it before ++ this point because this is where we get from the ++ decl to the type. */ ++ if (IMPLICIT_TYPENAME_P ($$.t)) ++ $$.t = TREE_TYPE ($$.t); + $$.new_type_flag = $1.new_type_flag; + check_class_key (current_aggr, $$.t); + } +--- gcc/testsuite/g++.old-deja/g++.pt/crash43.C 27 Nov 2002 01:03:42 -0000 1.1 ++++ gcc/testsuite/g++.old-deja/g++.pt/crash43.C 9 Aug 2004 17:20:46 -0000 +@@ -7,7 +7,7 @@ struct S { + struct Y {}; + + template +- friend struct S::X; // ERROR - typename as friend ++ friend struct S::X; // gets bogus error - XFAIL *-*-* + + template + friend typename S::Y; // ERROR - typename as friend +@@ -15,7 +15,7 @@ struct S { + + struct T { + template +- friend struct S::X; // ERROR - typename as friend ++ friend struct S::X; + }; + + struct U { +--- gcc/testsuite/g++.dg/template/friend0.C.jj 2004-08-12 14:03:21.001079817 +0200 ++++ gcc/testsuite/g++.dg/template/friend0.C 2004-08-12 14:03:15.734996391 +0200 +@@ -0,0 +1,10 @@ ++// http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=129350 ++// { dg-do compile } ++ ++template struct A { ++ struct B { }; ++}; ++ ++class C { ++ template friend struct A::B; ++}; diff --git a/SOURCES/gcc32-c++-pass-by-invisible-ref.patch b/SOURCES/gcc32-c++-pass-by-invisible-ref.patch new file mode 100644 index 0000000..13c5336 --- /dev/null +++ b/SOURCES/gcc32-c++-pass-by-invisible-ref.patch @@ -0,0 +1,67 @@ +2004-12-01 Alexandre Oliva + + * calls.c (initialize_argument_information): Treat NOP_EXPR + of TARGET_EXPR the same as TARGET_EXPR itself. + +2005-01-03 Jakub Jelinek + + * g++.dg/other/destruct1.C: New test. + +--- gcc/calls.c.jj 2003-09-16 16:57:44.000000000 +0200 ++++ gcc/calls.c 2005-01-03 11:00:11.604022891 +0100 +@@ -1239,7 +1239,10 @@ initialize_argument_information (num_act + args[i].tree_value); + type = build_pointer_type (type); + } +- else if (TREE_CODE (args[i].tree_value) == TARGET_EXPR) ++ else if (TREE_CODE (args[i].tree_value) == TARGET_EXPR ++ || (TREE_CODE (args[i].tree_value) == NOP_EXPR ++ && (TREE_CODE (TREE_OPERAND (args[i].tree_value, 0)) ++ == TARGET_EXPR))) + { + /* In the V3 C++ ABI, parameters are destroyed in the caller. + We implement this by passing the address of the temporary +--- gcc/testsuite/g++.dg/other/destruct1.C.jj 2005-01-03 11:02:26.440730539 +0100 ++++ gcc/testsuite/g++.dg/other/destruct1.C 2005-01-03 11:02:44.971392180 +0100 +@@ -0,0 +1,41 @@ ++// { dg-do run } ++ ++int i, j, k; ++extern "C" void abort (); ++ ++struct S ++{ ++ S () { ++i; } ++ S (const S &x) { ++k; } ++ S &operator= (const S &x) { abort (); return *this; } ++ ~S () { ++j; } ++}; ++ ++const S foo () ++{ ++ S s; ++ return s; ++} ++ ++S bar (S x) ++{ ++ return S (); ++} ++ ++S baz (S x) ++{ ++ return x; ++} ++ ++void test () ++{ ++ S a = bar (foo ()); ++ S b = baz (foo ()); ++} ++ ++int main () ++{ ++ test (); ++ if (i != 3 || j != 4 || k != 1) ++ abort (); ++} diff --git a/SOURCES/gcc32-c++-pr10558.patch b/SOURCES/gcc32-c++-pr10558.patch new file mode 100644 index 0000000..b95bd8e --- /dev/null +++ b/SOURCES/gcc32-c++-pr10558.patch @@ -0,0 +1,90 @@ +2003-07-10 Mark Mitchell + + PR c++/10558 + * parse.y (class_template_ok_as_expr): New variable. + (template_arg_1): New non-terminal. + (primary): Issue errors about uses of class templates as + expressions. + + * g++.dg/parse/template8.C: New test. + +--- gcc/cp/parse.y 10 Jul 2003 12:43:11 -0000 1.284.2.7 ++++ gcc/cp/parse.y 11 Jul 2003 08:39:55 -0000 1.284.2.8 +@@ -53,6 +53,8 @@ extern struct obstack permanent_obstack; + /* Like YYERROR but do call yyerror. */ + #define YYERROR1 { yyerror ("syntax error"); YYERROR; } + ++static int class_template_ok_as_expr; ++ + #define OP0(NODE) (TREE_OPERAND (NODE, 0)) + #define OP1(NODE) (TREE_OPERAND (NODE, 1)) + +@@ -422,7 +424,7 @@ cp_parse_init () + %type template_close_bracket + %type apparent_template_type + %type template_type template_arg_list template_arg_list_opt +-%type template_arg ++%type template_arg template_arg_1 + %type condition xcond paren_cond_or_null + %type type_name nested_name_specifier nested_type ptr_to_mem + %type complete_type_name notype_identifier nonnested_type +@@ -1108,7 +1110,7 @@ template_close_bracket: + template_arg_list_opt: + /* empty */ + { $$ = NULL_TREE; } +- | template_arg_list ++ | template_arg_list + ; + + template_arg_list: +@@ -1119,6 +1121,15 @@ template_arg_list: + ; + + template_arg: ++ { ++class_template_ok_as_expr; } ++ template_arg_1 ++ { ++ --class_template_ok_as_expr; ++ $$ = $2; ++ } ++ ; ++ ++template_arg_1: + type_id + { $$ = groktypename ($1.t); } + | PTYPENAME +@@ -1695,7 +1706,14 @@ primary: + $$ = $2; + } + | overqualified_id %prec HYPERUNARY +- { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } ++ { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); ++ if (!class_template_ok_as_expr ++ && DECL_CLASS_TEMPLATE_P ($$)) ++ { ++ error ("invalid use of template `%D'", $$); ++ $$ = error_mark_node; ++ } ++ } + | overqualified_id '(' nonnull_exprlist ')' + { $$ = finish_qualified_call_expr ($1, $3); } + | overqualified_id LEFT_RIGHT +--- gcc/testsuite/g++.dg/parse/template8.C 2005-01-27 14:27:08.338732320 +0100 ++++ gcc/testsuite/g++.dg/parse/template8.C 2003-07-16 18:05:35.000000000 +0200 +@@ -0,0 +1,16 @@ ++namespace N ++{ ++ ++template struct A ++{ ++ template A(A); ++}; ++ ++} ++ ++void foo(N::A); ++ ++void bar() ++{ ++ foo(N::A); // { dg-error "" } ++} diff --git a/SOURCES/gcc32-c++-pr7566.patch b/SOURCES/gcc32-c++-pr7566.patch new file mode 100644 index 0000000..7857776 --- /dev/null +++ b/SOURCES/gcc32-c++-pr7566.patch @@ -0,0 +1,44 @@ +2002-08-14 Gabriel Dos Reis + + Fix PR/7566 + * c-semantics.c (genrtl_case_label): Don't (mis)use + warning_with_decl. + +2005-01-03 Jakub Jelinek + + * g++.dg/parse/jumptocaselab1.C: New test. + +--- gcc/c-semantics.c.jj 2003-01-17 18:31:04.000000000 +0100 ++++ gcc/c-semantics.c 2005-01-03 10:19:51.912155689 +0100 +@@ -673,8 +673,7 @@ genrtl_case_label (case_label) + if (cleanup) + { + static int explained = 0; +- warning_with_decl (TREE_PURPOSE (cleanup), +- "destructor needed for `%#D'"); ++ warning ("destructor needed for `%#D'", TREE_PURPOSE (cleanup)); + warning ("where case label appears here"); + if (!explained) + { +--- gcc/testsuite/g++.dg/parse/jumptocaselab1.C.jj 2005-01-03 10:23:45.286072690 +0100 ++++ gcc/testsuite/g++.dg/parse/jumptocaselab1.C 2005-01-03 10:26:29.216516818 +0100 +@@ -0,0 +1,19 @@ ++// PR c++/7566 ++// { dg-do compile } ++ ++struct bar { bar (); ~bar ();}; ++ ++void foo (int c) ++{ ++ switch (c) ++ { ++ case 0: ++ case 1: ++ bar x; // { dg-error "crosses initialization" } ++ break; ++ default: // { dg-error "jump to case label" } ++ break; ++ } ++} ++ ++// { dg-warning "destructor needed|where case label|enclose actions" "" { target *-*-* } 14 } diff --git a/SOURCES/gcc32-c++-reregister-specialization.patch b/SOURCES/gcc32-c++-reregister-specialization.patch new file mode 100644 index 0000000..87b6e85 --- /dev/null +++ b/SOURCES/gcc32-c++-reregister-specialization.patch @@ -0,0 +1,89 @@ +2003-07-14 Mark Mitchell + + PR c++/7053 + * pt.c (unregister_specialization): Rename to ... + (reregister_specialization): ... this. + (tsubst_friend_function): Use it. + (regenerate_decl_from_template): Likewise. + + * g++.dg/template/friend20.C: New test. + +--- gcc/cp/pt.c 14 Jul 2003 10:08:58 -0000 1.635.2.33 ++++ gcc/cp/pt.c 14 Jul 2003 20:18:18 -0000 1.635.2.34 +@@ -128,7 +128,7 @@ static tree retrieve_specialization PARA + static tree retrieve_local_specialization PARAMS ((tree)); + static tree register_specialization PARAMS ((tree, tree, tree)); + static void register_local_specialization PARAMS ((tree, tree)); +-static int unregister_specialization PARAMS ((tree, tree)); ++static int reregister_specialization PARAMS ((tree, tree, tree)); + static tree reduce_template_parm_level PARAMS ((tree, tree, int)); + static tree build_template_decl PARAMS ((tree, tree)); + static int mark_template_parm PARAMS ((tree, void *)); +@@ -969,13 +969,11 @@ register_specialization (spec, tmpl, arg + } + + /* Unregister the specialization SPEC as a specialization of TMPL. +- Returns nonzero if the SPEC was listed as a specialization of +- TMPL. */ ++ Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true ++ if the SPEC was listed as a specialization of TMPL. */ + + static int +-unregister_specialization (spec, tmpl) +- tree spec; +- tree tmpl; ++reregister_specialization (tree spec, tree tmpl, tree new_spec) + { + tree* s; + +@@ -984,7 +982,10 @@ unregister_specialization (spec, tmpl) + s = &TREE_CHAIN (*s)) + if (TREE_VALUE (*s) == spec) + { +- *s = TREE_CHAIN (*s); ++ if (!new_spec) ++ *s = TREE_CHAIN (*s); ++ else ++ TREE_VALUE (*s) = new_spec; + return 1; + } + +@@ -4807,8 +4808,9 @@ tsubst_friend_function (decl, args) + DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info; + + if (TREE_CODE (old_decl) != TEMPLATE_DECL) +- /* duplicate_decls will take care of this case. */ +- ; ++ reregister_specialization (new_friend, ++ most_general_template (old_decl), ++ old_decl); + else + { + tree t; +@@ -9897,7 +9899,7 @@ regenerate_decl_from_template (decl, tmp + instantiation of a specialization, which it isn't: it's a full + instantiation. */ + gen_tmpl = most_general_template (tmpl); +- unregistered = unregister_specialization (decl, gen_tmpl); ++ unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE); + + /* If the DECL was not unregistered then something peculiar is + happening: we created a specialization but did not call +--- gcc/testsuite/g++.dg/template/friend20.C 2004-12-09 13:34:01.422415552 +0100 ++++ gcc/testsuite/g++.dg/template/friend20.C 2003-07-15 02:29:07.000000000 +0200 +@@ -0,0 +1,15 @@ ++template ++struct A ++{ ++ friend void bar(A a) {} ++}; ++ ++void bar(A); ++ ++int main() ++{ ++ A a; ++ ++ bar(a); ++} ++ diff --git a/SOURCES/gcc32-c++-scope-nesting.patch b/SOURCES/gcc32-c++-scope-nesting.patch new file mode 100644 index 0000000..e898c55 --- /dev/null +++ b/SOURCES/gcc32-c++-scope-nesting.patch @@ -0,0 +1,113 @@ +2004-08-13 Alexandre Oliva + + Revert: + 2003-03-17 Jason Merrill + * decl.c (finish_function): Don't skip a block. + +2004-08-12 Alexandre Oliva + + 2002-12-16 Jason Merrill + * c-semantics.c (add_scope_stmt): Abort if the end SCOPE_STMT + doesn't match the begin SCOPE_STMT in partialness. + +2004-08-12 Alexandre Oliva + + 2002-12-16 Jason Merrill + * semantics.c (do_pushlevel): Call pushlevel after adding the + SCOPE_STMT. + (do_poplevel): Call poplevel before adding the SCOPE_STMT. + * parse.y (function_body): Go back to using compstmt. + * decl.c (pushdecl): Skip another level to get to the parms level. + +--- gcc/c-semantics.c 17 Jan 2003 17:49:35 -0000 1.40.2.2.8.2 ++++ gcc/c-semantics.c 12 Aug 2004 09:16:00 -0000 +@@ -143,6 +143,8 @@ add_scope_stmt (begin_p, partial_p) + } + else + { ++ if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top))) ++ abort (); + TREE_VALUE (top) = ss; + *stack_ptr = TREE_CHAIN (top); + } +--- gcc/cp/decl.c 25 Mar 2003 20:01:38 -0000 1.866.2.36.4.15 ++++ gcc/cp/decl.c 12 Aug 2004 09:16:20 -0000 +@@ -4218,6 +4218,9 @@ pushdecl (x) + them there. */ + struct binding_level *b = current_binding_level->level_chain; + ++ /* Skip the ctor/dtor cleanup level. */ ++ b = b->level_chain; ++ + /* ARM $8.3 */ + if (b->parm_flag == 1) + { +--- gcc/cp/decl.c 2004-08-13 01:32:01.000000000 -0300 ++++ gcc/cp/decl.c 2004-08-12 21:55:06.000000000 -0300 +@@ -14375,7 +14375,8 @@ + the function so we know that their lifetime always ends with a + return; see g++.dg/opt/nrv6.C. We could be more flexible if + we were to do this optimization in tree-ssa. */ +- && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)), ++ /* Skip the artificial function body block. */ ++ && (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))), + chain_member (r, BLOCK_VARS (outer)))) + { + +--- gcc/cp/parse.y 17 Jan 2003 17:49:55 -0000 1.248.2.5.4.1.2.3 ++++ gcc/cp/parse.y 12 Aug 2004 09:16:22 -0000 +@@ -775,15 +775,10 @@ eat_saved_input: + ; + + /* The outermost block of a function really begins before the +- mem-initializer-list, so we open one there and suppress the one that +- actually corresponds to the curly braces. */ ++ mem-initializer-list, so we open one there, too. */ + function_body: +- .begin_function_body ctor_initializer_opt save_lineno '{' +- { $$ = begin_compound_stmt (/*has_no_scope=*/1); } +- compstmtend ++ .begin_function_body ctor_initializer_opt compstmt + { +- STMT_LINENO ($5) = $3; +- finish_compound_stmt (/*has_no_scope=*/1, $5); + finish_function_body ($1); + } + ; +--- gcc/cp/semantics.c 25 Mar 2003 20:01:39 -0000 1.252.2.6.8.3 ++++ gcc/cp/semantics.c 12 Aug 2004 09:16:23 -0000 +@@ -125,14 +125,17 @@ do_poplevel () + { + tree scope_stmts = NULL_TREE; + +- if (!processing_template_decl) +- scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); +- + block = poplevel (kept_level_p (), 1, 0); +- if (block && !processing_template_decl) ++ if (!processing_template_decl) + { +- SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block; +- SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block; ++ /* This needs to come after the poplevel so that partial scopes ++ are properly nested. */ ++ scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); ++ if (block) ++ { ++ SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block; ++ SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block; ++ } + } + } + +@@ -146,9 +149,9 @@ do_pushlevel () + { + if (stmts_are_full_exprs_p ()) + { +- pushlevel (0); + if (!processing_template_decl) + add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); ++ pushlevel (0); + } + } + diff --git a/SOURCES/gcc32-c++-unitialized-self-ref.patch b/SOURCES/gcc32-c++-unitialized-self-ref.patch new file mode 100644 index 0000000..733ecb3 --- /dev/null +++ b/SOURCES/gcc32-c++-unitialized-self-ref.patch @@ -0,0 +1,109 @@ +2004-12-02 Alexandre Oliva + + * decl.c (copy_tree_replacing_r, struct replace_node): New. + (grok_reference_init): Use them to replace uses of a reference + being initialized with a NULL dereference. + +2005-01-03 Jakub Jelinek + + * g++.dg/other/ref1.C: New test. + +--- gcc/cp/decl.c.jj 2003-03-28 22:03:02.000000000 +0100 ++++ gcc/cp/decl.c 2005-01-03 11:45:24.669972609 +0100 +@@ -1,6 +1,6 @@ + /* Process declarations and variables for C compiler. + Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +- 2001, 2002, 2003 Free Software Foundation, Inc. ++ 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Michael Tiemann (tiemann@cygnus.com) + + This file is part of GNU CC. +@@ -7535,6 +7535,30 @@ start_decl_1 (decl) + DECL_INITIAL (decl) = NULL_TREE; + } + ++static tree copy_tree_replacing_r PARAMS ((tree *, int *, void *)); ++ ++struct replace_node ++{ ++ tree from, to; ++}; ++ ++static tree ++copy_tree_replacing_r (tp, walk_subtrees, data) ++ tree *tp; ++ int *walk_subtrees; ++ void *data; ++{ ++ struct replace_node *rn = data; ++ ++ if (*tp != rn->from) ++ return copy_tree_r (tp, walk_subtrees, NULL); ++ ++ *tp = rn->to; ++ *walk_subtrees = 0; ++ ++ return NULL; ++} ++ + /* Handle initialization of references. + These three arguments are from `cp_finish_decl', and have the + same meaning here that they do there. +@@ -7565,6 +7589,35 @@ grok_reference_init (decl, type, init) + return NULL_TREE; + } + ++ /* Replace occurrences of a reference variable in its own ++ initializer with a zero-initialized NULL reference. If we don't ++ do this and the reference initializer ends up requiring a ++ temporary (as it almost always will in this case), we'll end up ++ with the initializer of the temporary referencing the reference ++ variable before it's in scope, which crashes because we haven't ++ expanded the reference declaration yet, so its DECL_RTL is NULL. ++ This is equivalent to zero-initializing the reference variable, ++ expanding the temporary definition with initializer, then binding ++ the reference to the temporary, without requiring all the revamp ++ in reference handling that mainline undergone for GCC 3.4. It ++ actually changes behavior a little bit, in that a reference ++ initialized to itself will now be bound to a NULL reference ++ instead of getting an indeterminate value, but since using it ++ before initialization invokes undefined behavior, either way is ++ fine. */ ++ if (find_tree (init, decl)) ++ { ++ struct replace_node rn; ++ ++ rn.from = decl; ++ rn.to = build1 (NOP_EXPR, type, integer_zero_node); ++ ++ walk_tree (&init, copy_tree_replacing_r, &rn, NULL); ++ ++ if (warn_uninitialized) ++ warning ("reference used in its own initializer"); ++ } ++ + if (TREE_CODE (init) == TREE_LIST) + init = build_compound_expr (init); + +--- gcc/testsuite/g++.dg/other/ref1.C.jj 2005-01-03 11:46:43.005868429 +0100 ++++ gcc/testsuite/g++.dg/other/ref1.C 2005-01-03 11:47:34.475601869 +0100 +@@ -0,0 +1,19 @@ ++// { dg-do compile } ++// { dg-options "-O2" } ++ ++struct A ++{ ++ A (); ++ ~A (); ++}; ++ ++extern const A &bar (); ++extern A baz (); ++extern int operator!= (const A &x, const A &y); ++ ++void foo (const A &x) ++{ ++ /* This has undefined behaviour, as a is used before it is initialized. ++ Still, we shouldn't ICE on it. */ ++ const A &a = a != bar () ? x : baz (); ++} diff --git a/SOURCES/gcc32-convert-move.patch b/SOURCES/gcc32-convert-move.patch new file mode 100644 index 0000000..e456b42 --- /dev/null +++ b/SOURCES/gcc32-convert-move.patch @@ -0,0 +1,18 @@ +2003-05-22 Jeff Law + + * expr.c (convert_move): Avoid making silly copies. + +--- gcc/expr.c.jj 2004-05-25 17:05:45.000000000 +0200 ++++ gcc/expr.c 2004-08-03 17:40:55.114899943 +0200 +@@ -531,6 +531,11 @@ convert_move (to, from, unsignedp) + if (to_real != from_real) + abort (); + ++ /* If the source and destination are already the same, then there's ++ nothing to do. */ ++ if (to == from) ++ return; ++ + /* If FROM is a SUBREG that indicates that we have already done at least + the required extension, strip it. We don't handle such SUBREGs as + TO here. */ diff --git a/SOURCES/gcc32-cxa_demangle-ambiguity.patch b/SOURCES/gcc32-cxa_demangle-ambiguity.patch new file mode 100644 index 0000000..8a6c28b --- /dev/null +++ b/SOURCES/gcc32-cxa_demangle-ambiguity.patch @@ -0,0 +1,78 @@ +2005-02-13 Jason Merrill + + * cp-demangle.c (__cxa_demangle): Change resolution of ambiguous + arguments. + +2005-02-15 Jakub Jelinek + + PR libstdc++/19946 + * testsuite/demangle/abi_examples/01.cc (main): Adjust for 2005-02-13 + demangler change. + * testsuite/demangle/abi_examples/02.cc (main): Likewise. + +--- libiberty/cp-demangle.c 24 Nov 2004 02:19:09 -0000 1.75 ++++ libiberty/cp-demangle.c 13 Feb 2005 06:58:20 -0000 1.76 +@@ -4047,21 +4047,6 @@ __cxa_demangle (mangled_name, output_buf + return NULL; + } + +- /* The specification for __cxa_demangle() is that if the mangled +- name could be either an extern "C" identifier, or an internal +- built-in type name, then we resolve it as the identifier. All +- internal built-in type names are a single lower case character. +- Frankly, this simplistic disambiguation doesn't make sense to me, +- but it is documented, so we implement it here. */ +- if (IS_LOWER (mangled_name[0]) +- && mangled_name[1] == '\0' +- && cplus_demangle_builtin_types[mangled_name[0] - 'a'].name != NULL) +- { +- if (status != NULL) +- *status = -2; +- return NULL; +- } +- + demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc); + + if (demangled == NULL) +--- libstdc++-v3/testsuite/demangle/abi_examples/01.cc.jj 2004-03-09 16:09:24.000000000 +0100 ++++ libstdc++-v3/testsuite/demangle/abi_examples/01.cc 2005-02-14 09:05:09.383834357 +0100 +@@ -1,6 +1,6 @@ + // 2003-02-26 Benjamin Kosnik + +-// Copyright (C) 2003 Free Software Foundation, Inc. ++// Copyright (C) 2003, 2005 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +@@ -31,7 +31,9 @@ int main() + // extern "C" function + // extern "C" float f(void) { }; + // T f +- verify_demangle("f", "error code = -2: invalid mangled name"); ++ // f is ambiguous between "C" external name and internal built-in type ++ // name. The ambiguity is resolved to the built-in type name. ++ verify_demangle("f", "float"); + + return 0; + } +--- libstdc++-v3/testsuite/demangle/abi_examples/02.cc.jj 2004-03-09 16:09:24.000000000 +0100 ++++ libstdc++-v3/testsuite/demangle/abi_examples/02.cc 2005-02-14 09:05:59.661857808 +0100 +@@ -1,6 +1,6 @@ + // 2003-02-26 Benjamin Kosnik + +-// Copyright (C) 2003 Free Software Foundation, Inc. ++// Copyright (C) 2003, 2005 Free Software Foundation, Inc. + // + // This file is part of the GNU ISO C++ Library. This library is free + // software; you can redistribute it and/or modify it under the +@@ -31,7 +31,9 @@ int main() + // or variable "f" + // int f; + // B f +- verify_demangle("f", "error code = -2: invalid mangled name"); ++ // f is ambiguous between variable external name and internal built-in type ++ // name. The ambiguity is resolved to the built-in type name. ++ verify_demangle("f", "float"); + + return 0; + } diff --git a/SOURCES/gcc32-debug-cdtor.patch b/SOURCES/gcc32-debug-cdtor.patch new file mode 100644 index 0000000..033b118 --- /dev/null +++ b/SOURCES/gcc32-debug-cdtor.patch @@ -0,0 +1,17 @@ +2003-07-14 Mark Mitchell + + PR debug/11098 + * integrate.c (copy_decl_for_inlining): Do not mark copied decls + as DECL_ABSTRACT. + +--- gcc/integrate.c.jj 2003-02-14 09:26:34.000000000 +0100 ++++ gcc/integrate.c 2005-01-28 21:28:44.332792466 +0100 +@@ -368,6 +368,8 @@ copy_decl_for_inlining (decl, from_fn, t + else + { + copy = copy_node (decl); ++ /* The COPY is not abstract; it will be generated in TO_FN. */ ++ DECL_ABSTRACT (copy) = 0; + if (DECL_LANG_SPECIFIC (copy)) + copy_lang_decl (copy); + diff --git a/SOURCES/gcc32-demangle-pr16240.patch b/SOURCES/gcc32-demangle-pr16240.patch new file mode 100644 index 0000000..1c190f5 --- /dev/null +++ b/SOURCES/gcc32-demangle-pr16240.patch @@ -0,0 +1,32 @@ +2004-06-28 Ian Lance Taylor + + PR other/16240 + * cp-demangle.c (d_expr_primary): Check for a failure return from + cplus_demangle_type. + * testsuite/demangle-expected: Add test case. + +--- libiberty/cp-demangle.c 25 Feb 2004 04:51:37 -0000 1.73 ++++ libiberty/cp-demangle.c 28 Jun 2004 15:23:33 -0000 1.74 +@@ -2398,6 +2398,8 @@ d_expr_primary (di) + const char *s; + + type = cplus_demangle_type (di); ++ if (type == NULL) ++ return NULL; + + /* If we have a type we know how to print, we aren't going to + print the type name itself. */ +--- libiberty/testsuite/demangle-expected 25 Feb 2004 04:51:39 -0000 1.30 ++++ libiberty/testsuite/demangle-expected 28 Jun 2004 17:36:27 -0000 1.31 +@@ -3699,6 +3699,11 @@ _Z3fooIPA3_iEvRKT_ + void foo(int (* const&) [3]) + foo + # ++# This used to crash the demangler--PR 16240 ++--format=gnu-v3 --no-params ++_ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE ++_ZN13PatternDriver23StringScalarDeleteValueC1ERKNS_25ConflateStringScalarValueERKNS_25AbstractStringScalarValueERKNS_12TemplateEnumINS_12pdcomplementELZNS_16complement_namesEELZNS_14COMPLEMENTENUMEEEE ++PatternDriver::StringScalarDeleteValue::StringScalarDeleteValue + # Test GNU V3 constructor and destructor identification. + # 0 means it is not a constructor/destructor. + # Other integers correspond to enum gnu_v3_{c,d}tor_kinds in demangle.h. diff --git a/SOURCES/gcc32-dwarf2-pruning-keep-spec.patch b/SOURCES/gcc32-dwarf2-pruning-keep-spec.patch new file mode 100644 index 0000000..1dc503c --- /dev/null +++ b/SOURCES/gcc32-dwarf2-pruning-keep-spec.patch @@ -0,0 +1,28 @@ +2004-08-13 Alexandre Oliva + + * dwarf2out.c (prune_unused_types_walk): Mark the specification if + the declaration is marked. + +--- gcc/dwarf2out.c 2004-08-13 04:46:06.000000000 -0300 ++++ gcc/dwarf2out.c 2004-08-13 04:47:21.904025637 -0300 +@@ -12364,6 +12364,12 @@ prune_unused_types_walk (die) + return; + + switch (die->die_tag) { ++ case DW_TAG_structure_type: ++ /* If the declaration is marked, mark the specification as well. */ ++ if ((c = get_AT_ref (die, DW_AT_specification)) != NULL ++ && c->die_mark) ++ break; ++ + case DW_TAG_const_type: + case DW_TAG_packed_type: + case DW_TAG_pointer_type: +@@ -12371,7 +12377,6 @@ prune_unused_types_walk (die) + case DW_TAG_volatile_type: + case DW_TAG_typedef: + case DW_TAG_array_type: +- case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_class_type: + case DW_TAG_friend: diff --git a/SOURCES/gcc32-fc4-compile.patch b/SOURCES/gcc32-fc4-compile.patch new file mode 100644 index 0000000..0af6103 --- /dev/null +++ b/SOURCES/gcc32-fc4-compile.patch @@ -0,0 +1,30 @@ +--- gcc/tradcif.y.jj 2005-03-08 15:22:54.000000000 -0500 ++++ gcc/tradcif.y 2005-03-08 15:30:11.000000000 -0500 +@@ -29,6 +29,7 @@ Foundation, 59 Temple Place - Suite 330, + #include + #ifdef __GNUC__ + #define YYMALLOC nonexistent ++#define YYSTACK_USE_ALLOCA 1 + #endif + + static int yylex PARAMS ((void)); +--- gcc/cp/parse.y.jj 2005-03-08 15:53:07.821036000 -0500 ++++ gcc/cp/parse.y 2005-03-08 15:57:31.895819332 -0500 +@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA. */ + #include "ggc.h" + #ifdef __GNUC__ + #define YYMALLOC nonexistent ++#define YYSTACK_USE_ALLOCA 1 + #endif + + extern struct obstack permanent_obstack; +--- gcc/c-parse.in.jj 2005-03-08 15:53:07.828035000 -0500 ++++ gcc/c-parse.in 2005-03-08 15:57:07.787221389 -0500 +@@ -49,6 +49,7 @@ end ifc + #include "ggc.h" + #ifdef __GNUC__ + #define YYMALLOC nonexistent ++#define YYSTACK_USE_ALLOCA 1 + #endif + + #ifdef MULTIBYTE_CHARS diff --git a/SOURCES/gcc32-gnuc-rh-release.patch b/SOURCES/gcc32-gnuc-rh-release.patch new file mode 100644 index 0000000..1f6aa1a --- /dev/null +++ b/SOURCES/gcc32-gnuc-rh-release.patch @@ -0,0 +1,72 @@ +2005-11-10 Alexandre Oliva + + * gcc.c (cpp_unique_options): Add %vR. + (do_spec_1): Use it to define __GNUC_RH_RELEASE__. + +--- gcc/gcc.c 2005-11-10 14:59:39.000000000 -0200 ++++ gcc/gcc.c 2005-11-10 15:47:01.000000000 -0200 +@@ -696,7 +696,7 @@ + %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\ + %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\ + %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\ +- %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3 -D__GXX_ABI_VERSION=102}\ ++ %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3 %vR -D__GXX_ABI_VERSION=102}\ + %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\ + %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ + %{fno-inline|O0|!O*:-D__NO_INLINE__} %{ffast-math:-D__FAST_MATH__}\ +@@ -5226,7 +5226,7 @@ + + /* If desired, advance to third version number. + But don't complain if it's not present */ +- if (c1 == '3') ++ if (c1 >= '3') + { + /* Set V after the second period. */ + while (ISDIGIT (*v)) +@@ -5237,11 +5237,45 @@ + v++; + } + ++ if (c1 == 'R') ++ { ++ /* Move q to the end of compiler_version, so that we ++ can compare the beginning of compiler_version ++ with the beginning of version_string below. */ ++ q = v + strlen (v); ++ ++ v = strchr (version_string, '('); ++ if (v != NULL && strncmp (v + 1, "Red Hat ", 8) == 0) ++ { ++ v += 9; ++ if (strncmp (v, "Linux ", 6) == 0) ++ v += 6; ++ ++ /* If compiler_version changed, don't define ++ __GNUC_RH_RELEASE__. */ ++ if (strncmp (v, compiler_version, q - compiler_version) ++ != 0) ++ break; ++ ++ if (strncmp (v, version_string, q - compiler_version) ++ != 0 || v[q - compiler_version] != '-') ++ abort (); ++ ++ /* Skip the version and the dash. */ ++ v += q - compiler_version + 1; ++ obstack_grow (&obstack, "-D__GNUC_RH_RELEASE__=", ++ sizeof ("-D__GNUC_RH_RELEASE__=") - 1); ++ } ++ else ++ break; ++ } ++ + /* Set Q at the next period or at the end. */ + q = v; + while (ISDIGIT (*q)) + q++; +- if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-') ++ if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-' ++ && *q != ')') + abort (); + + if (q > v) diff --git a/SOURCES/gcc32-i386-prefetch-sse.patch b/SOURCES/gcc32-i386-prefetch-sse.patch new file mode 100644 index 0000000..643c7e2 --- /dev/null +++ b/SOURCES/gcc32-i386-prefetch-sse.patch @@ -0,0 +1,95 @@ +2004-07-09 Jakub Jelinek + + * Backport from mainline: + 2004-07-08 Paolo Bonzini + Jakub Jelinek + + * config/i386/i386.c (override_options): Enable + SSE prefetches with -mtune, as long as we are + compiling for i686 or higher. All i686 processors + accept SSE prefetches as NOPS, some i586's don't. + + 2004-07-07 Jakub Jelinek + + * config/i386/i386.c (override_options): Don't set x86_prefetch_sse + from -mtune= option. + +2004-07-08 Jakub Jelinek + + * gcc.mist-tests/i386-prefetch.exp (PREFETCH_SSE): Change all + -march=i386 into -march=i686. Add -march=i686 -mcpu=prescott and + -march=prescott. + +2003-08-04 Janis Johnson + + PR target/11739 + * gcc.misc-tests/i386-prefetch.exp: Use -march=i386 when specifying + a value for -mcpu. + +--- gcc/config/i386/i386.c.jj 2004-07-01 12:52:56.000000000 +0200 ++++ gcc/config/i386/i386.c 2004-08-12 14:26:55.039997547 +0200 +@@ -1064,11 +1064,17 @@ override_options () + ix86_cpu = processor_alias_table[i].processor; + if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT)) + error ("CPU you selected does not support x86-64 instruction set"); ++ ++ /* Intel CPUs have always interpreted SSE prefetch instructions as ++ NOPs; so, we can enable SSE prefetch instructions even when ++ -mtune (rather than -march) points us to a processor that has them. ++ However, the VIA C3 gives a SIGILL, so we only do that for i686 and ++ higher processors. */ ++ if (TARGET_CMOVE && (processor_alias_table[i].flags & PTA_PREFETCH_SSE)) ++ x86_prefetch_sse = true; + break; + } + +- if (processor_alias_table[i].flags & PTA_PREFETCH_SSE) +- x86_prefetch_sse = true; + if (i == pta_size) + error ("bad value (%s) for -mcpu= switch", ix86_cpu_string); + +--- gcc/testsuite/gcc.misc-tests/i386-prefetch.exp.jj 2002-01-18 19:41:41.000000000 +0100 ++++ gcc/testsuite/gcc.misc-tests/i386-prefetch.exp 2004-08-12 14:34:28.702060131 +0200 +@@ -24,14 +24,14 @@ + # Do not generate prefetch instructions for the following options. + + set PREFETCH_NONE [list \ +- { -mcpu=i386 } \ +- { -mcpu=i486 } \ +- { -mcpu=i586 } \ +- { -mcpu=i686 } \ +- { -mcpu=pentium2 } \ +- { -mcpu=k6 } \ +- { -mcpu=k6-2 } \ +- { -mcpu=k6-3 } \ ++ { -march=i386 -mcpu=i386 } \ ++ { -march=i386 -mcpu=i486 } \ ++ { -march=i386 -mcpu=i586 } \ ++ { -march=i386 -mcpu=i686 } \ ++ { -march=i386 -mcpu=pentium2 } \ ++ { -march=i386 -mcpu=k6 } \ ++ { -march=i386 -mcpu=k6-2 } \ ++ { -march=i386 -mcpu=k6-3 } \ + { -march=i386 } \ + { -march=i486 } \ + { -march=i586 } \ +@@ -44,12 +44,14 @@ set PREFETCH_NONE [list \ + # instructions as nops. + + set PREFETCH_SSE [list \ +- { -mcpu=pentium3 } \ +- { -mcpu=pentium4 } \ +- { -mcpu=athlon } \ +- { -mcpu=athlon-4 } \ ++ { -march=i686 -mcpu=pentium3 } \ ++ { -march=i686 -mcpu=pentium4 } \ ++ { -march=i686 -mcpu=prescott } \ ++ { -march=i686 -mcpu=athlon } \ ++ { -march=i686 -mcpu=athlon-4 } \ + { -march=pentium3 } \ +- { -march=pentium4 } ] ++ { -march=pentium4 } \ ++ { -march=prescott } ] + + # Generate 3DNow! prefetch instructions for the following. + diff --git a/SOURCES/gcc32-ia64-expand_load_address.patch b/SOURCES/gcc32-ia64-expand_load_address.patch new file mode 100644 index 0000000..e835d30 --- /dev/null +++ b/SOURCES/gcc32-ia64-expand_load_address.patch @@ -0,0 +1,17 @@ +2004-10-05 Richard Henderson + + * config/ia64/ia64.c (ia64_expand_load_address): Recurse for + base of addition. + +--- gcc/config/ia64/ia64.c 2003/11/21 14:18:53 1.139.2.15.8.11 ++++ gcc/config/ia64/ia64.c 2004/10/05 22:24:12 1.139.2.15.8.12 +@@ -1052,8 +1052,7 @@ + if (! scratch) + scratch = no_new_pseudos ? subtarget : gen_reg_rtx (DImode); + +- emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi), +- scratch)); ++ ia64_expand_load_address (subtarget, plus_constant (sym, hi), scratch); + emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo))); + } + else diff --git a/SOURCES/gcc32-ice-hack.patch b/SOURCES/gcc32-ice-hack.patch new file mode 100644 index 0000000..5980863 --- /dev/null +++ b/SOURCES/gcc32-ice-hack.patch @@ -0,0 +1,355 @@ +--- gcc/system.h.jj 2003-04-08 15:55:41.000000000 +0200 ++++ gcc/system.h 2003-10-03 19:01:24.000000000 +0200 +@@ -153,6 +153,10 @@ extern int errno; + # endif + #endif + ++#ifndef ICE_EXIT_CODE ++# define ICE_EXIT_CODE 27 ++#endif ++ + #ifdef HAVE_UNISTD_H + # include + #endif +--- gcc/gcc.c.jj 2003-06-11 15:08:12.000000000 +0200 ++++ gcc/gcc.c 2003-10-06 10:10:42.000000000 +0200 +@@ -112,6 +112,10 @@ extern int getrusage PARAMS ((int, struc + #define TARGET_OBJECT_SUFFIX ".o" + #endif + ++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS)) ++static void retry_ice PARAMS ((const char *, const char **)); ++#endif ++ + #ifndef VMS + /* FIXME: the location independence code for VMS is hairier than this, + and hasn't been written. */ +@@ -2857,7 +2861,7 @@ execute () + if (commands[i].pid == -1) + pfatal_pexecute (errmsg_fmt, errmsg_arg); + +- if (string != commands[i].prog) ++ if (i && string != commands[i].prog) + free ((PTR) string); + } + +@@ -2935,6 +2939,17 @@ See %s for instructions.", + else if (WIFEXITED (status) + && WEXITSTATUS (status) >= MIN_FATAL_STATUS) + { ++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS)) ++ /* For ICEs in cc1, cc1obj, cc1plus see if it is ++ reproducible or not. */ ++ char *p; ++ if (WEXITSTATUS (status) == ICE_EXIT_CODE ++ && j == 0 ++ && (p = strrchr (commands[j].argv[0], DIR_SEPARATOR)) ++ && ! strncmp (p + 1, "cc1", 3)) ++ retry_ice (commands[j].prog, commands[j].argv); ++#endif ++ + if (WEXITSTATUS (status) > greatest_status) + greatest_status = WEXITSTATUS (status); + ret_code = -1; +@@ -2946,6 +2961,10 @@ See %s for instructions.", + break; + } + } ++ ++ if (commands[0].argv[0] != commands[0].prog) ++ free ((PTR) commands[0].argv[0]); ++ + return ret_code; + } + } +@@ -5667,6 +5686,231 @@ give_switch (switchnum, omit_first_word, + switches[switchnum].validated = 1; + } + ++#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS)) ++#define RETRY_ICE_ATTEMPTS 2 ++ ++static void ++retry_ice (prog, argv) ++ const char *prog; ++ const char **argv; ++{ ++ int nargs, out_arg = -1, quiet = 0, attempt; ++ int pid, retries, sleep_interval; ++ const char **new_argv; ++ char *temp_filenames[RETRY_ICE_ATTEMPTS * 2 + 2]; ++ ++ if (input_filename == NULL || ! strcmp (input_filename, "-")) ++ return; ++ ++ for (nargs = 0; argv[nargs] != NULL; ++nargs) ++ /* Only retry compiler ICEs, not preprocessor ones. */ ++ if (! strcmp (argv[nargs], "-E")) ++ return; ++ else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o') ++ { ++ if (out_arg == -1) ++ out_arg = nargs; ++ else ++ return; ++ } ++ /* If the compiler is going to output any time information, ++ it might varry between invocations. */ ++ else if (! strcmp (argv[nargs], "-quiet")) ++ quiet = 1; ++ else if (! strcmp (argv[nargs], "-ftime-report")) ++ return; ++ ++ if (out_arg == -1 || !quiet) ++ return; ++ ++ memset (temp_filenames, '\0', sizeof (temp_filenames)); ++ new_argv = alloca ((nargs + 2) * sizeof (const char *)); ++ memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *)); ++ if (new_argv[out_arg][2] == '\0') ++ new_argv[out_arg + 1] = "-"; ++ else ++ new_argv[out_arg] = "-o-"; ++ ++ for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS + 1; ++attempt) ++ { ++ int fd; ++ int status; ++ ++ temp_filenames[attempt * 2] = make_temp_file (".out"); ++ temp_filenames[attempt * 2 + 1] = make_temp_file (".err"); ++ ++ if (attempt == RETRY_ICE_ATTEMPTS) ++ { ++ int i; ++ int fd1, fd2; ++ struct stat st1, st2; ++ size_t n, len; ++ char *buf; ++ char *cpp0; ++ ++ buf = xmalloc (8192); ++ ++ for (i = 0; i < 2; ++i) ++ { ++ fd1 = open (temp_filenames[i], O_RDONLY); ++ fd2 = open (temp_filenames[2 + i], O_RDONLY); ++ ++ if (fd1 < 0 || fd2 < 0) ++ { ++ i = -1; ++ close (fd1); ++ close (fd2); ++ break; ++ } ++ ++ if (fstat (fd1, &st1) < 0 || fstat (fd2, &st2) < 0) ++ { ++ i = -1; ++ close (fd1); ++ close (fd2); ++ break; ++ } ++ ++ if (st1.st_size != st2.st_size) ++ { ++ close (fd1); ++ close (fd2); ++ break; ++ } ++ ++ len = 0; ++ for (n = st1.st_size; n; n -= len) ++ { ++ len = n; ++ if (len > 4096) ++ len = 4096; ++ ++ if (read (fd1, buf, len) != (int) len ++ || read (fd2, buf + 4096, len) != (int) len) ++ { ++ i = -1; ++ break; ++ } ++ ++ if (memcmp (buf, buf + 4096, len) != 0) ++ break; ++ } ++ ++ close (fd1); ++ close (fd2); ++ ++ if (n) ++ break; ++ } ++ ++ free (buf); ++ if (i == -1) ++ break; ++ ++ if (i != 2) ++ { ++ notice ("The bug is not reproducible, so it is likely a hardware or OS problem.\n"); ++ break; ++ } ++ ++ fd = open (temp_filenames[attempt * 2], O_RDWR); ++ if (fd < 0) ++ break; ++ write (fd, "//", 2); ++ for (i = 0; i < nargs; i++) ++ { ++ write (fd, " ", 1); ++ write (fd, new_argv[i], strlen (new_argv[i])); ++ } ++ write (fd, "\n", 1); ++ cpp0 = alloca (strlen (new_argv[0]) + sizeof "cpp0"); ++ strcpy (cpp0, new_argv[0]); ++ new_argv[0] = cpp0; ++ cpp0 = strrchr (new_argv[0], DIR_SEPARATOR); ++ if (cpp0 != NULL) ++ strcpy (cpp0 + 1, "cpp0"); ++ new_argv[nargs] = "--ice-hack"; ++ new_argv[nargs + 1] = NULL; ++ } ++ ++ /* Fork a subprocess; wait and retry if it fails. */ ++ sleep_interval = 1; ++ pid = -1; ++ for (retries = 0; retries < 4; retries++) ++ { ++ pid = fork (); ++ if (pid >= 0) ++ break; ++ sleep (sleep_interval); ++ sleep_interval *= 2; ++ } ++ ++ if (pid < 0) ++ break; ++ else if (pid == 0) ++ { ++ if (attempt != RETRY_ICE_ATTEMPTS) ++ fd = open (temp_filenames[attempt * 2], O_RDWR); ++ if (fd < 0) ++ exit (-1); ++ if (fd != 1) ++ { ++ close (1); ++ dup (fd); ++ close (fd); ++ } ++ ++ fd = open (temp_filenames[attempt * 2 + 1], O_RDWR); ++ if (fd < 0) ++ exit (-1); ++ if (fd != 2) ++ { ++ close (2); ++ dup (fd); ++ close (fd); ++ } ++ ++ if (prog == new_argv[0]) ++ execvp (prog, (char *const *) new_argv); ++ else ++ execv (new_argv[0], (char *const *) new_argv); ++ exit (-1); ++ } ++ ++ if (waitpid (pid, &status, 0) < 0) ++ break; ++ ++ if (attempt < RETRY_ICE_ATTEMPTS ++ && (! WIFEXITED (status) || WEXITSTATUS (status) != ICE_EXIT_CODE)) ++ { ++ notice ("The bug is not reproducible, so it is likely a hardware or OS problem.\n"); ++ break; ++ } ++ else if (attempt == RETRY_ICE_ATTEMPTS) ++ { ++ close (fd); ++ if (WIFEXITED (status) ++ && WEXITSTATUS (status) == SUCCESS_EXIT_CODE) ++ { ++ notice ("Preprocessed source stored into %s file, please attach this to your bugreport.\n", ++ temp_filenames[attempt * 2]); ++ /* Make sure it is not deleted. */ ++ free (temp_filenames[attempt * 2]); ++ temp_filenames[attempt * 2] = NULL; ++ break; ++ } ++ } ++ } ++ ++ for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS * 2 + 2; attempt++) ++ if (temp_filenames[attempt]) ++ { ++ unlink (temp_filenames[attempt]); ++ free (temp_filenames[attempt]); ++ } ++} ++#endif ++ + /* Search for a file named NAME trying various prefixes including the + user's -B prefix and some standard ones. + Return the absolute file name found. If nothing is found, return NAME. */ +--- gcc/diagnostic.c.jj 2002-01-24 23:37:04.000000000 +0100 ++++ gcc/diagnostic.c 2003-10-03 19:01:24.000000000 +0200 +@@ -1242,7 +1242,7 @@ internal_error VPARAMS ((const char *msg + "Please submit a full bug report,\n\ + with preprocessed source if appropriate.\n\ + See %s for instructions.\n", GCCBUGURL); +- exit (FATAL_EXIT_CODE); ++ exit (ICE_EXIT_CODE); + } + + void +@@ -1392,7 +1392,7 @@ error_recursion () + "Please submit a full bug report,\n\ + with preprocessed source if appropriate.\n\ + See %s for instructions.\n", GCCBUGURL); +- exit (FATAL_EXIT_CODE); ++ exit (ICE_EXIT_CODE); + } + + /* Given a partial pathname as input, return another pathname that +--- gcc/cppmain.c.jj 2002-05-03 20:19:22.000000000 +0200 ++++ gcc/cppmain.c 2003-10-06 10:35:15.000000000 +0200 +@@ -111,10 +111,33 @@ do_preprocessing (argc, argv) + char **argv; + { + int argi = 1; /* Next argument to handle. */ ++ int ice_hack = 0; + +- argi += cpp_handle_options (pfile, argc - argi , argv + argi); +- if (CPP_FATAL_ERRORS (pfile)) +- return; ++ if (argc >= 1 && strcmp (argv[argc - 1], "--ice-hack") == 0) ++ { ++ ice_hack = 1; ++ for (argi = 1; argi + 1 < argc; argi++) ++ if (strcmp (argv[argi], "-dumpbase") == 0) ++ { ++ argv[argi] = "-quiet"; ++ argv[argi + 1] = "-quiet"; ++ break; ++ } ++ argi = 1; ++ } ++ ++ do ++ { ++ argi += cpp_handle_options (pfile, argc - argi, argv + argi); ++ if (CPP_FATAL_ERRORS (pfile)) ++ return; ++ ++ if (argi >= argc || !ice_hack) ++ break; ++ ++ argi++; ++ } ++ while (argi < argc); + + if (argi < argc) + { diff --git a/SOURCES/gcc32-java-bytecode.patch b/SOURCES/gcc32-java-bytecode.patch new file mode 100644 index 0000000..8b865a9 --- /dev/null +++ b/SOURCES/gcc32-java-bytecode.patch @@ -0,0 +1,23 @@ +2004-08-14 Jakub Jelinek + + * fold-const.c (fold): If flag_syntax_only, don't depend on + BITS_PER_WORD. + +--- gcc/fold-const.c.jj 2004-08-14 12:17:15.000000000 +0200 ++++ gcc/fold-const.c 2004-08-14 13:00:37.814514205 +0200 +@@ -5204,10 +5204,11 @@ fold (expr) + && TREE_CODE (TREE_OPERAND (t, 2)) == code + && (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0)) + == TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 2), 0))) +- && ! (INTEGRAL_TYPE_P (TREE_TYPE (t)) +- && (INTEGRAL_TYPE_P +- (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0)))) +- && TYPE_PRECISION (TREE_TYPE (t)) <= BITS_PER_WORD)) ++ && (! (INTEGRAL_TYPE_P (TREE_TYPE (t)) ++ && (INTEGRAL_TYPE_P ++ (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0)))) ++ && TYPE_PRECISION (TREE_TYPE (t)) <= BITS_PER_WORD) ++ || flag_syntax_only)) + t = build1 (code, type, + build (COND_EXPR, + TREE_TYPE (TREE_OPERAND diff --git a/SOURCES/gcc32-java-intlex.patch b/SOURCES/gcc32-java-intlex.patch new file mode 100644 index 0000000..3ac22db --- /dev/null +++ b/SOURCES/gcc32-java-intlex.patch @@ -0,0 +1,175 @@ +2002-11-05 Tom Tromey + + Fix for PR java/6388. + * lex.h (JAVA_INTEGRAL_RANGE_ERROR): Wrap in do...while. + * java-tree.h (enum java_tree_index): New values + JTI_DECIMAL_INT_MAX_NODE, JTI_DECIMAL_LONG_MAX_NODE. + (decimal_int_max, decimal_long_max): New defines. + * lex.c (yylex): Rewrote range checking. Sign extend literals. + (error_if_numeric_overflow): Rewrote range checking. + * decl.c (java_init_decl_processing): Initialize decimal_int_max, + decimal_long_max. + +--- gcc/java/decl.c 2 Nov 2002 21:29:36 -0000 1.134 ++++ gcc/java/decl.c 6 Nov 2002 00:01:00 -0000 1.135 +@@ -454,6 +454,20 @@ java_init_decl_processing () + integer_four_node = build_int_2 (4, 0); + integer_minus_one_node = build_int_2 (-1, -1); + ++ /* A few values used for range checking in the lexer. */ ++ decimal_int_max = build_int_2 (0x80000000, 0); ++ TREE_TYPE (decimal_int_max) = unsigned_int_type_node; ++#if HOST_BITS_PER_WIDE_INT == 64 ++ decimal_long_max = build_int_2 (0x8000000000000000, 0); ++#else ++#if HOST_BITS_PER_WIDE_INT == 32 ++ decimal_long_max = build_int_2 (0, 0x80000000); ++#else ++ #error "unsupported size" ++#endif ++#endif ++ TREE_TYPE (decimal_long_max) = unsigned_long_type_node; ++ + size_zero_node = size_int (0); + size_one_node = size_int (1); + bitsize_zero_node = bitsize_int (0); +--- gcc/java/java-tree.h 2 Nov 2002 23:52:26 -0000 1.161 ++++ gcc/java/java-tree.h 6 Nov 2002 00:01:00 -0000 1.162 +@@ -275,6 +275,9 @@ enum java_tree_index + JTI_UNSIGNED_INT_TYPE_NODE, + JTI_UNSIGNED_LONG_TYPE_NODE, + ++ JTI_DECIMAL_INT_MAX_NODE, ++ JTI_DECIMAL_LONG_MAX_NODE, ++ + JTI_BOOLEAN_TYPE_NODE, + + JTI_OBJECT_TYPE_NODE, +@@ -441,6 +444,11 @@ extern GTY(()) tree java_global_trees[JT + #define unsigned_long_type_node \ + java_global_trees[JTI_UNSIGNED_LONG_TYPE_NODE] + ++#define decimal_int_max \ ++ java_global_trees[JTI_DECIMAL_INT_MAX_NODE] ++#define decimal_long_max \ ++ java_global_trees[JTI_DECIMAL_LONG_MAX_NODE] ++ + #define boolean_type_node \ + java_global_trees[JTI_BOOLEAN_TYPE_NODE] + +--- gcc/java/lex.c 2 Nov 2002 21:29:36 -0000 1.94 ++++ gcc/java/lex.c 6 Nov 2002 00:01:01 -0000 1.95 +@@ -1218,34 +1218,35 @@ java_lex (java_lval) + } + /* End borrowed section. */ + ++#ifndef JC1_LITE + /* Range checking. */ +- if (long_suffix) ++ value = build_int_2 (low, high); ++ /* Temporarily set type to unsigned. */ ++ SET_LVAL_NODE_TYPE (value, (long_suffix ++ ? unsigned_long_type_node ++ : unsigned_int_type_node)); ++ ++ /* For base 10 numbers, only values up to the highest value ++ (plus one) can be written. For instance, only ints up to ++ 2147483648 can be written. The special case of the largest ++ negative value is handled elsewhere. For other bases, any ++ number can be represented. */ ++ if (overflow || (radix == 10 ++ && tree_int_cst_lt (long_suffix ++ ? decimal_long_max ++ : decimal_int_max, ++ value))) + { +- /* 9223372036854775808L is valid if operand of a '-'. Otherwise +- 9223372036854775807L is the biggest `long' literal that can be +- expressed using a 10 radix. For other radices, everything that +- fits withing 64 bits is OK. */ +- int hb = (high >> 31); +- if (overflow || (hb && low && radix == 10) +- || (hb && high & 0x7fffffff && radix == 10)) ++ if (long_suffix) + JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `long' literal"); +- } +- else +- { +- /* 2147483648 is valid if operand of a '-'. Otherwise, +- 2147483647 is the biggest `int' literal that can be +- expressed using a 10 radix. For other radices, everything +- that fits within 32 bits is OK. As all literals are +- signed, we sign extend here. */ +- int hb = (low >> 31) & 0x1; +- if (overflow || high || (hb && low & 0x7fffffff && radix == 10)) ++ else + JAVA_INTEGRAL_RANGE_ERROR ("Numeric overflow for `int' literal"); +- high = -hb; + } +-#ifndef JC1_LITE +- value = build_int_2 (low, high); ++ ++ /* Sign extend the value. */ ++ SET_LVAL_NODE_TYPE (value, (long_suffix ? long_type_node : int_type_node)); ++ force_fit_type (value, 0); + JAVA_RADIX10_FLAG (value) = radix == 10; +- SET_LVAL_NODE_TYPE (value, long_suffix ? long_type_node : int_type_node); + #else + SET_LVAL_NODE_TYPE (build_int_2 (low, high), + long_suffix ? long_type_node : int_type_node); +@@ -1661,24 +1662,14 @@ static void + error_if_numeric_overflow (value) + tree value; + { +- if (TREE_CODE (value) == INTEGER_CST && JAVA_RADIX10_FLAG (value)) ++ if (TREE_CODE (value) == INTEGER_CST ++ && JAVA_RADIX10_FLAG (value) ++ && tree_int_cst_sgn (value) < 0) + { +- unsigned HOST_WIDE_INT lo, hi; +- +- lo = TREE_INT_CST_LOW (value); +- hi = TREE_INT_CST_HIGH (value); + if (TREE_TYPE (value) == long_type_node) +- { +- int hb = (hi >> 31); +- if (hb && !(hi & 0x7fffffff)) +- java_lex_error ("Numeric overflow for `long' literal", 0); +- } ++ java_lex_error ("Numeric overflow for `long' literal", 0); + else +- { +- int hb = (lo >> 31) & 0x1; +- if (hb && !(lo & 0x7fffffff)) +- java_lex_error ("Numeric overflow for `int' literal", 0); +- } ++ java_lex_error ("Numeric overflow for `int' literal", 0); + } + } + #endif /* JC1_LITE */ +--- gcc/java/lex.h 2 Nov 2002 21:29:36 -0000 1.28 ++++ gcc/java/lex.h 6 Nov 2002 00:01:01 -0000 1.29 +@@ -185,7 +185,7 @@ extern void java_destroy_lexer PARAMS (( + #define SET_LVAL_NODE_TYPE(NODE, TYPE) + #define BUILD_ID_WFL(EXP) (EXP) + #define JAVA_FLOAT_RANGE_ERROR(S) {} +-#define JAVA_INTEGRAL_RANGE_ERROR(S) {} ++#define JAVA_INTEGRAL_RANGE_ERROR(S) do { } while (0) + + #else + +@@ -237,12 +237,12 @@ extern void java_destroy_lexer PARAMS (( + ctxp->c_line->current = i; \ + } + #define JAVA_INTEGRAL_RANGE_ERROR(m) \ +- { \ ++ do { \ + int i = ctxp->c_line->current; \ + ctxp->c_line->current = number_beginning; \ + java_lex_error (m, 0); \ + ctxp->c_line->current = i; \ +- } ++ } while (0) + + #endif /* Definitions for jc1 compilation only */ + diff --git a/SOURCES/gcc32-java-nan.patch b/SOURCES/gcc32-java-nan.patch new file mode 100644 index 0000000..b664554 --- /dev/null +++ b/SOURCES/gcc32-java-nan.patch @@ -0,0 +1,27 @@ +2004-08-13 Andrew Haley + + * jcf-write.c (find_constant_index): Canonicalize NaN. + +--- gcc/java/jcf-write.c.jj 2002-10-16 22:36:11.000000000 +0100 ++++ gcc/java/jcf-write.c 2004-08-13 17:10:37.000000000 +0100 +@@ -828,12 +828,20 @@ + long words[2]; + if (TYPE_PRECISION (TREE_TYPE (value)) == 32) + { ++ if (REAL_VALUE_ISNAN (TREE_REAL_CST (value)) ++ && flag_emit_class_files) ++ return find_constant1 (&state->cpool, CONSTANT_Float, ++ 0x7fc00000); + words[0] = etarsingle (TREE_REAL_CST (value)) & 0xFFFFFFFF; + return find_constant1 (&state->cpool, CONSTANT_Float, + (jword)words[0]); + } + else + { ++ if (REAL_VALUE_ISNAN (TREE_REAL_CST (value)) ++ && flag_emit_class_files) ++ return find_constant2 (&state->cpool, CONSTANT_Double, ++ 0x7ff80000, 0x00000000); + etardouble (TREE_REAL_CST (value), words); + return find_constant2 (&state->cpool, CONSTANT_Double, + (jword)(words[1-FLOAT_WORDS_BIG_ENDIAN] & diff --git a/SOURCES/gcc32-java-zoneinfo.patch b/SOURCES/gcc32-java-zoneinfo.patch new file mode 100644 index 0000000..6598017 --- /dev/null +++ b/SOURCES/gcc32-java-zoneinfo.patch @@ -0,0 +1,4206 @@ +2007-02-24 Jakub Jelinek + + * java/util/TimeZone.java (getDefaultDisplayName): Don't + check if TimeZone is instanceof SimpleTimeZone. + +2007-02-23 Jakub Jelinek + + PR libgcj/17002 + PR classpath/28550 + * java/lang/System.java: Add gnu.java.util.zoneinfo.dir to comments. + * posix.cc (_Jv_platform_initProperties): Set + gnu.java.util.zoneinfo.dir. + * Makefile.am (ordinary_java_source_files): Add + gnu/java/util/ZoneInfo.java. + * Makefile.in: Regenerated. + * java/util/Date.java (parse): Properly parse 09:01:02 as + hours/minutes/seconds, not as hours/minutes/year. + * java/util/SimpleTimeZone.java (getOffset): Handle properly + millis + dstOffset overflowing into the next day. + * java/util/TimeZone.java (zoneinfo_dir, availableIDs, aliases0): New + static fields. + (timezones): Remove synchronized keyword. Set zoneinfo_dir. + If non-null, set up aliases0 and don't put anything into + timezones0. + (defaultZone): Call getTZEnvVar to try TZ env var. + Try to read /etc/localtime using ZoneInfo.readTZFile. + Call getDefaultTimeZone instead of getTimeZone. + (getDefaultTimeZone, getDateParams, parseTime): New private methods. + (getTimeZoneInternal): New private method. + (getTimeZone): Do the custom ID checking first, canonicalize + ID for custom IDs as required by documentation. Call + getTimeZoneInternal to handle the rest. + (getAvailableIDs(int)): Add locking. Handle zoneinfo_dir != null. + (getAvailableIDs(File,String,ArrayList)): New private method. + (getAvailableIDs()): Add locking. Handle zoneinfo_dir != null. + (readSysconfigClockFile): New static method. + (getTZEnvVar): New native method. + * java/util/natSystem.cc: Include java/lang/Character.h and + java/lang/Integer.h. + (java::lang::System::getSystemTimeZone): Renamed to... + (getSystemTimeZone): ... this. Add static. + (java::lang::System::init_properties): Don't set user.timezone + property. + (java::util::TimeZone::getDefaultTimeZoneId): New. + (java::util::TimeZone::getTZEnvVar): New method. + * gnu/java/util/ZoneInfo.java: New file. + * java/util/GregorianCalendar.java + (GregorianCalendar): Call clear before set in the constructors that + don't initialize it to current time. + +2007-02-09 Jakub Jelinek + + PR 23566 + * java/util/TimeZone.java (timezones): Regenerate from tzdata2007a. + +2005-02-21 Jeroen Frijters + + * java/util/GregorianCalendar.java + (GregorianCalendar): Chained constructors to a (new) + common constructor. + +2004-01-03 Per Bothner + + * java/util/Date.java (parse): Fix a number of problems. + (skipParens): Remove no-longer-needed method. + +2003-11-27 Ito Kazumitsu + + * java/util/GregorianCalendar.java (getLinearTime): Avoid counting + the leap day of the leap year twice. + +2003-09-18 Ingo Proetel + + * java/util/TimeZone.java: Initialize lazily. + +2002-05-13 Tom Tromey + + * java/util/TimeZone.java (getDefaultTimeZoneId): New method. + +--- libjava/Makefile.am.jj 2007-02-23 21:17:39.000000000 +0100 ++++ libjava/Makefile.am 2007-02-23 21:28:22.000000000 +0100 +@@ -1431,6 +1431,7 @@ gnu/java/text/LineBreakIterator.java \ + gnu/java/text/SentenceBreakIterator.java \ + gnu/java/text/WordBreakIterator.java \ + gnu/java/util/DoubleEnumeration.java \ ++gnu/java/util/ZoneInfo.java \ + java/lang/ref/PhantomReference.java \ + java/lang/ref/Reference.java \ + java/lang/ref/ReferenceQueue.java \ +--- libjava/Makefile.in.jj 2007-02-23 21:17:39.000000000 +0100 ++++ libjava/Makefile.in 2007-02-23 21:28:55.000000000 +0100 +@@ -1183,6 +1183,7 @@ gnu/java/text/LineBreakIterator.java \ + gnu/java/text/SentenceBreakIterator.java \ + gnu/java/text/WordBreakIterator.java \ + gnu/java/util/DoubleEnumeration.java \ ++gnu/java/util/ZoneInfo.java \ + java/lang/ref/PhantomReference.java \ + java/lang/ref/Reference.java \ + java/lang/ref/ReferenceQueue.java \ +@@ -2017,7 +2018,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_D + .deps/gnu/java/text/LineBreakIterator.P \ + .deps/gnu/java/text/SentenceBreakIterator.P \ + .deps/gnu/java/text/WordBreakIterator.P \ +-.deps/gnu/java/util/DoubleEnumeration.P .deps/interpret.P \ ++.deps/gnu/java/util/DoubleEnumeration.P \ ++.deps/gnu/java/util/ZoneInfo.P .deps/interpret.P \ + .deps/java/applet/Applet.P .deps/java/applet/AppletContext.P \ + .deps/java/applet/AppletStub.P .deps/java/applet/AudioClip.P \ + .deps/java/awt/AWTError.P .deps/java/awt/AWTEvent.P \ +--- libjava/java/util/GregorianCalendar.java.jj 2007-02-23 21:17:36.000000000 +0100 ++++ libjava/java/util/GregorianCalendar.java 2007-02-26 09:54:12.000000000 +0100 +@@ -111,6 +111,13 @@ public class GregorianCalendar extends C + this(TimeZone.getDefault(), locale); + } + ++ private GregorianCalendar(TimeZone zone, Locale locale, boolean unused) ++ { ++ super(zone, locale); ++ ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale); ++ gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime(); ++ } ++ + /** + * Constructs a new GregorianCalender representing the current + * time with the given time zone and the given locale. +@@ -119,9 +126,7 @@ public class GregorianCalendar extends C + */ + public GregorianCalendar(TimeZone zone, Locale locale) + { +- super(zone, locale); +- ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale); +- gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime(); ++ this(zone, locale, false); + setTimeInMillis(System.currentTimeMillis()); + } + +@@ -134,7 +139,8 @@ public class GregorianCalendar extends C + */ + public GregorianCalendar(int year, int month, int day) + { +- super(); ++ this(TimeZone.getDefault(), Locale.getDefault(), false); ++ clear(); + set(year, month, day); + } + +@@ -149,7 +155,8 @@ public class GregorianCalendar extends C + */ + public GregorianCalendar(int year, int month, int day, int hour, int minute) + { +- super(); ++ this(TimeZone.getDefault(), Locale.getDefault(), false); ++ clear(); + set(year, month, day, hour, minute); + } + +@@ -166,7 +173,8 @@ public class GregorianCalendar extends C + public GregorianCalendar(int year, int month, int day, + int hour, int minute, int second) + { +- super(); ++ this(TimeZone.getDefault(), Locale.getDefault(), false); ++ clear(); + set(year, month, day, hour, minute, second); + } + +@@ -254,8 +262,10 @@ public class GregorianCalendar extends C + // + // The additional leap year factor accounts for the fact that + // a leap day is not seen on Jan 1 of the leap year. ++ // And on and after the leap day, the leap day has already been ++ // included in dayOfYear. + int gregOffset = (year / 400) - (year / 100) + 2; +- if (isLeapYear (year, true) && dayOfYear < 31 + 29) ++ if (isLeapYear (year, true)) + --gregOffset; + time += gregOffset * (24 * 60 * 60 * 1000L); + } +--- libjava/java/util/SimpleTimeZone.java.jj 2007-02-23 21:17:36.000000000 +0100 ++++ libjava/java/util/SimpleTimeZone.java 2007-02-23 21:27:21.000000000 +0100 +@@ -458,16 +458,34 @@ public class SimpleTimeZone extends Time + int daylightSavings = 0; + if (useDaylight && era == GregorianCalendar.AD && year >= startYear) + { ++ int orig_year = year; + // This does only work for Gregorian calendars :-( + // This is mainly because setStartYear doesn't take an era. + + boolean afterStart = !isBefore(year, month, day, dayOfWeek, millis, + startMode, startMonth, + startDay, startDayOfWeek, startTime); ++ millis += dstSavings; ++ if (millis >= 24 * 60 * 60 * 1000) ++ { ++ millis -= 24 * 60 * 60 * 1000; ++ dayOfWeek = (dayOfWeek % 7) + 1; ++ if (++day > getDaysInMonth(month, year)) ++ { ++ day = 1; ++ if (month++ == Calendar.DECEMBER) ++ { ++ month = Calendar.JANUARY; ++ year++; ++ } ++ } ++ } + boolean beforeEnd = isBefore(year, month, day, dayOfWeek, millis, + endMode, endMonth, + endDay, endDayOfWeek, endTime); + ++ if (orig_year != year) ++ afterStart = false; + if (startMonth < endMonth) + { + // use daylight savings, if the date is after the start of +--- libjava/java/util/Date.java.jj 2007-02-23 21:17:36.000000000 +0100 ++++ libjava/java/util/Date.java 2007-02-26 09:43:28.000000000 +0100 +@@ -304,34 +304,6 @@ public class Date implements Cloneable, + return format.format(this); + } + +- private static int skipParens(String string, int offset) +- { +- int len = string.length(); +- int p = 0; +- int i; +- +- for (i = offset; i < len; ++i) +- { +- if (string.charAt(i) == '(') +- ++p; +- else if (string.charAt(i) == ')') +- { +- --p; +- if (p == 0) +- return i + 1; +- // If we've encounted unbalanced parens, just return the +- // leftover one as an ordinary character. It will be +- // caught later in parsing and cause an +- // IllegalArgumentException. +- if (p < 0) +- return i; +- } +- } +- +- // Not sure what to do if `p != 0' here. +- return i; +- } +- + private static int parseTz(String tok, char sign) + throws IllegalArgumentException + { +@@ -408,20 +380,25 @@ public class Date implements Cloneable, + + // Trim out any nested stuff in parentheses now to make parsing easier. + StringBuffer buf = new StringBuffer(); +- int off = 0; +- int openParenOffset, tmpMonth; +- while ((openParenOffset = string.indexOf('(', off)) >= 0) ++ int parenNesting = 0; ++ int len = string.length(); ++ for (int i = 0; i < len; i++) + { +- // Copy part of string leading up to open paren. +- buf.append(string.substring(off, openParenOffset)); +- off = skipParens(string, openParenOffset); ++ char ch = string.charAt(i); ++ if (ch >= 'a' && ch <= 'z') ++ ch -= 'a' - 'A'; ++ if (ch == '(') ++ parenNesting++; ++ else if (parenNesting == 0) ++ buf.append(ch); ++ else if (ch == ')') ++ parenNesting--; + } +- buf.append(string.substring(off)); ++ int tmpMonth; + + // Make all chars upper case to simplify comparisons later. + // Also ignore commas; treat them as delimiters. +- StringTokenizer strtok = +- new StringTokenizer(buf.toString().toUpperCase(), " \t\n\r,"); ++ StringTokenizer strtok = new StringTokenizer(buf.toString(), " \t\n\r,"); + + while (strtok.hasMoreTokens()) + { +@@ -434,58 +411,69 @@ public class Date implements Cloneable, + } + else if (firstch >= '0' && firstch <= '9') + { ++ int lastPunct = -1; + while (tok != null && tok.length() > 0) + { +- // A colon or slash may be valid in the number. +- // Find the first of these before calling parseInt. +- int colon = tok.indexOf(':'); +- int slash = tok.indexOf('/'); +- int hyphen = tok.indexOf('-'); +- // We choose tok.length initially because it makes +- // processing simpler. +- int punctOffset = tok.length(); +- if (colon >= 0) +- punctOffset = Math.min(punctOffset, colon); +- if (slash >= 0) +- punctOffset = Math.min(punctOffset, slash); +- if (hyphen >= 0) +- punctOffset = Math.min(punctOffset, hyphen); +- // Following code relies on -1 being the exceptional +- // case. +- if (punctOffset == tok.length()) +- punctOffset = -1; +- +- int num; +- try +- { +- num = Integer.parseInt(punctOffset < 0 ? tok : +- tok.substring(0, punctOffset)); +- } +- catch (NumberFormatException ex) +- { +- throw new IllegalArgumentException(tok); +- } +- +- // TBD: Spec says year can be followed by a slash. That might +- // make sense if using YY/MM/DD formats, but it would fail in +- // that format for years <= 70. Also, what about 1900? That +- // is interpreted as the year 3800; seems that the comparison +- // should be num >= 1900 rather than just > 1900. +- // What about a year of 62 - 70? (61 or less could be a (leap) +- // second). 70/MM/DD cause an exception but 71/MM/DD is ok +- // even though there's no ambiguity in either case. +- // For the parse method, the spec as written seems too loose. +- // Until shown otherwise, we'll follow the spec as written. +- if (num > 70 && (punctOffset < 0 || punctOffset == slash)) +- year = num > 1900 ? num - 1900 : num; +- else if (punctOffset > 0 && punctOffset == colon) ++ int punctOffset = tok.length(); ++ int num = 0; ++ int punct; ++ for (int i = 0; ; i++) ++ { ++ if (i >= punctOffset) ++ { ++ punct = -1; ++ break; ++ } ++ else ++ { ++ punct = tok.charAt(i); ++ if (punct >= '0' && punct <= '9') ++ { ++ if (num > 999999999) // in case of overflow ++ throw new IllegalArgumentException(tok); ++ num = 10 * num + (punct - '0'); ++ } ++ else ++ { ++ punctOffset = i; ++ break; ++ } ++ } ++ ++ } ++ ++ if (punct == ':') + { + if (hour < 0) + hour = num; + else + minute = num; + } +- else if (punctOffset > 0 && punctOffset == slash) ++ else if (lastPunct == ':' && hour >= 0 && (minute < 0 || second < 0)) ++ { ++ if (minute < 0) ++ minute = num; ++ else ++ second = num; ++ } ++ else if ((num >= 70 ++ && (punct == ' ' || punct == ',' ++ || punct == '/' || punct < 0)) ++ || (num < 70 && day >= 0 && month >= 0 && year < 0)) ++ { ++ if (num >= 100) ++ year = num; ++ else ++ { ++ int curYear = 1900 + new Date().getYear(); ++ int firstYear = curYear - 80; ++ year = firstYear / 100 * 100 + num; ++ int yx = year; ++ if (year < firstYear) ++ year += 100; ++ } ++ } ++ else if (punct == '/') + { + if (month < 0) + month = num - 1; +@@ -502,10 +490,11 @@ public class Date implements Cloneable, + throw new IllegalArgumentException(tok); + + // Advance string if there's more to process in this token. +- if (punctOffset < 0 || punctOffset + 1 >= tok.length()) ++ if (punct < 0 || punctOffset + 1 >= tok.length()) + tok = null; + else + tok = tok.substring(punctOffset + 1); ++ lastPunct = punct; + } + } + else if (firstch >= 'A' && firstch <= 'Z') +@@ -573,22 +562,29 @@ public class Date implements Cloneable, + throw new IllegalArgumentException(tok); + } + +- // Unspecified minutes and seconds should default to 0. ++ // Unspecified hours, minutes, or seconds should default to 0. ++ if (hour < 0) ++ hour = 0; + if (minute < 0) + minute = 0; + if (second < 0) + second = 0; + + // Throw exception if any other fields have not been recognized and set. +- if (year < 0 || month < 0 || day < 0 || hour < 0) ++ if (year < 0 || month < 0 || day < 0) + throw new IllegalArgumentException("Missing field"); + + // Return the time in either local time or relative to GMT as parsed. + // If no time-zone was specified, get the local one (in minutes) and + // convert to milliseconds before adding to the UTC. +- return UTC(year, month, day, hour, minute, second) + (localTimezone ? +- new Date(year, month, day).getTimezoneOffset() * 60 * 1000: +- -timezone * 60 * 1000); ++ GregorianCalendar cal ++ = new GregorianCalendar(year, month, day, hour, minute, second); ++ if (!localTimezone) ++ { ++ cal.set(Calendar.ZONE_OFFSET, timezone * 60 * 1000); ++ cal.set(Calendar.DST_OFFSET, 0); ++ } ++ return cal.getTimeInMillis(); + } + + /** +--- libjava/java/lang/natSystem.cc.jj 2007-02-23 21:17:31.000000000 +0100 ++++ libjava/java/lang/natSystem.cc 2007-02-24 22:04:41.000000000 +0100 +@@ -51,6 +51,8 @@ details. */ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -229,61 +231,6 @@ getpwuid_adaptor(T_passwd * (*getpwuid_r + } + #endif + +-/* +- * This method returns a time zone string that is used by init_properties +- * to set the default timezone property 'user.timezone'. That value is +- * used by default as a key into the timezone table used by the +- * java::util::TimeZone class. +- */ +-jstring +-java::lang::System::getSystemTimeZone (void) +-{ +- struct tm *tim; +- time_t current_time; +- long tzoffset; +- const char *tz1, *tz2; +- char *tzid; +- +- current_time = time(0); +- +- mktime(tim = localtime(¤t_time)); +-#ifdef STRUCT_TM_HAS_GMTOFF +- // tm_gmtoff is secs EAST of UTC. +- tzoffset = -(tim->tm_gmtoff) + tim->tm_isdst * 3600L; +-#elif HAVE_TIMEZONE +- // timezone is secs WEST of UTC. +- tzoffset = timezone; +-#else +- // FIXME: there must be another global if neither tm_gmtoff nor timezone +- // is available, esp. if tzname is valid. +- // Richard Earnshaw has suggested using difftime to +- // calculate between gmtime and localtime (and accounting for possible +- // daylight savings time) as an alternative. +- tzoffset = 0L; +-#endif +- +-#ifdef HAVE_TM_ZONE +- tz1 = tim->tm_zone; +- tz2 = ""; +-#elif defined (HAVE_TZNAME) +- tz1 = tzname[0]; +- tz2 = strcmp (tzname[0], tzname[1]) ? tzname[1] : ""; +-#else +- // Some targets have no concept of timezones. +- tz1 = "???"; +- tz2 = tz1; +-#endif +- +- if ((tzoffset % 3600) == 0) +- tzoffset = tzoffset / 3600; +- +- tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6); +- sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2); +- jstring retval = JvNewStringUTF (tzid); +- _Jv_Free (tzid); +- +- return retval; +-} + + extern void _Jv_SetDLLSearchPath (const char *); + +@@ -441,11 +388,6 @@ java::lang::System::init_properties (voi + SET ("user.region", "US"); + } + +- // Set the "user.timezone" property. +- jstring timezone = getDefaultTimeZoneId (); +- if (timezone != NULL) +- newprops->put (JvNewStringLatin1 ("user.timezone"), timezone); +- + // Set some properties according to whatever was compiled in with + // `-D'. + for (int i = 0; _Jv_Compiler_Properties[i]; ++i) +@@ -529,3 +471,146 @@ java::lang::System::init_properties (voi + // synchronized in the common case. + properties = newprops; + } ++ ++/* ++ * This method returns a time zone string that is used by init_properties ++ * to set the default timezone property 'user.timezone'. That value is ++ * used by default as a key into the timezone table used by the ++ * java::util::TimeZone class. ++ */ ++static jstring ++getSystemTimeZone (void) ++{ ++ struct tm *tim; ++ time_t current_time; ++ long tzoffset; ++ const char *tz1, *tz2; ++ char *tzid; ++ ++ current_time = time(0); ++ ++ mktime(tim = localtime(¤t_time)); ++#ifdef STRUCT_TM_HAS_GMTOFF ++ // tm_gmtoff is secs EAST of UTC. ++ tzoffset = -(tim->tm_gmtoff) + tim->tm_isdst * 3600L; ++#elif HAVE_TIMEZONE ++ // timezone is secs WEST of UTC. ++ tzoffset = timezone; ++#else ++ // FIXME: there must be another global if neither tm_gmtoff nor timezone ++ // is available, esp. if tzname is valid. ++ // Richard Earnshaw has suggested using difftime to ++ // calculate between gmtime and localtime (and accounting for possible ++ // daylight savings time) as an alternative. ++ tzoffset = 0L; ++#endif ++ ++#ifdef HAVE_TM_ZONE ++ tz1 = tim->tm_zone; ++ tz2 = ""; ++#elif defined (HAVE_TZNAME) ++ tz1 = tzname[0]; ++ tz2 = strcmp (tzname[0], tzname[1]) ? tzname[1] : ""; ++#else ++ // Some targets have no concept of timezones. ++ tz1 = "???"; ++ tz2 = tz1; ++#endif ++ ++ if ((tzoffset % 3600) == 0) ++ tzoffset = tzoffset / 3600; ++ ++ tzid = (char*) _Jv_Malloc (strlen(tz1) + strlen(tz2) + 6); ++ sprintf(tzid, "%s%ld%s", tz1, tzoffset, tz2); ++ jstring retval = JvNewStringUTF (tzid); ++ _Jv_Free (tzid); ++ ++ return retval; ++} ++ ++// Get the System Timezone as reported by the OS. It should be in ++// the form PST8PDT so we'll need to parse it and check that it's valid. ++// FIXME: Using the code from Classpath for generating the System ++// Timezone IMO is suboptimal because it ignores whether the rules for ++// DST match up. ++jstring ++java::util::TimeZone::getDefaultTimeZoneId () ++{ ++ jstring sysTimeZoneId = getSystemTimeZone (); ++ ++ using namespace java::lang; ++ ++ // Check if this is a valid timezone. Make sure the IDs match ++ // since getTimeZone returns GMT if no match is found. ++ TimeZone *tz = TimeZone::getTimeZone (sysTimeZoneId); ++ if (tz->getID ()->equals (sysTimeZoneId)) ++ return sysTimeZoneId; ++ ++ // Check if the base part of sysTimeZoneId is a valid timezone that ++ // matches with daylight usage and rawOffset. Make sure the IDs match ++ // since getTimeZone returns GMT if no match is found. ++ // First find start of GMT offset info and any Daylight zone name. ++ int startGMToffset = 0; ++ int sysTimeZoneIdLength = sysTimeZoneId->length(); ++ for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++) ++ { ++ if (Character::isDigit (sysTimeZoneId->charAt (i))) ++ startGMToffset = i; ++ } ++ ++ int startDaylightZoneName = 0; ++ jboolean usesDaylight = false; ++ for (int i = sysTimeZoneIdLength - 1; ++ i >= 0 && !Character::isDigit (sysTimeZoneId->charAt (i)); --i) ++ { ++ startDaylightZoneName = i; ++ } ++ if (startDaylightZoneName > 0) ++ usesDaylight = true; ++ ++ int GMToffset ++ = Integer::parseInt (startDaylightZoneName == 0 ? ++ sysTimeZoneId->substring (startGMToffset) : ++ sysTimeZoneId->substring (startGMToffset, ++ startDaylightZoneName)); ++ ++ // Offset could be in hours or seconds. Convert to millis. ++ if (GMToffset < 24) ++ GMToffset *= 60 * 60; ++ GMToffset *= -1000; ++ ++ jstring tzBasename = sysTimeZoneId->substring (0, startGMToffset); ++ tz = TimeZone::getTimeZone (tzBasename); ++ if (tz->getID ()->equals (tzBasename) && tz->getRawOffset () == GMToffset) ++ { ++ jboolean tzUsesDaylight = tz->useDaylightTime (); ++ if (usesDaylight && tzUsesDaylight || !usesDaylight && !tzUsesDaylight) ++ return tzBasename; ++ } ++ ++ // If no match, see if a valid timezone has the same attributes as this ++ // and then use it instead. ++ jstringArray IDs = TimeZone::getAvailableIDs (GMToffset); ++ jstring *elts = elements (IDs); ++ for (int i = 0; i < IDs->length; ++i) ++ { ++ // FIXME: The daylight savings rules may not match the rules ++ // for the desired zone. ++ jboolean IDusesDaylight = ++ TimeZone::getTimeZone (elts[i])->useDaylightTime (); ++ if (usesDaylight && IDusesDaylight || !usesDaylight && !IDusesDaylight) ++ return elts[i]; ++ } ++ ++ // If all else fails, return null. ++ return NULL; ++} ++ ++jstring ++java::util::TimeZone::getTZEnvVar () ++{ ++ const char *tzenv = ::getenv ("TZ"); ++ if (tzenv == NULL) ++ return NULL; ++ return JvNewStringUTF (tzenv); ++} +--- libjava/java/util/TimeZone.java.jj 2007-02-23 21:17:36.000000000 +0100 ++++ libjava/java/util/TimeZone.java 2007-02-24 21:54:41.000000000 +0100 +@@ -1,5 +1,6 @@ + /* java.util.TimeZone +- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. ++ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ++ Free Software Foundation, Inc. + + This file is part of GNU Classpath. + +@@ -37,6 +38,13 @@ exception statement from your version. * + + + package java.util; ++import gnu.java.util.ZoneInfo; ++import java.io.BufferedInputStream; ++import java.io.BufferedReader; ++import java.io.File; ++import java.io.FileInputStream; ++import java.io.InputStreamReader; ++import java.io.IOException; + import java.text.DateFormatSymbols; + + /** +@@ -79,690 +87,1215 @@ public abstract class TimeZone implement + /** + * The default time zone, as returned by getDefault. + */ +- private static TimeZone defaultZone; ++ private static TimeZone defaultZone0; ++ /* initialize this static field lazily to overhead if ++ * it is not needed: ++ */ ++ private static synchronized TimeZone defaultZone() { ++ /* Look up default timezone */ ++ if (defaultZone0 == null) ++ { ++ // System.loadLibrary("javautil"); ++ String tzid = System.getProperty("user.timezone"); ++ ++ if (tzid == null) ++ { ++ tzid = getTZEnvVar(); ++ if (tzid != null && tzid.equals("")) ++ tzid = null; ++ } ++ ++ if (tzid == null) ++ { ++ TimeZone zone = ZoneInfo.readTZFile((String) null, "/etc/localtime"); ++ if (zone != null) ++ { ++ // Try to find a more suitable ID for the /etc/localtime ++ // timezone. ++ // Sometimes /etc/localtime is a symlink to some ++ // /usr/share/zoneinfo/ file. ++ String id = null; ++ try ++ { ++ id = new File("/etc/localtime").getCanonicalPath(); ++ if (id != null) ++ { ++ String zoneinfo_dir ++ = System.getProperty("gnu.java.util.zoneinfo.dir"); ++ if (zoneinfo_dir != null) ++ zoneinfo_dir ++ = new File(zoneinfo_dir ++ + File.separatorChar).getCanonicalPath(); ++ if (zoneinfo_dir != null && id.startsWith(zoneinfo_dir)) ++ { ++ int pos = zoneinfo_dir.length(); ++ while (pos < id.length() ++ && id.charAt(pos) == File.separatorChar) ++ pos++; ++ if (pos < id.length()) ++ id = id.substring(pos); ++ else ++ id = null; ++ } ++ else ++ id = null; ++ } ++ } ++ catch (IOException ioe) ++ { ++ id = null; ++ } ++ ++ if (id == null) ++ id = readSysconfigClockFile("/etc/sysconfig/clock"); ++ ++ if (id != null) ++ zone.setID(id); ++ defaultZone0 = zone; ++ return defaultZone0; ++ } ++ } ++ ++ if (tzid == null) ++ tzid = getDefaultTimeZoneId(); ++ ++ if (tzid == null) ++ tzid = "GMT"; ++ ++ defaultZone0 = getDefaultTimeZone(tzid); ++ } ++ return defaultZone0; ++ } ++ + + private static final long serialVersionUID = 3581463369166924961L; + + /** +- * Hashtable for timezones by ID. ++ * Flag whether zoneinfo data should be used, ++ * otherwise builtin timezone data will be provided. + */ +- private static final Hashtable timezones = new Hashtable(); ++ private static String zoneinfo_dir; + +- static +- { +- TimeZone tz; +- // Automatically generated by scripts/timezones.pl +- // XXX - Should we read this data from a file? +- tz = new SimpleTimeZone(-11000 * 3600, "MIT"); +- timezones.put("MIT", tz); +- timezones.put("Pacific/Apia", tz); +- timezones.put("Pacific/Midway", tz); +- timezones.put("Pacific/Niue", tz); +- timezones.put("Pacific/Pago_Pago", tz); +- tz = new SimpleTimeZone +- (-10000 * 3600, "America/Adak", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("America/Adak", tz); +- tz = new SimpleTimeZone(-10000 * 3600, "HST"); +- timezones.put("HST", tz); +- timezones.put("Pacific/Fakaofo", tz); +- timezones.put("Pacific/Honolulu", tz); +- timezones.put("Pacific/Johnston", tz); +- timezones.put("Pacific/Rarotonga", tz); +- timezones.put("Pacific/Tahiti", tz); +- tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas"); +- timezones.put("Pacific/Marquesas", tz); +- tz = new SimpleTimeZone +- (-9000 * 3600, "AST", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("AST", tz); +- timezones.put("America/Anchorage", tz); +- timezones.put("America/Juneau", tz); +- timezones.put("America/Nome", tz); +- timezones.put("America/Yakutat", tz); +- tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier"); +- timezones.put("Pacific/Gambier", tz); +- tz = new SimpleTimeZone +- (-8000 * 3600, "PST", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("PST", tz); +- timezones.put("PST8PDT", tz); +- timezones.put("America/Dawson", tz); +- timezones.put("America/Los_Angeles", tz); +- timezones.put("America/Tijuana", tz); +- timezones.put("America/Vancouver", tz); +- timezones.put("America/Whitehorse", tz); +- timezones.put("US/Pacific-New", tz); +- tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn"); +- timezones.put("Pacific/Pitcairn", tz); +- tz = new SimpleTimeZone +- (-7000 * 3600, "MST", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("MST", tz); +- timezones.put("MST7MDT", tz); +- timezones.put("America/Boise", tz); +- timezones.put("America/Chihuahua", tz); +- timezones.put("America/Denver", tz); +- timezones.put("America/Edmonton", tz); +- timezones.put("America/Inuvik", tz); +- timezones.put("America/Mazatlan", tz); +- timezones.put("America/Shiprock", tz); +- timezones.put("America/Yellowknife", tz); +- tz = new SimpleTimeZone(-7000 * 3600, "MST7"); +- timezones.put("MST7", tz); +- timezones.put("PNT", tz); +- timezones.put("America/Dawson_Creek", tz); +- timezones.put("America/Hermosillo", tz); +- timezones.put("America/Phoenix", tz); +- tz = new SimpleTimeZone +- (-6000 * 3600, "CST", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("CST", tz); +- timezones.put("CST6CDT", tz); +- timezones.put("America/Cambridge_Bay", tz); +- timezones.put("America/Cancun", tz); +- timezones.put("America/Chicago", tz); +- timezones.put("America/Menominee", tz); +- timezones.put("America/Merida", tz); +- timezones.put("America/Mexico_City", tz); +- timezones.put("America/Monterrey", tz); +- timezones.put("America/Rainy_River", tz); +- timezones.put("America/Winnipeg", tz); +- tz = new SimpleTimeZone(-6000 * 3600, "America/Belize"); +- timezones.put("America/Belize", tz); +- timezones.put("America/Costa_Rica", tz); +- timezones.put("America/El_Salvador", tz); +- timezones.put("America/Guatemala", tz); +- timezones.put("America/Managua", tz); +- timezones.put("America/Regina", tz); +- timezones.put("America/Swift_Current", tz); +- timezones.put("America/Tegucigalpa", tz); +- timezones.put("Pacific/Galapagos", tz); +- tz = new SimpleTimeZone +- (-6000 * 3600, "Pacific/Easter", +- Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600, +- Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600); +- timezones.put("Pacific/Easter", tz); +- tz = new SimpleTimeZone +- (-5000 * 3600, "America/Grand_Turk", +- Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("America/Grand_Turk", tz); +- timezones.put("America/Havana", tz); +- tz = new SimpleTimeZone(-5000 * 3600, "EST5"); +- timezones.put("EST5", tz); +- timezones.put("IET", tz); +- timezones.put("America/Bogota", tz); +- timezones.put("America/Cayman", tz); +- timezones.put("America/Eirunepe", tz); +- timezones.put("America/Guayaquil", tz); +- timezones.put("America/Indiana/Indianapolis", tz); +- timezones.put("America/Indiana/Knox", tz); +- timezones.put("America/Indiana/Marengo", tz); +- timezones.put("America/Indiana/Vevay", tz); +- timezones.put("America/Indianapolis", tz); +- timezones.put("America/Iqaluit", tz); +- timezones.put("America/Jamaica", tz); +- timezones.put("America/Lima", tz); +- timezones.put("America/Panama", tz); +- timezones.put("America/Pangnirtung", tz); +- timezones.put("America/Port-au-Prince", tz); +- timezones.put("America/Porto_Acre", tz); +- timezones.put("America/Rankin_Inlet", tz); +- tz = new SimpleTimeZone +- (-5000 * 3600, "EST", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("EST", tz); +- timezones.put("EST5EDT", tz); +- timezones.put("America/Detroit", tz); +- timezones.put("America/Kentucky/Louisville", tz); +- timezones.put("America/Kentucky/Monticello", tz); +- timezones.put("America/Louisville", tz); +- timezones.put("America/Montreal", tz); +- timezones.put("America/Nassau", tz); +- timezones.put("America/New_York", tz); +- timezones.put("America/Nipigon", tz); +- timezones.put("America/Thunder_Bay", tz); +- tz = new SimpleTimeZone(-4000 * 3600, "PRT"); +- timezones.put("PRT", tz); +- timezones.put("America/Anguilla", tz); +- timezones.put("America/Antigua", tz); +- timezones.put("America/Aruba", tz); +- timezones.put("America/Barbados", tz); +- timezones.put("America/Boa_Vista", tz); +- timezones.put("America/Caracas", tz); +- timezones.put("America/Curacao", tz); +- timezones.put("America/Dominica", tz); +- timezones.put("America/Grenada", tz); +- timezones.put("America/Guadeloupe", tz); +- timezones.put("America/Guyana", tz); +- timezones.put("America/La_Paz", tz); +- timezones.put("America/Manaus", tz); +- timezones.put("America/Martinique", tz); +- timezones.put("America/Montserrat", tz); +- timezones.put("America/Port_of_Spain", tz); +- timezones.put("America/Porto_Velho", tz); +- timezones.put("America/Puerto_Rico", tz); +- timezones.put("America/Santo_Domingo", tz); +- timezones.put("America/St_Kitts", tz); +- timezones.put("America/St_Lucia", tz); +- timezones.put("America/St_Thomas", tz); +- timezones.put("America/St_Vincent", tz); +- timezones.put("America/Tortola", tz); +- tz = new SimpleTimeZone +- (-4000 * 3600, "America/Asuncion", +- Calendar.OCTOBER, 1, Calendar.SUNDAY, 0 * 3600, +- Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("America/Asuncion", tz); +- tz = new SimpleTimeZone +- (-4000 * 3600, "America/Cuiaba", +- Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600, +- Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600); +- timezones.put("America/Cuiaba", tz); +- tz = new SimpleTimeZone +- (-4000 * 3600, "America/Goose_Bay", +- Calendar.APRIL, 1, Calendar.SUNDAY, 60000, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000); +- timezones.put("America/Goose_Bay", tz); +- tz = new SimpleTimeZone +- (-4000 * 3600, "America/Glace_Bay", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("America/Glace_Bay", tz); +- timezones.put("America/Halifax", tz); +- timezones.put("America/Thule", tz); +- timezones.put("Atlantic/Bermuda", tz); +- tz = new SimpleTimeZone +- (-4000 * 3600, "America/Santiago", +- Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600, +- Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600); +- timezones.put("America/Santiago", tz); +- timezones.put("Antarctica/Palmer", tz); +- tz = new SimpleTimeZone +- (-4000 * 3600, "Atlantic/Stanley", +- Calendar.SEPTEMBER, 2, Calendar.SUNDAY, 0 * 3600, +- Calendar.APRIL, 16, -Calendar.SUNDAY, 0 * 3600); +- timezones.put("Atlantic/Stanley", tz); +- tz = new SimpleTimeZone +- (-3500 * 3600, "CNT", +- Calendar.APRIL, 1, Calendar.SUNDAY, 60000, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 60000); +- timezones.put("CNT", tz); +- timezones.put("America/St_Johns", tz); +- tz = new SimpleTimeZone +- (-3000 * 3600, "America/Araguaina", +- Calendar.OCTOBER, 2, Calendar.SUNDAY, 0 * 3600, +- Calendar.FEBRUARY, 3, Calendar.SUNDAY, 0 * 3600); +- timezones.put("America/Araguaina", tz); +- timezones.put("America/Sao_Paulo", tz); +- tz = new SimpleTimeZone(-3000 * 3600, "AGT"); +- timezones.put("AGT", tz); +- timezones.put("America/Belem", tz); +- timezones.put("America/Buenos_Aires", tz); +- timezones.put("America/Catamarca", tz); +- timezones.put("America/Cayenne", tz); +- timezones.put("America/Cordoba", tz); +- timezones.put("America/Fortaleza", tz); +- timezones.put("America/Jujuy", tz); +- timezones.put("America/Maceio", tz); +- timezones.put("America/Mendoza", tz); +- timezones.put("America/Montevideo", tz); +- timezones.put("America/Paramaribo", tz); +- timezones.put("America/Recife", tz); +- timezones.put("America/Rosario", tz); +- tz = new SimpleTimeZone +- (-3000 * 3600, "America/Godthab", +- Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600, +- Calendar.OCTOBER, 30, -Calendar.SATURDAY, 22000 * 3600); +- timezones.put("America/Godthab", tz); +- tz = new SimpleTimeZone +- (-3000 * 3600, "America/Miquelon", +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("America/Miquelon", tz); +- tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha"); +- timezones.put("America/Noronha", tz); +- timezones.put("Atlantic/South_Georgia", tz); +- tz = new SimpleTimeZone +- (-1000 * 3600, "America/Scoresbysund", +- Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("America/Scoresbysund", tz); +- timezones.put("Atlantic/Azores", tz); +- tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde"); +- timezones.put("Atlantic/Cape_Verde", tz); +- timezones.put("Atlantic/Jan_Mayen", tz); +- tz = new SimpleTimeZone(0 * 3600, "GMT"); +- timezones.put("GMT", tz); +- timezones.put("UTC", tz); +- timezones.put("Africa/Abidjan", tz); +- timezones.put("Africa/Accra", tz); +- timezones.put("Africa/Bamako", tz); +- timezones.put("Africa/Banjul", tz); +- timezones.put("Africa/Bissau", tz); +- timezones.put("Africa/Casablanca", tz); +- timezones.put("Africa/Conakry", tz); +- timezones.put("Africa/Dakar", tz); +- timezones.put("Africa/El_Aaiun", tz); +- timezones.put("Africa/Freetown", tz); +- timezones.put("Africa/Lome", tz); +- timezones.put("Africa/Monrovia", tz); +- timezones.put("Africa/Nouakchott", tz); +- timezones.put("Africa/Ouagadougou", tz); +- timezones.put("Africa/Sao_Tome", tz); +- timezones.put("Africa/Timbuktu", tz); +- timezones.put("Atlantic/Reykjavik", tz); +- timezones.put("Atlantic/St_Helena", tz); +- timezones.put("Europe/Belfast", tz); +- timezones.put("Europe/Dublin", tz); +- timezones.put("Europe/London", tz); +- tz = new SimpleTimeZone +- (0 * 3600, "WET", +- Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); +- timezones.put("WET", tz); +- timezones.put("Atlantic/Canary", tz); +- timezones.put("Atlantic/Faeroe", tz); +- timezones.put("Atlantic/Madeira", tz); +- timezones.put("Europe/Lisbon", tz); +- tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers"); +- timezones.put("Africa/Algiers", tz); +- timezones.put("Africa/Bangui", tz); +- timezones.put("Africa/Brazzaville", tz); +- timezones.put("Africa/Douala", tz); +- timezones.put("Africa/Kinshasa", tz); +- timezones.put("Africa/Lagos", tz); +- timezones.put("Africa/Libreville", tz); +- timezones.put("Africa/Luanda", tz); +- timezones.put("Africa/Malabo", tz); +- timezones.put("Africa/Ndjamena", tz); +- timezones.put("Africa/Niamey", tz); +- timezones.put("Africa/Porto-Novo", tz); +- timezones.put("Africa/Tunis", tz); +- tz = new SimpleTimeZone +- (1000 * 3600, "Africa/Windhoek", +- Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Africa/Windhoek", tz); +- tz = new SimpleTimeZone +- (1000 * 3600, "CET", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("CET", tz); +- timezones.put("ECT", tz); +- timezones.put("MET", tz); +- timezones.put("Africa/Ceuta", tz); +- timezones.put("Arctic/Longyearbyen", tz); +- timezones.put("Europe/Amsterdam", tz); +- timezones.put("Europe/Andorra", tz); +- timezones.put("Europe/Belgrade", tz); +- timezones.put("Europe/Berlin", tz); +- timezones.put("Europe/Bratislava", tz); +- timezones.put("Europe/Brussels", tz); +- timezones.put("Europe/Budapest", tz); +- timezones.put("Europe/Copenhagen", tz); +- timezones.put("Europe/Gibraltar", tz); +- timezones.put("Europe/Ljubljana", tz); +- timezones.put("Europe/Luxembourg", tz); +- timezones.put("Europe/Madrid", tz); +- timezones.put("Europe/Malta", tz); +- timezones.put("Europe/Monaco", tz); +- timezones.put("Europe/Oslo", tz); +- timezones.put("Europe/Paris", tz); +- timezones.put("Europe/Prague", tz); +- timezones.put("Europe/Rome", tz); +- timezones.put("Europe/San_Marino", tz); +- timezones.put("Europe/Sarajevo", tz); +- timezones.put("Europe/Skopje", tz); +- timezones.put("Europe/Stockholm", tz); +- timezones.put("Europe/Tirane", tz); +- timezones.put("Europe/Vaduz", tz); +- timezones.put("Europe/Vatican", tz); +- timezones.put("Europe/Vienna", tz); +- timezones.put("Europe/Warsaw", tz); +- timezones.put("Europe/Zagreb", tz); +- timezones.put("Europe/Zurich", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "ART", +- Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600, +- Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 23000 * 3600); +- timezones.put("ART", tz); +- timezones.put("Africa/Cairo", tz); +- tz = new SimpleTimeZone(2000 * 3600, "CAT"); +- timezones.put("CAT", tz); +- timezones.put("Africa/Blantyre", tz); +- timezones.put("Africa/Bujumbura", tz); +- timezones.put("Africa/Gaborone", tz); +- timezones.put("Africa/Harare", tz); +- timezones.put("Africa/Johannesburg", tz); +- timezones.put("Africa/Kigali", tz); +- timezones.put("Africa/Lubumbashi", tz); +- timezones.put("Africa/Lusaka", tz); +- timezones.put("Africa/Maputo", tz); +- timezones.put("Africa/Maseru", tz); +- timezones.put("Africa/Mbabane", tz); +- timezones.put("Africa/Tripoli", tz); +- timezones.put("Europe/Riga", tz); +- timezones.put("Europe/Tallinn", tz); +- timezones.put("Europe/Vilnius", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "Asia/Amman", +- Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600, +- Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 0 * 3600); +- timezones.put("Asia/Amman", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "Asia/Beirut", +- Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("Asia/Beirut", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "Asia/Damascus", +- Calendar.APRIL, 1, 0, 0 * 3600, +- Calendar.OCTOBER, 1, 0, 0 * 3600); +- timezones.put("Asia/Damascus", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "Asia/Gaza", +- Calendar.APRIL, 3, Calendar.FRIDAY, 0 * 3600, +- Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600); +- timezones.put("Asia/Gaza", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "Asia/Jerusalem", +- Calendar.APRIL, 1, 0, 1000 * 3600, +- Calendar.OCTOBER, 1, 0, 1000 * 3600); +- timezones.put("Asia/Jerusalem", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "EET", +- Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); +- timezones.put("EET", tz); +- timezones.put("Asia/Istanbul", tz); +- timezones.put("Asia/Nicosia", tz); +- timezones.put("Europe/Athens", tz); +- timezones.put("Europe/Bucharest", tz); +- timezones.put("Europe/Chisinau", tz); +- timezones.put("Europe/Helsinki", tz); +- timezones.put("Europe/Istanbul", tz); +- timezones.put("Europe/Kiev", tz); +- timezones.put("Europe/Nicosia", tz); +- timezones.put("Europe/Simferopol", tz); +- timezones.put("Europe/Sofia", tz); +- timezones.put("Europe/Uzhgorod", tz); +- timezones.put("Europe/Zaporozhye", tz); +- tz = new SimpleTimeZone +- (2000 * 3600, "Europe/Kaliningrad", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Europe/Kaliningrad", tz); +- timezones.put("Europe/Minsk", tz); +- tz = new SimpleTimeZone +- (3000 * 3600, "Asia/Baghdad", +- Calendar.APRIL, 1, 0, 3000 * 3600, +- Calendar.OCTOBER, 1, 0, 3000 * 3600); +- timezones.put("Asia/Baghdad", tz); +- tz = new SimpleTimeZone +- (3000 * 3600, "Europe/Moscow", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Europe/Moscow", tz); +- timezones.put("Europe/Tiraspol", tz); +- tz = new SimpleTimeZone(3000 * 3600, "EAT"); +- timezones.put("EAT", tz); +- timezones.put("Africa/Addis_Ababa", tz); +- timezones.put("Africa/Asmera", tz); +- timezones.put("Africa/Dar_es_Salaam", tz); +- timezones.put("Africa/Djibouti", tz); +- timezones.put("Africa/Kampala", tz); +- timezones.put("Africa/Khartoum", tz); +- timezones.put("Africa/Mogadishu", tz); +- timezones.put("Africa/Nairobi", tz); +- timezones.put("Antarctica/Syowa", tz); +- timezones.put("Asia/Aden", tz); +- timezones.put("Asia/Bahrain", tz); +- timezones.put("Asia/Kuwait", tz); +- timezones.put("Asia/Qatar", tz); +- timezones.put("Asia/Riyadh", tz); +- timezones.put("Indian/Antananarivo", tz); +- timezones.put("Indian/Comoro", tz); +- timezones.put("Indian/Mayotte", tz); +- tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran"); +- timezones.put("Asia/Tehran", tz); +- tz = new SimpleTimeZone +- (4000 * 3600, "Asia/Baku", +- Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); +- timezones.put("Asia/Baku", tz); +- tz = new SimpleTimeZone +- (4000 * 3600, "Asia/Aqtau", +- Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("Asia/Aqtau", tz); +- timezones.put("Asia/Tbilisi", tz); +- tz = new SimpleTimeZone +- (4000 * 3600, "Asia/Yerevan", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Yerevan", tz); +- timezones.put("Europe/Samara", tz); +- tz = new SimpleTimeZone(4000 * 3600, "NET"); +- timezones.put("NET", tz); +- timezones.put("Asia/Dubai", tz); +- timezones.put("Asia/Muscat", tz); +- timezones.put("Indian/Mahe", tz); +- timezones.put("Indian/Mauritius", tz); +- timezones.put("Indian/Reunion", tz); +- tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul"); +- timezones.put("Asia/Kabul", tz); +- tz = new SimpleTimeZone +- (5000 * 3600, "Asia/Aqtobe", +- Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("Asia/Aqtobe", tz); +- tz = new SimpleTimeZone +- (5000 * 3600, "Asia/Bishkek", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2500 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2500 * 3600); +- timezones.put("Asia/Bishkek", tz); +- tz = new SimpleTimeZone +- (5000 * 3600, "Asia/Yekaterinburg", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Yekaterinburg", tz); +- tz = new SimpleTimeZone(5000 * 3600, "PLT"); +- timezones.put("PLT", tz); +- timezones.put("Asia/Ashgabat", tz); +- timezones.put("Asia/Dushanbe", tz); +- timezones.put("Asia/Karachi", tz); +- timezones.put("Asia/Samarkand", tz); +- timezones.put("Asia/Tashkent", tz); +- timezones.put("Indian/Chagos", tz); +- timezones.put("Indian/Kerguelen", tz); +- timezones.put("Indian/Maldives", tz); +- tz = new SimpleTimeZone(5500 * 3600, "IST"); +- timezones.put("IST", tz); +- timezones.put("Asia/Calcutta", tz); +- tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu"); +- timezones.put("Asia/Katmandu", tz); +- tz = new SimpleTimeZone(6000 * 3600, "BST"); +- timezones.put("BST", tz); +- timezones.put("Antarctica/Mawson", tz); +- timezones.put("Asia/Colombo", tz); +- timezones.put("Asia/Dhaka", tz); +- timezones.put("Asia/Thimphu", tz); +- tz = new SimpleTimeZone +- (6000 * 3600, "Asia/Almaty", +- Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); +- timezones.put("Asia/Almaty", tz); +- tz = new SimpleTimeZone +- (6000 * 3600, "Asia/Novosibirsk", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Novosibirsk", tz); +- timezones.put("Asia/Omsk", tz); +- tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon"); +- timezones.put("Asia/Rangoon", tz); +- timezones.put("Indian/Cocos", tz); +- tz = new SimpleTimeZone(7000 * 3600, "VST"); +- timezones.put("VST", tz); +- timezones.put("Antarctica/Davis", tz); +- timezones.put("Asia/Bangkok", tz); +- timezones.put("Asia/Hovd", tz); +- timezones.put("Asia/Jakarta", tz); +- timezones.put("Asia/Phnom_Penh", tz); +- timezones.put("Asia/Saigon", tz); +- timezones.put("Asia/Vientiane", tz); +- timezones.put("Indian/Christmas", tz); +- tz = new SimpleTimeZone +- (7000 * 3600, "Asia/Krasnoyarsk", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Krasnoyarsk", tz); +- tz = new SimpleTimeZone(8000 * 3600, "CTT"); +- timezones.put("CTT", tz); +- timezones.put("Antarctica/Casey", tz); +- timezones.put("Asia/Brunei", tz); +- timezones.put("Asia/Chungking", tz); +- timezones.put("Asia/Harbin", tz); +- timezones.put("Asia/Hong_Kong", tz); +- timezones.put("Asia/Kashgar", tz); +- timezones.put("Asia/Kuala_Lumpur", tz); +- timezones.put("Asia/Kuching", tz); +- timezones.put("Asia/Macao", tz); +- timezones.put("Asia/Manila", tz); +- timezones.put("Asia/Shanghai", tz); +- timezones.put("Asia/Singapore", tz); +- timezones.put("Asia/Taipei", tz); +- timezones.put("Asia/Ujung_Pandang", tz); +- timezones.put("Asia/Ulaanbaatar", tz); +- timezones.put("Asia/Urumqi", tz); +- timezones.put("Australia/Perth", tz); +- tz = new SimpleTimeZone +- (8000 * 3600, "Asia/Irkutsk", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Irkutsk", tz); +- tz = new SimpleTimeZone(9000 * 3600, "JST"); +- timezones.put("JST", tz); +- timezones.put("Asia/Dili", tz); +- timezones.put("Asia/Jayapura", tz); +- timezones.put("Asia/Pyongyang", tz); +- timezones.put("Asia/Seoul", tz); +- timezones.put("Asia/Tokyo", tz); +- timezones.put("Pacific/Palau", tz); +- tz = new SimpleTimeZone +- (9000 * 3600, "Asia/Yakutsk", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Yakutsk", tz); +- tz = new SimpleTimeZone +- (9500 * 3600, "Australia/Adelaide", +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Australia/Adelaide", tz); +- timezones.put("Australia/Broken_Hill", tz); +- tz = new SimpleTimeZone(9500 * 3600, "ACT"); +- timezones.put("ACT", tz); +- timezones.put("Australia/Darwin", tz); +- tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville"); +- timezones.put("Antarctica/DumontDUrville", tz); +- timezones.put("Australia/Brisbane", tz); +- timezones.put("Australia/Lindeman", tz); +- timezones.put("Pacific/Guam", tz); +- timezones.put("Pacific/Port_Moresby", tz); +- timezones.put("Pacific/Saipan", tz); +- timezones.put("Pacific/Truk", tz); +- timezones.put("Pacific/Yap", tz); +- tz = new SimpleTimeZone +- (10000 * 3600, "Asia/Vladivostok", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Vladivostok", tz); +- tz = new SimpleTimeZone +- (10000 * 3600, "Australia/Hobart", +- Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Australia/Hobart", tz); +- tz = new SimpleTimeZone +- (10000 * 3600, "AET", +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("AET", tz); +- timezones.put("Australia/Melbourne", tz); +- timezones.put("Australia/Sydney", tz); +- tz = new SimpleTimeZone +- (10500 * 3600, "Australia/Lord_Howe", +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600); +- timezones.put("Australia/Lord_Howe", tz); +- tz = new SimpleTimeZone +- (11000 * 3600, "Asia/Magadan", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Magadan", tz); +- tz = new SimpleTimeZone(11000 * 3600, "SST"); +- timezones.put("SST", tz); +- timezones.put("Pacific/Efate", tz); +- timezones.put("Pacific/Guadalcanal", tz); +- timezones.put("Pacific/Kosrae", tz); +- timezones.put("Pacific/Noumea", tz); +- timezones.put("Pacific/Ponape", tz); +- tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk"); +- timezones.put("Pacific/Norfolk", tz); +- tz = new SimpleTimeZone +- (12000 * 3600, "NST", +- Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.MARCH, 3, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("NST", tz); +- timezones.put("Antarctica/McMurdo", tz); +- timezones.put("Antarctica/South_Pole", tz); +- timezones.put("Pacific/Auckland", tz); +- tz = new SimpleTimeZone +- (12000 * 3600, "Asia/Anadyr", +- Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, +- Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); +- timezones.put("Asia/Anadyr", tz); +- timezones.put("Asia/Kamchatka", tz); +- tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji"); +- timezones.put("Pacific/Fiji", tz); +- timezones.put("Pacific/Funafuti", tz); +- timezones.put("Pacific/Kwajalein", tz); +- timezones.put("Pacific/Majuro", tz); +- timezones.put("Pacific/Nauru", tz); +- timezones.put("Pacific/Tarawa", tz); +- timezones.put("Pacific/Wake", tz); +- timezones.put("Pacific/Wallis", tz); +- tz = new SimpleTimeZone +- (12750 * 3600, "Pacific/Chatham", +- Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600, +- Calendar.MARCH, 3, Calendar.SUNDAY, 2750 * 3600); +- timezones.put("Pacific/Chatham", tz); +- tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury"); +- timezones.put("Pacific/Enderbury", tz); +- timezones.put("Pacific/Tongatapu", tz); +- tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati"); +- timezones.put("Pacific/Kiritimati", tz); ++ /** ++ * Cached copy of getAvailableIDs(). ++ */ ++ private static String[] availableIDs = null; ++ ++ /** ++ * JDK 1.1.x compatibility aliases. ++ */ ++ private static Hashtable aliases0; ++ ++ /** ++ * Hashtable for timezones by ID. ++ */ ++ private static Hashtable timezones0; ++ /* initialize this static field lazily to overhead if ++ * it is not needed: ++ */ ++ private static Hashtable timezones() { ++ if (timezones0==null) ++ { ++ Hashtable timezones = new Hashtable(); ++ timezones0 = timezones; ++ ++ zoneinfo_dir = System.getProperty("gnu.java.util.zoneinfo.dir"); ++ if (zoneinfo_dir != null && !new File(zoneinfo_dir).isDirectory()) ++ zoneinfo_dir = null; ++ ++ if (zoneinfo_dir != null) ++ { ++ aliases0 = new Hashtable(); ++ ++ // These deprecated aliases for JDK 1.1.x compatibility ++ // should take precedence over data files read from ++ // /usr/share/zoneinfo. ++ aliases0.put("ACT", "Australia/Darwin"); ++ aliases0.put("AET", "Australia/Sydney"); ++ aliases0.put("AGT", "America/Argentina/Buenos_Aires"); ++ aliases0.put("ART", "Africa/Cairo"); ++ aliases0.put("AST", "America/Juneau"); ++ aliases0.put("BST", "Asia/Colombo"); ++ aliases0.put("CAT", "Africa/Gaborone"); ++ aliases0.put("CNT", "America/St_Johns"); ++ aliases0.put("CST", "CST6CDT"); ++ aliases0.put("CTT", "Asia/Brunei"); ++ aliases0.put("EAT", "Indian/Comoro"); ++ aliases0.put("ECT", "CET"); ++ aliases0.put("EST", "EST5EDT"); ++ aliases0.put("EST5", "EST5EDT"); ++ aliases0.put("IET", "EST5EDT"); ++ aliases0.put("IST", "Asia/Calcutta"); ++ aliases0.put("JST", "Asia/Seoul"); ++ aliases0.put("MIT", "Pacific/Niue"); ++ aliases0.put("MST", "MST7MDT"); ++ aliases0.put("MST7", "MST7MDT"); ++ aliases0.put("NET", "Indian/Mauritius"); ++ aliases0.put("NST", "Pacific/Auckland"); ++ aliases0.put("PLT", "Indian/Kerguelen"); ++ aliases0.put("PNT", "MST7MDT"); ++ aliases0.put("PRT", "America/Anguilla"); ++ aliases0.put("PST", "PST8PDT"); ++ aliases0.put("SST", "Pacific/Ponape"); ++ aliases0.put("VST", "Asia/Bangkok"); ++ return timezones; ++ } ++ ++ TimeZone tz; ++ // Automatically generated by scripts/timezones.pl ++ // XXX - Should we read this data from a file? ++ tz = new SimpleTimeZone(-11000 * 3600, "MIT"); ++ timezones0.put("MIT", tz); ++ timezones0.put("Pacific/Apia", tz); ++ timezones0.put("Pacific/Midway", tz); ++ timezones0.put("Pacific/Niue", tz); ++ timezones0.put("Pacific/Pago_Pago", tz); ++ tz = new SimpleTimeZone ++ (-10000 * 3600, "America/Adak", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Adak", tz); ++ tz = new SimpleTimeZone(-10000 * 3600, "HST"); ++ timezones0.put("HST", tz); ++ timezones0.put("Pacific/Fakaofo", tz); ++ timezones0.put("Pacific/Honolulu", tz); ++ timezones0.put("Pacific/Johnston", tz); ++ timezones0.put("Pacific/Rarotonga", tz); ++ timezones0.put("Pacific/Tahiti", tz); ++ tz = new SimpleTimeZone(-9500 * 3600, "Pacific/Marquesas"); ++ timezones0.put("Pacific/Marquesas", tz); ++ tz = new SimpleTimeZone ++ (-9000 * 3600, "AST", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("AST", tz); ++ timezones0.put("America/Anchorage", tz); ++ timezones0.put("America/Juneau", tz); ++ timezones0.put("America/Nome", tz); ++ timezones0.put("America/Yakutat", tz); ++ tz = new SimpleTimeZone(-9000 * 3600, "Pacific/Gambier"); ++ timezones0.put("Pacific/Gambier", tz); ++ tz = new SimpleTimeZone ++ (-8000 * 3600, "America/Tijuana", ++ Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Tijuana", tz); ++ tz = new SimpleTimeZone ++ (-8000 * 3600, "PST", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("PST", tz); ++ timezones0.put("PST8PDT", tz); ++ timezones0.put("America/Dawson", tz); ++ timezones0.put("America/Los_Angeles", tz); ++ timezones0.put("America/Vancouver", tz); ++ timezones0.put("America/Whitehorse", tz); ++ timezones0.put("US/Pacific-New", tz); ++ tz = new SimpleTimeZone(-8000 * 3600, "Pacific/Pitcairn"); ++ timezones0.put("Pacific/Pitcairn", tz); ++ tz = new SimpleTimeZone ++ (-7000 * 3600, "America/Chihuahua", ++ Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Chihuahua", tz); ++ timezones0.put("America/Mazatlan", tz); ++ tz = new SimpleTimeZone(-7000 * 3600, "MST7"); ++ timezones0.put("MST7", tz); ++ timezones0.put("PNT", tz); ++ timezones0.put("America/Dawson_Creek", tz); ++ timezones0.put("America/Hermosillo", tz); ++ timezones0.put("America/Phoenix", tz); ++ tz = new SimpleTimeZone ++ (-7000 * 3600, "MST", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("MST", tz); ++ timezones0.put("MST7MDT", tz); ++ timezones0.put("America/Boise", tz); ++ timezones0.put("America/Cambridge_Bay", tz); ++ timezones0.put("America/Denver", tz); ++ timezones0.put("America/Edmonton", tz); ++ timezones0.put("America/Inuvik", tz); ++ timezones0.put("America/Shiprock", tz); ++ timezones0.put("America/Yellowknife", tz); ++ tz = new SimpleTimeZone ++ (-6000 * 3600, "America/Cancun", ++ Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Cancun", tz); ++ timezones0.put("America/Merida", tz); ++ timezones0.put("America/Mexico_City", tz); ++ timezones0.put("America/Monterrey", tz); ++ tz = new SimpleTimeZone(-6000 * 3600, "America/Belize"); ++ timezones0.put("America/Belize", tz); ++ timezones0.put("America/Costa_Rica", tz); ++ timezones0.put("America/El_Salvador", tz); ++ timezones0.put("America/Guatemala", tz); ++ timezones0.put("America/Managua", tz); ++ timezones0.put("America/Regina", tz); ++ timezones0.put("America/Swift_Current", tz); ++ timezones0.put("America/Tegucigalpa", tz); ++ timezones0.put("Pacific/Galapagos", tz); ++ tz = new SimpleTimeZone ++ (-6000 * 3600, "CST", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("CST", tz); ++ timezones0.put("CST6CDT", tz); ++ timezones0.put("America/Chicago", tz); ++ timezones0.put("America/Indiana/Knox", tz); ++ timezones0.put("America/Indiana/Petersburg", tz); ++ timezones0.put("America/Indiana/Vincennes", tz); ++ timezones0.put("America/Menominee", tz); ++ timezones0.put("America/North_Dakota/Center", tz); ++ timezones0.put("America/North_Dakota/New_Salem", tz); ++ timezones0.put("America/Rainy_River", tz); ++ timezones0.put("America/Rankin_Inlet", tz); ++ timezones0.put("America/Winnipeg", tz); ++ tz = new SimpleTimeZone ++ (-6000 * 3600, "Pacific/Easter", ++ Calendar.OCTOBER, 2, Calendar.SATURDAY, 22000 * 3600, ++ Calendar.MARCH, 2, Calendar.SATURDAY, 22000 * 3600); ++ timezones0.put("Pacific/Easter", tz); ++ tz = new SimpleTimeZone(-5000 * 3600, "EST5"); ++ timezones0.put("EST5", tz); ++ timezones0.put("IET", tz); ++ timezones0.put("America/Atikokan", tz); ++ timezones0.put("America/Bogota", tz); ++ timezones0.put("America/Cayman", tz); ++ timezones0.put("America/Eirunepe", tz); ++ timezones0.put("America/Guayaquil", tz); ++ timezones0.put("America/Jamaica", tz); ++ timezones0.put("America/Lima", tz); ++ timezones0.put("America/Panama", tz); ++ timezones0.put("America/Rio_Branco", tz); ++ tz = new SimpleTimeZone ++ (-5000 * 3600, "America/Havana", ++ Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); ++ timezones0.put("America/Havana", tz); ++ tz = new SimpleTimeZone ++ (-5000 * 3600, "America/Grand_Turk", ++ Calendar.APRIL, 1, Calendar.SUNDAY, 0 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); ++ timezones0.put("America/Grand_Turk", tz); ++ timezones0.put("America/Port-au-Prince", tz); ++ tz = new SimpleTimeZone ++ (-5000 * 3600, "EST", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("EST", tz); ++ timezones0.put("EST5EDT", tz); ++ timezones0.put("America/Detroit", tz); ++ timezones0.put("America/Indiana/Indianapolis", tz); ++ timezones0.put("America/Indiana/Marengo", tz); ++ timezones0.put("America/Indiana/Vevay", tz); ++ timezones0.put("America/Iqaluit", tz); ++ timezones0.put("America/Kentucky/Louisville", tz); ++ timezones0.put("America/Kentucky/Monticello", tz); ++ timezones0.put("America/Montreal", tz); ++ timezones0.put("America/Nassau", tz); ++ timezones0.put("America/New_York", tz); ++ timezones0.put("America/Nipigon", tz); ++ timezones0.put("America/Pangnirtung", tz); ++ timezones0.put("America/Thunder_Bay", tz); ++ timezones0.put("America/Toronto", tz); ++ tz = new SimpleTimeZone ++ (-4000 * 3600, "America/Asuncion", ++ Calendar.OCTOBER, 3, Calendar.SUNDAY, 0 * 3600, ++ Calendar.MARCH, 2, Calendar.SUNDAY, 0 * 3600); ++ timezones0.put("America/Asuncion", tz); ++ tz = new SimpleTimeZone(-4000 * 3600, "PRT"); ++ timezones0.put("PRT", tz); ++ timezones0.put("America/Anguilla", tz); ++ timezones0.put("America/Antigua", tz); ++ timezones0.put("America/Aruba", tz); ++ timezones0.put("America/Barbados", tz); ++ timezones0.put("America/Blanc-Sablon", tz); ++ timezones0.put("America/Boa_Vista", tz); ++ timezones0.put("America/Caracas", tz); ++ timezones0.put("America/Curacao", tz); ++ timezones0.put("America/Dominica", tz); ++ timezones0.put("America/Grenada", tz); ++ timezones0.put("America/Guadeloupe", tz); ++ timezones0.put("America/Guyana", tz); ++ timezones0.put("America/La_Paz", tz); ++ timezones0.put("America/Manaus", tz); ++ timezones0.put("America/Martinique", tz); ++ timezones0.put("America/Montserrat", tz); ++ timezones0.put("America/Port_of_Spain", tz); ++ timezones0.put("America/Porto_Velho", tz); ++ timezones0.put("America/Puerto_Rico", tz); ++ timezones0.put("America/Santo_Domingo", tz); ++ timezones0.put("America/St_Kitts", tz); ++ timezones0.put("America/St_Lucia", tz); ++ timezones0.put("America/St_Thomas", tz); ++ timezones0.put("America/St_Vincent", tz); ++ timezones0.put("America/Tortola", tz); ++ tz = new SimpleTimeZone ++ (-4000 * 3600, "America/Campo_Grande", ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600, ++ Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); ++ timezones0.put("America/Campo_Grande", tz); ++ timezones0.put("America/Cuiaba", tz); ++ tz = new SimpleTimeZone ++ (-4000 * 3600, "America/Goose_Bay", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 60000, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000); ++ timezones0.put("America/Goose_Bay", tz); ++ tz = new SimpleTimeZone ++ (-4000 * 3600, "America/Glace_Bay", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Glace_Bay", tz); ++ timezones0.put("America/Halifax", tz); ++ timezones0.put("America/Moncton", tz); ++ timezones0.put("America/Thule", tz); ++ timezones0.put("Atlantic/Bermuda", tz); ++ tz = new SimpleTimeZone ++ (-4000 * 3600, "America/Santiago", ++ Calendar.OCTOBER, 9, -Calendar.SUNDAY, 0 * 3600, ++ Calendar.MARCH, 9, -Calendar.SUNDAY, 0 * 3600); ++ timezones0.put("America/Santiago", tz); ++ timezones0.put("Antarctica/Palmer", tz); ++ tz = new SimpleTimeZone ++ (-4000 * 3600, "Atlantic/Stanley", ++ Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.APRIL, 3, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("Atlantic/Stanley", tz); ++ tz = new SimpleTimeZone ++ (-3500 * 3600, "CNT", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 60000, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 60000); ++ timezones0.put("CNT", tz); ++ timezones0.put("America/St_Johns", tz); ++ tz = new SimpleTimeZone ++ (-3000 * 3600, "America/Godthab", ++ Calendar.MARCH, 30, -Calendar.SATURDAY, 22000 * 3600, ++ Calendar.OCTOBER, 30, -Calendar.SATURDAY, 23000 * 3600); ++ timezones0.put("America/Godthab", tz); ++ tz = new SimpleTimeZone ++ (-3000 * 3600, "America/Miquelon", ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Miquelon", tz); ++ tz = new SimpleTimeZone ++ (-3000 * 3600, "America/Montevideo", ++ Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.MARCH, 2, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("America/Montevideo", tz); ++ tz = new SimpleTimeZone ++ (-3000 * 3600, "America/Sao_Paulo", ++ Calendar.NOVEMBER, 1, Calendar.SUNDAY, 0 * 3600, ++ Calendar.FEBRUARY, -1, Calendar.SUNDAY, 0 * 3600); ++ timezones0.put("America/Sao_Paulo", tz); ++ tz = new SimpleTimeZone(-3000 * 3600, "AGT"); ++ timezones0.put("AGT", tz); ++ timezones0.put("America/Araguaina", tz); ++ timezones0.put("America/Argentina/Buenos_Aires", tz); ++ timezones0.put("America/Argentina/Catamarca", tz); ++ timezones0.put("America/Argentina/Cordoba", tz); ++ timezones0.put("America/Argentina/Jujuy", tz); ++ timezones0.put("America/Argentina/La_Rioja", tz); ++ timezones0.put("America/Argentina/Mendoza", tz); ++ timezones0.put("America/Argentina/Rio_Gallegos", tz); ++ timezones0.put("America/Argentina/San_Juan", tz); ++ timezones0.put("America/Argentina/Tucuman", tz); ++ timezones0.put("America/Argentina/Ushuaia", tz); ++ timezones0.put("America/Bahia", tz); ++ timezones0.put("America/Belem", tz); ++ timezones0.put("America/Cayenne", tz); ++ timezones0.put("America/Fortaleza", tz); ++ timezones0.put("America/Maceio", tz); ++ timezones0.put("America/Paramaribo", tz); ++ timezones0.put("America/Recife", tz); ++ timezones0.put("Antarctica/Rothera", tz); ++ tz = new SimpleTimeZone(-2000 * 3600, "America/Noronha"); ++ timezones0.put("America/Noronha", tz); ++ timezones0.put("Atlantic/South_Georgia", tz); ++ tz = new SimpleTimeZone ++ (-1000 * 3600, "America/Scoresbysund", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 1000 * 3600); ++ timezones0.put("America/Scoresbysund", tz); ++ timezones0.put("Atlantic/Azores", tz); ++ tz = new SimpleTimeZone(-1000 * 3600, "Atlantic/Cape_Verde"); ++ timezones0.put("Atlantic/Cape_Verde", tz); ++ tz = new SimpleTimeZone(0 * 3600, "GMT"); ++ timezones0.put("GMT", tz); ++ timezones0.put("UTC", tz); ++ timezones0.put("Africa/Abidjan", tz); ++ timezones0.put("Africa/Accra", tz); ++ timezones0.put("Africa/Bamako", tz); ++ timezones0.put("Africa/Banjul", tz); ++ timezones0.put("Africa/Bissau", tz); ++ timezones0.put("Africa/Casablanca", tz); ++ timezones0.put("Africa/Conakry", tz); ++ timezones0.put("Africa/Dakar", tz); ++ timezones0.put("Africa/El_Aaiun", tz); ++ timezones0.put("Africa/Freetown", tz); ++ timezones0.put("Africa/Lome", tz); ++ timezones0.put("Africa/Monrovia", tz); ++ timezones0.put("Africa/Nouakchott", tz); ++ timezones0.put("Africa/Ouagadougou", tz); ++ timezones0.put("Africa/Sao_Tome", tz); ++ timezones0.put("America/Danmarkshavn", tz); ++ timezones0.put("Atlantic/Reykjavik", tz); ++ timezones0.put("Atlantic/St_Helena", tz); ++ tz = new SimpleTimeZone ++ (0 * 3600, "WET", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 1000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("WET", tz); ++ timezones0.put("Atlantic/Canary", tz); ++ timezones0.put("Atlantic/Faroe", tz); ++ timezones0.put("Atlantic/Madeira", tz); ++ timezones0.put("Europe/Dublin", tz); ++ timezones0.put("Europe/Guernsey", tz); ++ timezones0.put("Europe/Isle_of_Man", tz); ++ timezones0.put("Europe/Jersey", tz); ++ timezones0.put("Europe/Lisbon", tz); ++ timezones0.put("Europe/London", tz); ++ tz = new SimpleTimeZone(1000 * 3600, "Africa/Algiers"); ++ timezones0.put("Africa/Algiers", tz); ++ timezones0.put("Africa/Bangui", tz); ++ timezones0.put("Africa/Brazzaville", tz); ++ timezones0.put("Africa/Douala", tz); ++ timezones0.put("Africa/Kinshasa", tz); ++ timezones0.put("Africa/Lagos", tz); ++ timezones0.put("Africa/Libreville", tz); ++ timezones0.put("Africa/Luanda", tz); ++ timezones0.put("Africa/Malabo", tz); ++ timezones0.put("Africa/Ndjamena", tz); ++ timezones0.put("Africa/Niamey", tz); ++ timezones0.put("Africa/Porto-Novo", tz); ++ tz = new SimpleTimeZone ++ (1000 * 3600, "Africa/Windhoek", ++ Calendar.SEPTEMBER, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.APRIL, 1, Calendar.SUNDAY, 2000 * 3600); ++ timezones0.put("Africa/Windhoek", tz); ++ tz = new SimpleTimeZone ++ (1000 * 3600, "CET", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("CET", tz); ++ timezones0.put("ECT", tz); ++ timezones0.put("MET", tz); ++ timezones0.put("Africa/Ceuta", tz); ++ timezones0.put("Africa/Tunis", tz); ++ timezones0.put("Arctic/Longyearbyen", tz); ++ timezones0.put("Atlantic/Jan_Mayen", tz); ++ timezones0.put("Europe/Amsterdam", tz); ++ timezones0.put("Europe/Andorra", tz); ++ timezones0.put("Europe/Belgrade", tz); ++ timezones0.put("Europe/Berlin", tz); ++ timezones0.put("Europe/Bratislava", tz); ++ timezones0.put("Europe/Brussels", tz); ++ timezones0.put("Europe/Budapest", tz); ++ timezones0.put("Europe/Copenhagen", tz); ++ timezones0.put("Europe/Gibraltar", tz); ++ timezones0.put("Europe/Ljubljana", tz); ++ timezones0.put("Europe/Luxembourg", tz); ++ timezones0.put("Europe/Madrid", tz); ++ timezones0.put("Europe/Malta", tz); ++ timezones0.put("Europe/Monaco", tz); ++ timezones0.put("Europe/Oslo", tz); ++ timezones0.put("Europe/Paris", tz); ++ timezones0.put("Europe/Podgorica", tz); ++ timezones0.put("Europe/Prague", tz); ++ timezones0.put("Europe/Rome", tz); ++ timezones0.put("Europe/San_Marino", tz); ++ timezones0.put("Europe/Sarajevo", tz); ++ timezones0.put("Europe/Skopje", tz); ++ timezones0.put("Europe/Stockholm", tz); ++ timezones0.put("Europe/Tirane", tz); ++ timezones0.put("Europe/Vaduz", tz); ++ timezones0.put("Europe/Vatican", tz); ++ timezones0.put("Europe/Vienna", tz); ++ timezones0.put("Europe/Warsaw", tz); ++ timezones0.put("Europe/Zagreb", tz); ++ timezones0.put("Europe/Zurich", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "ART", ++ Calendar.APRIL, -1, Calendar.FRIDAY, 0 * 3600, ++ Calendar.SEPTEMBER, -1, Calendar.THURSDAY, 24000 * 3600); ++ timezones0.put("ART", tz); ++ timezones0.put("Africa/Cairo", tz); ++ tz = new SimpleTimeZone(2000 * 3600, "CAT"); ++ timezones0.put("CAT", tz); ++ timezones0.put("Africa/Blantyre", tz); ++ timezones0.put("Africa/Bujumbura", tz); ++ timezones0.put("Africa/Gaborone", tz); ++ timezones0.put("Africa/Harare", tz); ++ timezones0.put("Africa/Johannesburg", tz); ++ timezones0.put("Africa/Kigali", tz); ++ timezones0.put("Africa/Lubumbashi", tz); ++ timezones0.put("Africa/Lusaka", tz); ++ timezones0.put("Africa/Maputo", tz); ++ timezones0.put("Africa/Maseru", tz); ++ timezones0.put("Africa/Mbabane", tz); ++ timezones0.put("Africa/Tripoli", tz); ++ timezones0.put("Asia/Jerusalem", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "Asia/Amman", ++ Calendar.MARCH, -1, Calendar.THURSDAY, 0 * 3600, ++ Calendar.OCTOBER, -1, Calendar.FRIDAY, 1000 * 3600); ++ timezones0.put("Asia/Amman", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "Asia/Beirut", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 0 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 0 * 3600); ++ timezones0.put("Asia/Beirut", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "Asia/Damascus", ++ Calendar.APRIL, 1, 0, 0 * 3600, ++ Calendar.OCTOBER, 1, 0, 0 * 3600); ++ timezones0.put("Asia/Damascus", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "Asia/Gaza", ++ Calendar.APRIL, 1, 0, 0 * 3600, ++ Calendar.OCTOBER, 3, Calendar.FRIDAY, 0 * 3600); ++ timezones0.put("Asia/Gaza", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "EET", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 4000 * 3600); ++ timezones0.put("EET", tz); ++ timezones0.put("Asia/Istanbul", tz); ++ timezones0.put("Asia/Nicosia", tz); ++ timezones0.put("Europe/Athens", tz); ++ timezones0.put("Europe/Bucharest", tz); ++ timezones0.put("Europe/Chisinau", tz); ++ timezones0.put("Europe/Helsinki", tz); ++ timezones0.put("Europe/Istanbul", tz); ++ timezones0.put("Europe/Kiev", tz); ++ timezones0.put("Europe/Mariehamn", tz); ++ timezones0.put("Europe/Nicosia", tz); ++ timezones0.put("Europe/Riga", tz); ++ timezones0.put("Europe/Simferopol", tz); ++ timezones0.put("Europe/Sofia", tz); ++ timezones0.put("Europe/Tallinn", tz); ++ timezones0.put("Europe/Uzhgorod", tz); ++ timezones0.put("Europe/Vilnius", tz); ++ timezones0.put("Europe/Zaporozhye", tz); ++ tz = new SimpleTimeZone ++ (2000 * 3600, "Europe/Kaliningrad", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Europe/Kaliningrad", tz); ++ timezones0.put("Europe/Minsk", tz); ++ tz = new SimpleTimeZone ++ (3000 * 3600, "Asia/Baghdad", ++ Calendar.APRIL, 1, 0, 3000 * 3600, ++ Calendar.OCTOBER, 1, 0, 4000 * 3600); ++ timezones0.put("Asia/Baghdad", tz); ++ tz = new SimpleTimeZone ++ (3000 * 3600, "Europe/Moscow", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Europe/Moscow", tz); ++ timezones0.put("Europe/Volgograd", tz); ++ tz = new SimpleTimeZone(3000 * 3600, "EAT"); ++ timezones0.put("EAT", tz); ++ timezones0.put("Africa/Addis_Ababa", tz); ++ timezones0.put("Africa/Asmara", tz); ++ timezones0.put("Africa/Dar_es_Salaam", tz); ++ timezones0.put("Africa/Djibouti", tz); ++ timezones0.put("Africa/Kampala", tz); ++ timezones0.put("Africa/Khartoum", tz); ++ timezones0.put("Africa/Mogadishu", tz); ++ timezones0.put("Africa/Nairobi", tz); ++ timezones0.put("Antarctica/Syowa", tz); ++ timezones0.put("Asia/Aden", tz); ++ timezones0.put("Asia/Bahrain", tz); ++ timezones0.put("Asia/Kuwait", tz); ++ timezones0.put("Asia/Qatar", tz); ++ timezones0.put("Asia/Riyadh", tz); ++ timezones0.put("Indian/Antananarivo", tz); ++ timezones0.put("Indian/Comoro", tz); ++ timezones0.put("Indian/Mayotte", tz); ++ tz = new SimpleTimeZone(3500 * 3600, "Asia/Tehran"); ++ timezones0.put("Asia/Tehran", tz); ++ tz = new SimpleTimeZone ++ (4000 * 3600, "Asia/Baku", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 4000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 5000 * 3600); ++ timezones0.put("Asia/Baku", tz); ++ tz = new SimpleTimeZone ++ (4000 * 3600, "Asia/Yerevan", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Yerevan", tz); ++ timezones0.put("Europe/Samara", tz); ++ tz = new SimpleTimeZone(4000 * 3600, "NET"); ++ timezones0.put("NET", tz); ++ timezones0.put("Asia/Dubai", tz); ++ timezones0.put("Asia/Muscat", tz); ++ timezones0.put("Asia/Tbilisi", tz); ++ timezones0.put("Indian/Mahe", tz); ++ timezones0.put("Indian/Mauritius", tz); ++ timezones0.put("Indian/Reunion", tz); ++ tz = new SimpleTimeZone(4500 * 3600, "Asia/Kabul"); ++ timezones0.put("Asia/Kabul", tz); ++ tz = new SimpleTimeZone ++ (5000 * 3600, "Asia/Yekaterinburg", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Yekaterinburg", tz); ++ tz = new SimpleTimeZone(5000 * 3600, "PLT"); ++ timezones0.put("PLT", tz); ++ timezones0.put("Asia/Aqtau", tz); ++ timezones0.put("Asia/Aqtobe", tz); ++ timezones0.put("Asia/Ashgabat", tz); ++ timezones0.put("Asia/Dushanbe", tz); ++ timezones0.put("Asia/Karachi", tz); ++ timezones0.put("Asia/Oral", tz); ++ timezones0.put("Asia/Samarkand", tz); ++ timezones0.put("Asia/Tashkent", tz); ++ timezones0.put("Indian/Kerguelen", tz); ++ timezones0.put("Indian/Maldives", tz); ++ tz = new SimpleTimeZone(5500 * 3600, "BST"); ++ timezones0.put("BST", tz); ++ timezones0.put("IST", tz); ++ timezones0.put("Asia/Calcutta", tz); ++ timezones0.put("Asia/Colombo", tz); ++ tz = new SimpleTimeZone(5750 * 3600, "Asia/Katmandu"); ++ timezones0.put("Asia/Katmandu", tz); ++ tz = new SimpleTimeZone(6000 * 3600, "Antarctica/Mawson"); ++ timezones0.put("Antarctica/Mawson", tz); ++ timezones0.put("Antarctica/Vostok", tz); ++ timezones0.put("Asia/Almaty", tz); ++ timezones0.put("Asia/Bishkek", tz); ++ timezones0.put("Asia/Dhaka", tz); ++ timezones0.put("Asia/Qyzylorda", tz); ++ timezones0.put("Asia/Thimphu", tz); ++ timezones0.put("Indian/Chagos", tz); ++ tz = new SimpleTimeZone ++ (6000 * 3600, "Asia/Novosibirsk", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Novosibirsk", tz); ++ timezones0.put("Asia/Omsk", tz); ++ tz = new SimpleTimeZone(6500 * 3600, "Asia/Rangoon"); ++ timezones0.put("Asia/Rangoon", tz); ++ timezones0.put("Indian/Cocos", tz); ++ tz = new SimpleTimeZone(7000 * 3600, "VST"); ++ timezones0.put("VST", tz); ++ timezones0.put("Antarctica/Davis", tz); ++ timezones0.put("Asia/Bangkok", tz); ++ timezones0.put("Asia/Jakarta", tz); ++ timezones0.put("Asia/Phnom_Penh", tz); ++ timezones0.put("Asia/Pontianak", tz); ++ timezones0.put("Asia/Saigon", tz); ++ timezones0.put("Asia/Vientiane", tz); ++ timezones0.put("Indian/Christmas", tz); ++ tz = new SimpleTimeZone ++ (7000 * 3600, "Asia/Hovd", ++ Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, ++ Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); ++ timezones0.put("Asia/Hovd", tz); ++ tz = new SimpleTimeZone ++ (7000 * 3600, "Asia/Krasnoyarsk", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Krasnoyarsk", tz); ++ tz = new SimpleTimeZone(8000 * 3600, "CTT"); ++ timezones0.put("CTT", tz); ++ timezones0.put("Antarctica/Casey", tz); ++ timezones0.put("Asia/Brunei", tz); ++ timezones0.put("Asia/Chongqing", tz); ++ timezones0.put("Asia/Harbin", tz); ++ timezones0.put("Asia/Hong_Kong", tz); ++ timezones0.put("Asia/Kashgar", tz); ++ timezones0.put("Asia/Kuala_Lumpur", tz); ++ timezones0.put("Asia/Kuching", tz); ++ timezones0.put("Asia/Macau", tz); ++ timezones0.put("Asia/Makassar", tz); ++ timezones0.put("Asia/Manila", tz); ++ timezones0.put("Asia/Shanghai", tz); ++ timezones0.put("Asia/Singapore", tz); ++ timezones0.put("Asia/Taipei", tz); ++ timezones0.put("Asia/Urumqi", tz); ++ timezones0.put("Australia/Perth", tz); ++ tz = new SimpleTimeZone ++ (8000 * 3600, "Asia/Irkutsk", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Irkutsk", tz); ++ tz = new SimpleTimeZone ++ (8000 * 3600, "Asia/Ulaanbaatar", ++ Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, ++ Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); ++ timezones0.put("Asia/Ulaanbaatar", tz); ++ tz = new SimpleTimeZone(8750 * 3600, "Australia/Eucla"); ++ timezones0.put("Australia/Eucla", tz); ++ tz = new SimpleTimeZone ++ (9000 * 3600, "Asia/Choibalsan", ++ Calendar.MARCH, -1, Calendar.SATURDAY, 2000 * 3600, ++ Calendar.SEPTEMBER, -1, Calendar.SATURDAY, 2000 * 3600); ++ timezones0.put("Asia/Choibalsan", tz); ++ tz = new SimpleTimeZone(9000 * 3600, "JST"); ++ timezones0.put("JST", tz); ++ timezones0.put("Asia/Dili", tz); ++ timezones0.put("Asia/Jayapura", tz); ++ timezones0.put("Asia/Pyongyang", tz); ++ timezones0.put("Asia/Seoul", tz); ++ timezones0.put("Asia/Tokyo", tz); ++ timezones0.put("Pacific/Palau", tz); ++ tz = new SimpleTimeZone ++ (9000 * 3600, "Asia/Yakutsk", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Yakutsk", tz); ++ tz = new SimpleTimeZone ++ (9500 * 3600, "Australia/Adelaide", ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Australia/Adelaide", tz); ++ timezones0.put("Australia/Broken_Hill", tz); ++ tz = new SimpleTimeZone(9500 * 3600, "ACT"); ++ timezones0.put("ACT", tz); ++ timezones0.put("Australia/Darwin", tz); ++ tz = new SimpleTimeZone(10000 * 3600, "Antarctica/DumontDUrville"); ++ timezones0.put("Antarctica/DumontDUrville", tz); ++ timezones0.put("Australia/Brisbane", tz); ++ timezones0.put("Australia/Lindeman", tz); ++ timezones0.put("Pacific/Guam", tz); ++ timezones0.put("Pacific/Port_Moresby", tz); ++ timezones0.put("Pacific/Saipan", tz); ++ timezones0.put("Pacific/Truk", tz); ++ tz = new SimpleTimeZone ++ (10000 * 3600, "Asia/Sakhalin", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Sakhalin", tz); ++ timezones0.put("Asia/Vladivostok", tz); ++ tz = new SimpleTimeZone ++ (10000 * 3600, "Australia/Currie", ++ Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Australia/Currie", tz); ++ timezones0.put("Australia/Hobart", tz); ++ tz = new SimpleTimeZone ++ (10000 * 3600, "AET", ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.MARCH, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("AET", tz); ++ timezones0.put("Australia/Melbourne", tz); ++ timezones0.put("Australia/Sydney", tz); ++ tz = new SimpleTimeZone ++ (10500 * 3600, "Australia/Lord_Howe", ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, 500 * 3600); ++ timezones0.put("Australia/Lord_Howe", tz); ++ tz = new SimpleTimeZone ++ (11000 * 3600, "Asia/Magadan", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Magadan", tz); ++ tz = new SimpleTimeZone(11000 * 3600, "SST"); ++ timezones0.put("SST", tz); ++ timezones0.put("Pacific/Efate", tz); ++ timezones0.put("Pacific/Guadalcanal", tz); ++ timezones0.put("Pacific/Kosrae", tz); ++ timezones0.put("Pacific/Noumea", tz); ++ timezones0.put("Pacific/Ponape", tz); ++ tz = new SimpleTimeZone(11500 * 3600, "Pacific/Norfolk"); ++ timezones0.put("Pacific/Norfolk", tz); ++ tz = new SimpleTimeZone ++ (12000 * 3600, "NST", ++ Calendar.OCTOBER, 1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.MARCH, 3, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("NST", tz); ++ timezones0.put("Antarctica/McMurdo", tz); ++ timezones0.put("Antarctica/South_Pole", tz); ++ timezones0.put("Pacific/Auckland", tz); ++ tz = new SimpleTimeZone ++ (12000 * 3600, "Asia/Anadyr", ++ Calendar.MARCH, -1, Calendar.SUNDAY, 2000 * 3600, ++ Calendar.OCTOBER, -1, Calendar.SUNDAY, 3000 * 3600); ++ timezones0.put("Asia/Anadyr", tz); ++ timezones0.put("Asia/Kamchatka", tz); ++ tz = new SimpleTimeZone(12000 * 3600, "Pacific/Fiji"); ++ timezones0.put("Pacific/Fiji", tz); ++ timezones0.put("Pacific/Funafuti", tz); ++ timezones0.put("Pacific/Kwajalein", tz); ++ timezones0.put("Pacific/Majuro", tz); ++ timezones0.put("Pacific/Nauru", tz); ++ timezones0.put("Pacific/Tarawa", tz); ++ timezones0.put("Pacific/Wake", tz); ++ timezones0.put("Pacific/Wallis", tz); ++ tz = new SimpleTimeZone ++ (12750 * 3600, "Pacific/Chatham", ++ Calendar.OCTOBER, 1, Calendar.SUNDAY, 2750 * 3600, ++ Calendar.MARCH, 3, Calendar.SUNDAY, 3750 * 3600); ++ timezones0.put("Pacific/Chatham", tz); ++ tz = new SimpleTimeZone(13000 * 3600, "Pacific/Enderbury"); ++ timezones0.put("Pacific/Enderbury", tz); ++ timezones0.put("Pacific/Tongatapu", tz); ++ tz = new SimpleTimeZone(14000 * 3600, "Pacific/Kiritimati"); ++ timezones0.put("Pacific/Kiritimati", tz); ++ } ++ return timezones0; + } + ++ /** ++ * Maps a time zone name (with optional GMT offset and daylight time ++ * zone name) to one of the known time zones. This method called ++ * with the result of System.getProperty("user.timezone") ++ * or getDefaultTimeZoneId(). Note that giving one of ++ * the standard tz data names from ftp://elsie.nci.nih.gov/pub/ is ++ * preferred. ++ * The time zone name can be given as follows: ++ * (standard zone name)[(GMT offset)[(DST zone name)[DST offset]]] ++ * ++ *

++ * If only a (standard zone name) is given (no numbers in the ++ * String) then it gets mapped directly to the TimeZone with that ++ * name, if that fails null is returned. ++ *

++ * Alternately, a POSIX-style TZ string can be given, defining the time zone: ++ * std offset dst offset,date/time,date/time ++ * See the glibc manual, or the man page for tzset for details ++ * of this format. ++ *

++ * A GMT offset is the offset to add to the local time to get GMT. ++ * If a (GMT offset) is included (either in seconds or hours) then ++ * an attempt is made to find a TimeZone name matching both the name ++ * and the offset (that doesn't observe daylight time, if the ++ * timezone observes daylight time then you must include a daylight ++ * time zone name after the offset), if that fails then a TimeZone ++ * with the given GMT offset is returned (whether or not the ++ * TimeZone observes daylight time is ignored), if that also fails ++ * the GMT TimeZone is returned. ++ *

++ * If the String ends with (GMT offset)(daylight time zone name) ++ * then an attempt is made to find a TimeZone with the given name and ++ * GMT offset that also observes (the daylight time zone name is not ++ * currently used in any other way), if that fails a TimeZone with ++ * the given GMT offset that observes daylight time is returned, if ++ * that also fails the GMT TimeZone is returned. ++ *

++ * Examples: In Chicago, the time zone id could be "CST6CDT", but ++ * the preferred name would be "America/Chicago". In Indianapolis ++ * (which does not have Daylight Savings Time) the string could be ++ * "EST5", but the preferred name would be "America/Indianapolis". ++ * The standard time zone name for The Netherlands is "Europe/Amsterdam", ++ * but can also be given as "CET-1CEST". ++ */ ++ private static TimeZone getDefaultTimeZone(String sysTimeZoneId) ++ { ++ String stdName = null; ++ int stdOffs; ++ int dstOffs; ++ try ++ { ++ int idLength = sysTimeZoneId.length(); ++ ++ int index = 0; ++ int prevIndex; ++ char c; ++ ++ // get std ++ do ++ c = sysTimeZoneId.charAt(index); ++ while (c != '+' && c != '-' && c != ',' && c != ':' ++ && ! Character.isDigit(c) && c != '\0' && ++index < idLength); ++ ++ if (index >= idLength) ++ return getTimeZoneInternal(sysTimeZoneId); ++ ++ stdName = sysTimeZoneId.substring(0, index); ++ prevIndex = index; ++ ++ // get the std offset ++ do ++ c = sysTimeZoneId.charAt(index++); ++ while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) ++ && index < idLength); ++ if (index < idLength) ++ index--; ++ ++ { // convert the dst string to a millis number ++ String offset = sysTimeZoneId.substring(prevIndex, index); ++ prevIndex = index; ++ ++ if (offset.charAt(0) == '+' || offset.charAt(0) == '-') ++ stdOffs = parseTime(offset.substring(1)); ++ else ++ stdOffs = parseTime(offset); ++ ++ if (offset.charAt(0) == '-') ++ stdOffs = -stdOffs; + +- /* Look up default timezone */ +- static ++ // TZ timezone offsets are positive when WEST of the meridian. ++ stdOffs = -stdOffs; ++ } ++ ++ // Done yet? (Format: std offset) ++ if (index >= idLength) ++ { ++ // Do we have an existing timezone with that name and offset? ++ TimeZone tz = getTimeZoneInternal(stdName); ++ if (tz != null) ++ if (tz.getRawOffset() == stdOffs) ++ return tz; ++ ++ // Custom then. ++ return new SimpleTimeZone(stdOffs, stdName); ++ } ++ ++ // get dst ++ do ++ c = sysTimeZoneId.charAt(index); ++ while (c != '+' && c != '-' && c != ',' && c != ':' ++ && ! Character.isDigit(c) && c != '\0' && ++index < idLength); ++ ++ // Done yet? (Format: std offset dst) ++ if (index >= idLength) ++ { ++ // Do we have an existing timezone with that name and offset ++ // which has DST? ++ TimeZone tz = getTimeZoneInternal(stdName); ++ if (tz != null) ++ if (tz.getRawOffset() == stdOffs && tz.useDaylightTime()) ++ return tz; ++ ++ // Custom then. ++ return new SimpleTimeZone(stdOffs, stdName); ++ } ++ ++ // get the dst offset ++ prevIndex = index; ++ do ++ c = sysTimeZoneId.charAt(index++); ++ while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) ++ && index < idLength); ++ if (index < idLength) ++ index--; ++ ++ if (index == prevIndex && (c == ',' || c == ';')) ++ { ++ // Missing dst offset defaults to one hour ahead of standard ++ // time. ++ dstOffs = stdOffs + 60 * 60 * 1000; ++ } ++ else ++ { // convert the dst string to a millis number ++ String offset = sysTimeZoneId.substring(prevIndex, index); ++ prevIndex = index; ++ ++ if (offset.charAt(0) == '+' || offset.charAt(0) == '-') ++ dstOffs = parseTime(offset.substring(1)); ++ else ++ dstOffs = parseTime(offset); ++ ++ if (offset.charAt(0) == '-') ++ dstOffs = -dstOffs; ++ ++ // TZ timezone offsets are positive when WEST of the meridian. ++ dstOffs = -dstOffs; ++ } ++ ++ // Done yet? (Format: std offset dst offset) ++ // FIXME: We don't support DST without a rule given. Should we? ++ if (index >= idLength) ++ { ++ // Time Zone existing with same name, dst and offsets? ++ TimeZone tz = getTimeZoneInternal(stdName); ++ if (tz != null) ++ if (tz.getRawOffset() == stdOffs && tz.useDaylightTime()) ++ { ++ if ((tz instanceof SimpleTimeZone) ++ && ((SimpleTimeZone) tz).getDSTSavings() ++ == (dstOffs - stdOffs)) ++ return tz; ++ if ((tz instanceof ZoneInfo) ++ && ((ZoneInfo) tz).getDSTSavings() ++ == (dstOffs - stdOffs)) ++ return tz; ++ } ++ ++ return new SimpleTimeZone(stdOffs, stdName); ++ } ++ ++ // get the DST rule ++ if (sysTimeZoneId.charAt(index) == ',' ++ || sysTimeZoneId.charAt(index) == ';') ++ { ++ index++; ++ int offs = index; ++ while (sysTimeZoneId.charAt(index) != ',' ++ && sysTimeZoneId.charAt(index) != ';') ++ index++; ++ String startTime = sysTimeZoneId.substring(offs, index); ++ index++; ++ String endTime = sysTimeZoneId.substring(index); ++ ++ index = startTime.indexOf('/'); ++ int startMillis; ++ int endMillis; ++ String startDate; ++ String endDate; ++ if (index != -1) ++ { ++ startDate = startTime.substring(0, index); ++ startMillis = parseTime(startTime.substring(index + 1)); ++ } ++ else ++ { ++ startDate = startTime; ++ // if time isn't given, default to 2:00:00 AM. ++ startMillis = 2 * 60 * 60 * 1000; ++ } ++ index = endTime.indexOf('/'); ++ if (index != -1) ++ { ++ endDate = endTime.substring(0, index); ++ endMillis = parseTime(endTime.substring(index + 1)); ++ } ++ else ++ { ++ endDate = endTime; ++ // if time isn't given, default to 2:00:00 AM. ++ endMillis = 2 * 60 * 60 * 1000; ++ } ++ ++ int[] start = getDateParams(startDate); ++ int[] end = getDateParams(endDate); ++ return new SimpleTimeZone(stdOffs, stdName, start[0], start[1], ++ start[2], startMillis, end[0], end[1], ++ end[2], endMillis, (dstOffs - stdOffs)); ++ } ++ } ++ ++ // FIXME: Produce a warning here? ++ catch (IndexOutOfBoundsException _) ++ { ++ } ++ catch (NumberFormatException _) ++ { ++ } ++ ++ return null; ++ } ++ ++ /** ++ * Parses and returns the params for a POSIX TZ date field, ++ * in the format int[]{ month, day, dayOfWeek }, following the ++ * SimpleTimeZone constructor rules. ++ */ ++ private static int[] getDateParams(String date) + { +- // System.loadLibrary("javautil"); ++ int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; ++ int month; + +- String tzid = System.getProperty("user.timezone"); ++ if (date.charAt(0) == 'M' || date.charAt(0) == 'm') ++ { ++ int day; ++ ++ // Month, week of month, day of week ++ ++ // "Mm.w.d". d is between 0 (Sunday) and 6. Week w is ++ // between 1 and 5; Week 1 is the first week in which day d ++ // occurs and Week 5 specifies the last d day in the month. ++ // Month m is between 1 and 12. ++ ++ month = Integer.parseInt(date.substring(1, date.indexOf('.'))); ++ int week = Integer.parseInt(date.substring(date.indexOf('.') + 1, ++ date.lastIndexOf('.'))); ++ int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.') ++ + 1)); ++ dayOfWeek++; // Java day of week is one-based, Sunday is first day. ++ ++ if (week == 5) ++ day = -1; // last day of month is -1 in java, 5 in TZ ++ else ++ { ++ // First day of week starting on or after. For example, ++ // to specify the second Sunday of April, set month to ++ // APRIL, day-of-month to 8, and day-of-week to -SUNDAY. ++ day = (week - 1) * 7 + 1; ++ dayOfWeek = -dayOfWeek; ++ } ++ ++ month--; // Java month is zero-based. ++ return new int[] { month, day, dayOfWeek }; ++ } ++ ++ // julian day, either zero-based 0<=n<=365 (incl feb 29) ++ // or one-based 1<=n<=365 (no feb 29) ++ int julianDay; // Julian day, ++ ++ if (date.charAt(0) != 'J' || date.charAt(0) != 'j') ++ { ++ julianDay = Integer.parseInt(date.substring(1)); ++ julianDay++; // make 1-based ++ // Adjust day count to include feb 29. ++ dayCount = new int[] ++ { ++ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ++ }; ++ } ++ else ++ // 1-based julian day ++ julianDay = Integer.parseInt(date); ++ ++ int i = 11; ++ while (i > 0) ++ if (dayCount[i] < julianDay) ++ break; ++ else ++ i--; ++ julianDay -= dayCount[i]; ++ month = i; ++ return new int[] { month, julianDay, 0 }; ++ } + +- if (tzid == null) +- tzid = "GMT"; ++ /** ++ * Parses a time field hh[:mm[:ss]], returning the result ++ * in milliseconds. No leading sign. ++ */ ++ private static int parseTime(String time) ++ { ++ int millis = 0; ++ int i = 0; + +- defaultZone = getTimeZone(tzid); ++ while (i < time.length()) ++ if (time.charAt(i) == ':') ++ break; ++ else ++ i++; ++ millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i)); ++ if (i >= time.length()) ++ return millis; ++ ++ int iprev = ++i; ++ while (i < time.length()) ++ if (time.charAt(i) == ':') ++ break; ++ else ++ i++; ++ millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i)); ++ if (i >= time.length()) ++ return millis; ++ ++ millis += 1000 * Integer.parseInt(time.substring(++i)); ++ return millis; + } + ++ /* This method returns us a time zone id string which is in the ++ form . ++ The GMT offset is in seconds, except where it is evenly divisible ++ by 3600, then it is in hours. If the zone does not observe ++ daylight time, then the daylight zone name is omitted. Examples: ++ in Chicago, the timezone would be CST6CDT. In Indianapolis ++ (which does not have Daylight Savings Time) the string would ++ be EST5 ++ */ ++ private static native String getDefaultTimeZoneId(); ++ private static native String getTZEnvVar(); ++ + /** + * Gets the time zone offset, for current date, modified in case of + * daylight savings. This is the offset to add to UTC to get the local +@@ -916,6 +1449,8 @@ public abstract class TimeZone implement + // TimeZone knows nothing about daylight saving offsets. + offset += ((SimpleTimeZone) this).getDSTSavings(); + } ++ if (dst && this instanceof ZoneInfo) ++ offset += ((ZoneInfo) this).getDSTSavings(); + + StringBuffer sb = new StringBuffer(9); + sb.append("GMT"); +@@ -949,30 +1484,67 @@ public abstract class TimeZone implement + * @return The time zone for the identifier or GMT, if no such time + * zone exists. + */ +- // FIXME: XXX: JCL indicates this and other methods are synchronized. +- public static TimeZone getTimeZone(String ID) ++ private static TimeZone getTimeZoneInternal(String ID) + { + // First check timezones hash +- TimeZone tz = (TimeZone) timezones.get(ID); +- if (tz != null) ++ TimeZone tz = null; ++ TimeZone tznew = null; ++ for (int pass = 0; pass < 2; pass++) + { +- if (tz.getID().equals(ID)) +- return tz; ++ synchronized (TimeZone.class) ++ { ++ tz = (TimeZone) timezones().get(ID); ++ if (tz != null) ++ { ++ if (!tz.getID().equals(ID)) ++ { ++ // We always return a timezone with the requested ID. ++ // This is the same behaviour as with JDK1.2. ++ tz = (TimeZone) tz.clone(); ++ tz.setID(ID); ++ // We also save the alias, so that we return the same ++ // object again if getTimeZone is called with the same ++ // alias. ++ timezones().put(ID, tz); ++ } ++ return tz; ++ } ++ else if (tznew != null) ++ { ++ timezones().put(ID, tznew); ++ return tznew; ++ } ++ } ++ ++ if (pass == 1 || zoneinfo_dir == null) ++ return null; + +- // We always return a timezone with the requested ID. +- // This is the same behaviour as with JDK1.2. +- tz = (TimeZone) tz.clone(); +- tz.setID(ID); +- // We also save the alias, so that we return the same +- // object again if getTimeZone is called with the same +- // alias. +- timezones.put(ID, tz); +- return tz; ++ // aliases0 is never changing after first timezones(), so should ++ // be safe without synchronization. ++ String zonename = (String) aliases0.get(ID); ++ if (zonename == null) ++ zonename = ID; ++ ++ // Read the file outside of the critical section, it is expensive. ++ tznew = ZoneInfo.readTZFile (ID, zoneinfo_dir ++ + File.separatorChar + zonename); ++ if (tznew == null) ++ return null; + } + +- // See if the ID is really a GMT offset form. +- // Note that GMT is in the table so we know it is different. +- if (ID.startsWith("GMT")) ++ return null; ++ } ++ ++ /** ++ * Gets the TimeZone for the given ID. ++ * @param ID the time zone identifier. ++ * @return The time zone for the identifier or GMT, if no such time ++ * zone exists. ++ */ ++ public static TimeZone getTimeZone(String ID) ++ { ++ // Check for custom IDs first ++ if (ID.startsWith("GMT") && ID.length() > 3) + { + int pos = 3; + int offset_direction = 1; +@@ -1017,8 +1589,20 @@ public abstract class TimeZone implement + } + } + +- return new SimpleTimeZone((hour * (60 * 60 * 1000) + +- minute * (60 * 1000)) ++ // Custom IDs have to be normalized ++ StringBuffer sb = new StringBuffer(9); ++ sb.append("GMT"); ++ ++ sb.append(offset_direction >= 0 ? '+' : '-'); ++ sb.append((char) ('0' + hour / 10)); ++ sb.append((char) ('0' + hour % 10)); ++ sb.append(':'); ++ sb.append((char) ('0' + minute / 10)); ++ sb.append((char) ('0' + minute % 10)); ++ ID = sb.toString(); ++ ++ return new SimpleTimeZone((hour * (60 * 60 * 1000) ++ + minute * (60 * 1000)) + * offset_direction, ID); + } + catch (NumberFormatException e) +@@ -1026,8 +1610,11 @@ public abstract class TimeZone implement + } + } + +- // Finally, return GMT per spec +- return getTimeZone("GMT"); ++ TimeZone tz = getTimeZoneInternal(ID); ++ if (tz != null) ++ return tz; ++ ++ return new SimpleTimeZone(0, "GMT"); + } + + /** +@@ -1040,37 +1627,134 @@ public abstract class TimeZone implement + */ + public static String[] getAvailableIDs(int rawOffset) + { ++ synchronized (TimeZone.class) ++ { ++ Hashtable h = timezones(); ++ int count = 0; ++ if (zoneinfo_dir == null) ++ { ++ Iterator iter = h.entrySet().iterator(); ++ while (iter.hasNext()) ++ { ++ // Don't iterate the values, since we want to count ++ // doubled values (aliases) ++ Map.Entry entry = (Map.Entry) iter.next(); ++ if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) ++ count++; ++ } ++ ++ String[] ids = new String[count]; ++ count = 0; ++ iter = h.entrySet().iterator(); ++ while (iter.hasNext()) ++ { ++ Map.Entry entry = (Map.Entry) iter.next(); ++ if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) ++ ids[count++] = (String) entry.getKey(); ++ } ++ return ids; ++ } ++ } ++ ++ String[] s = getAvailableIDs(); + int count = 0; +- Iterator iter = timezones.entrySet().iterator(); +- while (iter.hasNext()) ++ for (int i = 0; i < s.length; i++) + { +- // Don't iterate the values, since we want to count +- // doubled values (aliases) +- Map.Entry entry = (Map.Entry) iter.next(); +- if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) ++ TimeZone t = getTimeZoneInternal(s[i]); ++ if (t == null || t.getRawOffset() != rawOffset) ++ s[i] = null; ++ else + count++; + } +- + String[] ids = new String[count]; + count = 0; +- iter = timezones.entrySet().iterator(); +- while (iter.hasNext()) +- { +- Map.Entry entry = (Map.Entry) iter.next(); +- if (((TimeZone) entry.getValue()).getRawOffset() == rawOffset) +- ids[count++] = (String) entry.getKey(); +- } ++ for (int i = 0; i < s.length; i++) ++ if (s[i] != null) ++ ids[count++] = s[i]; ++ + return ids; + } + ++ private static int getAvailableIDs(File d, String prefix, ArrayList list) ++ { ++ String[] files = d.list(); ++ int count = files.length; ++ boolean top = prefix.length() == 0; ++ list.add (files); ++ for (int i = 0; i < files.length; i++) ++ { ++ if (top ++ && (files[i].equals("posix") ++ || files[i].equals("right") ++ || files[i].endsWith(".tab") ++ || aliases0.get(files[i]) != null)) ++ { ++ files[i] = null; ++ count--; ++ continue; ++ } ++ ++ File f = new File(d, files[i]); ++ if (f.isDirectory()) ++ { ++ count += getAvailableIDs(f, prefix + files[i] ++ + File.separatorChar, list) - 1; ++ files[i] = null; ++ } ++ else ++ files[i] = prefix + files[i]; ++ } ++ return count; ++ } ++ + /** + * Gets all available IDs. + * @return An array of all supported IDs. + */ + public static String[] getAvailableIDs() + { +- return (String[]) +- timezones.keySet().toArray(new String[timezones.size()]); ++ synchronized (TimeZone.class) ++ { ++ Hashtable h = timezones(); ++ if (zoneinfo_dir == null) ++ return (String[]) h.keySet().toArray(new String[h.size()]); ++ ++ if (availableIDs != null) ++ { ++ String[] ids = new String[availableIDs.length]; ++ for (int i = 0; i < availableIDs.length; i++) ++ ids[i] = availableIDs[i]; ++ return ids; ++ } ++ ++ File d = new File(zoneinfo_dir); ++ ArrayList list = new ArrayList(30); ++ int count = getAvailableIDs(d, "", list) + aliases0.size(); ++ availableIDs = new String[count]; ++ String[] ids = new String[count]; ++ ++ count = 0; ++ for (int i = 0; i < list.size(); i++) ++ { ++ String[] s = (String[]) list.get(i); ++ for (int j = 0; j < s.length; j++) ++ if (s[j] != null) ++ { ++ availableIDs[count] = s[j]; ++ ids[count++] = s[j]; ++ } ++ } ++ ++ Iterator iter = aliases0.entrySet().iterator(); ++ while (iter.hasNext()) ++ { ++ Map.Entry entry = (Map.Entry) iter.next(); ++ availableIDs[count] = (String) entry.getKey(); ++ ids[count++] = (String) entry.getKey(); ++ } ++ ++ return ids; ++ } + } + + /** +@@ -1081,12 +1765,12 @@ public abstract class TimeZone implement + */ + public static TimeZone getDefault() + { +- return defaultZone; ++ return defaultZone(); + } + + public static void setDefault(TimeZone zone) + { +- defaultZone = zone; ++ defaultZone0 = zone; + } + + /** +@@ -1116,4 +1800,66 @@ public abstract class TimeZone implement + return null; + } + } ++ ++ /** ++ * Tries to read the time zone name from a file. ++ * If the file cannot be read or an IOException occurs null is returned. ++ *

++ * The /etc/sysconfig/clock file is not standard, but a lot of systems ++ * have it. The file is included by shell scripts and the timezone ++ * name is defined in ZONE variable. ++ * This routine should grok it with or without quotes: ++ * ZONE=America/New_York ++ * or ++ * ZONE="Europe/London" ++ */ ++ private static String readSysconfigClockFile(String file) ++ { ++ BufferedReader br = null; ++ try ++ { ++ FileInputStream fis = new FileInputStream(file); ++ BufferedInputStream bis = new BufferedInputStream(fis); ++ br = new BufferedReader(new InputStreamReader(bis)); ++ ++ for (String line = br.readLine(); line != null; line = br.readLine()) ++ { ++ line = line.trim(); ++ if (line.length() < 8 || !line.startsWith("ZONE=")) ++ continue; ++ int posstart = 6; ++ int posend; ++ if (line.charAt(5) == '"') ++ posend = line.indexOf('"', 6); ++ else if (line.charAt(5) == '\'') ++ posend = line.indexOf('\'', 6); ++ else ++ { ++ posstart = 5; ++ posend = line.length(); ++ } ++ if (posend < 0) ++ return null; ++ return line.substring(posstart, posend); ++ } ++ return null; ++ } ++ catch (IOException ioe) ++ { ++ // Parse error, not a proper tzfile. ++ return null; ++ } ++ finally ++ { ++ try ++ { ++ if (br != null) ++ br.close(); ++ } ++ catch (IOException ioe) ++ { ++ // Error while close, nothing we can do. ++ } ++ } ++ } + } +--- libjava/java/lang/System.java.jj 2007-02-23 21:27:25.000000000 +0100 ++++ libjava/java/lang/System.java 2007-02-24 21:47:38.000000000 +0100 +@@ -42,83 +42,6 @@ public final class System + + public static native long currentTimeMillis (); + +- // FIXME: When merging with Classpath, remember to remove the call to +- // getDefaultTimeZoneId from java.util.Timezone. +- private static native String getSystemTimeZone (); +- +- // Get the System Timezone as reported by the OS. It should be in +- // the form PST8PDT so we'll need to parse it and check that it's valid. +- // The result is used to set the user.timezone property in init_properties. +- // FIXME: Using the code from Classpath for generating the System +- // Timezone IMO is suboptimal because it ignores whether the rules for +- // DST match up. +- private static String getDefaultTimeZoneId () +- { +- String sysTimeZoneId = getSystemTimeZone (); +- +- // Check if this is a valid timezone. Make sure the IDs match +- // since getTimeZone returns GMT if no match is found. +- TimeZone tz = TimeZone.getTimeZone (sysTimeZoneId); +- if (tz.getID ().equals (sysTimeZoneId)) +- return sysTimeZoneId; +- +- // Check if the base part of sysTimeZoneId is a valid timezone that +- // matches with daylight usage and rawOffset. Make sure the IDs match +- // since getTimeZone returns GMT if no match is found. +- // First find start of GMT offset info and any Daylight zone name. +- int startGMToffset = 0; +- int sysTimeZoneIdLength = sysTimeZoneId.length(); +- for (int i = 0; i < sysTimeZoneIdLength && startGMToffset == 0; i++) +- { +- if (Character.isDigit (sysTimeZoneId.charAt (i))) +- startGMToffset = i; +- } +- +- int startDaylightZoneName = 0; +- boolean usesDaylight = false; +- for (int i = sysTimeZoneIdLength - 1; +- i >= 0 && !Character.isDigit (sysTimeZoneId.charAt (i)); --i) +- { +- startDaylightZoneName = i; +- } +- if (startDaylightZoneName > 0) +- usesDaylight = true; +- +- int GMToffset = Integer.parseInt (startDaylightZoneName == 0 ? +- sysTimeZoneId.substring (startGMToffset) : +- sysTimeZoneId.substring (startGMToffset, startDaylightZoneName)); +- +- // Offset could be in hours or seconds. Convert to millis. +- if (GMToffset < 24) +- GMToffset *= 60 * 60; +- GMToffset *= -1000; +- +- String tzBasename = sysTimeZoneId.substring (0, startGMToffset); +- tz = TimeZone.getTimeZone (tzBasename); +- if (tz.getID ().equals (tzBasename) && tz.getRawOffset () == GMToffset) +- { +- boolean tzUsesDaylight = tz.useDaylightTime (); +- if (usesDaylight && tzUsesDaylight || !usesDaylight && !tzUsesDaylight) +- return tzBasename; +- } +- +- // If no match, see if a valid timezone has the same attributes as this +- // and then use it instead. +- String[] IDs = TimeZone.getAvailableIDs (GMToffset); +- for (int i = 0; i < IDs.length; ++i) +- { +- // FIXME: The daylight savings rules may not match the rules +- // for the desired zone. +- boolean IDusesDaylight = +- TimeZone.getTimeZone (IDs[i]).useDaylightTime (); +- if (usesDaylight && IDusesDaylight || !usesDaylight && !IDusesDaylight) +- return IDs[i]; +- } +- +- // If all else fails, return null. +- return null; +- } +- + public static void exit (int status) + { + Runtime.getRuntime().exit(status); +--- libjava/posix.cc.jj 2007-02-23 21:17:39.000000000 +0100 ++++ libjava/posix.cc 2007-02-23 21:27:25.000000000 +0100 +@@ -79,6 +79,10 @@ _Jv_platform_initProperties (java::util: + if (! tmpdir) + tmpdir = "/tmp"; + SET ("java.io.tmpdir", tmpdir); ++ const char *zoneinfodir = ::getenv("TZDATA"); ++ if (! zoneinfodir) ++ zoneinfodir = "/usr/share/zoneinfo"; ++ SET ("gnu.java.util.zoneinfo.dir", zoneinfodir); + } + + static inline void +--- libjava/gnu/java/util/ZoneInfo.java.jj 2007-02-23 21:27:25.000000000 +0100 ++++ libjava/gnu/java/util/ZoneInfo.java 2007-02-24 19:14:27.000000000 +0100 +@@ -0,0 +1,1149 @@ ++/* gnu.java.util.ZoneInfo ++ Copyright (C) 2007 Free Software Foundation, Inc. ++ ++This file is part of GNU Classpath. ++ ++GNU Classpath is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2, or (at your option) ++any later version. ++ ++GNU Classpath is distributed in the hope that it will be useful, but ++WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with GNU Classpath; see the file COPYING. If not, write to the ++Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++02110-1301 USA. ++ ++Linking this library statically or dynamically with other modules is ++making a combined work based on this library. Thus, the terms and ++conditions of the GNU General Public License cover the whole ++combination. ++ ++As a special exception, the copyright holders of this library give you ++permission to link this library with independent modules to produce an ++executable, regardless of the license terms of these independent ++modules, and to copy and distribute the resulting executable under ++terms of your choice, provided that you also meet, for each linked ++independent module, the terms and conditions of the license of that ++module. An independent module is a module which is not derived from ++or based on this library. If you modify this library, you may extend ++this exception to your version of the library, but you are not ++obligated to do so. If you do not wish to do so, delete this ++exception statement from your version. */ ++ ++ ++package gnu.java.util; ++ ++import java.io.BufferedInputStream; ++import java.io.DataInputStream; ++import java.io.EOFException; ++import java.io.FileInputStream; ++import java.io.InputStream; ++import java.io.IOException; ++import java.util.Calendar; ++import java.util.Date; ++import java.util.GregorianCalendar; ++import java.util.SimpleTimeZone; ++import java.util.TimeZone; ++ ++/** ++ * This class represents more advanced variant of java.util.SimpleTimeZone. ++ * It can handle zic(8) compiled transition dates plus uses a SimpleTimeZone ++ * for years beyond last precomputed transition. Before first precomputed ++ * transition it assumes no daylight saving was in effect. ++ * Timezones that never used daylight saving time should use just ++ * SimpleTimeZone instead of this class. ++ * ++ * This object is tightly bound to the Gregorian calendar. It assumes ++ * a regular seven days week, and the month lengths are that of the ++ * Gregorian Calendar. ++ * ++ * @see Calendar ++ * @see GregorianCalendar ++ * @see SimpleTimeZone ++ * @author Jakub Jelinek ++ */ ++public class ZoneInfo extends TimeZone ++{ ++ private static final int SECS_SHIFT = 22; ++ private static final long OFFSET_MASK = (1 << 21) - 1; ++ private static final int OFFSET_SHIFT = 64 - 21; ++ private static final long IS_DST = 1 << 21; ++ ++ /** ++ * The raw time zone offset in milliseconds to GMT, ignoring ++ * daylight savings. ++ * @serial ++ */ ++ private int rawOffset; ++ ++ /** ++ * Cached DST savings for the last transition rule. ++ */ ++ private int dstSavings; ++ ++ /** ++ * Cached flag whether last transition rule uses DST saving. ++ */ ++ private boolean useDaylight; ++ ++ /** ++ * Array of encoded transitions. ++ * Transition time in UTC seconds since epoch is in the most ++ * significant 64 - SECS_SHIFT bits, then one bit flag ++ * whether DST is active and the least significant bits ++ * containing offset relative to rawOffset. Both the DST ++ * flag and relative offset apply to time before the transition ++ * and after or equal to previous transition if any. ++ * The array must be sorted. ++ */ ++ private long[] transitions; ++ ++ /** ++ * SimpleTimeZone rule which applies on or after the latest ++ * transition. If the DST changes are not expresible as a ++ * SimpleTimeZone rule, then the rule should just contain ++ * the standard time and no DST time. ++ */ ++ private SimpleTimeZone lastRule; ++ ++ /** ++ * Cached GMT SimpleTimeZone object for internal use in ++ * getOffset method. ++ */ ++ private static SimpleTimeZone gmtZone = null; ++ ++ static final long serialVersionUID = -3740626706860383657L; ++ ++ /** ++ * Create a ZoneInfo with the given time offset ++ * from GMT and with daylight savings. ++ * ++ * @param rawOffset The time offset from GMT in milliseconds. ++ * @param id The identifier of this time zone. ++ * @param transitions Array of transition times in UTC seconds since ++ * Epoch in topmost 42 bits, below that 1 boolean bit whether the time ++ * before that transition used daylight saving and in bottommost 21 ++ * bits relative daylight saving offset against rawOffset in seconds ++ * that applies before this transition. ++ * @param endRule SimpleTimeZone class describing the daylight saving ++ * rules after the last transition. ++ */ ++ public ZoneInfo(int rawOffset, String id, long[] transitions, ++ SimpleTimeZone lastRule) ++ { ++ if (transitions == null || transitions.length < 1) ++ throw new IllegalArgumentException("transitions must not be null"); ++ if (lastRule == null) ++ throw new IllegalArgumentException("lastRule must not be null"); ++ this.rawOffset = rawOffset; ++ this.transitions = transitions; ++ this.lastRule = lastRule; ++ setID(id); ++ computeDSTSavings(); ++ } ++ ++ /** ++ * Gets the time zone offset, for current date, modified in case of ++ * daylight savings. This is the offset to add to UTC to get the local ++ * time. ++ * ++ * The day must be a positive number and dayOfWeek must be a positive value ++ * from Calendar. dayOfWeek is redundant, but must match the other values ++ * or an inaccurate result may be returned. ++ * ++ * @param era the era of the given date ++ * @param year the year of the given date ++ * @param month the month of the given date, 0 for January. ++ * @param day the day of month ++ * @param dayOfWeek the day of week; this must match the other fields. ++ * @param millis the millis in the day (in local standard time) ++ * @return the time zone offset in milliseconds. ++ * @throws IllegalArgumentException if arguments are incorrect. ++ */ ++ public int getOffset(int era, int year, int month, int day, int dayOfWeek, ++ int millis) ++ { ++ if (gmtZone == null) ++ gmtZone = new SimpleTimeZone(0, "GMT"); ++ ++ if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) ++ throw new IllegalArgumentException("dayOfWeek out of range"); ++ if (month < Calendar.JANUARY || month > Calendar.DECEMBER) ++ throw new IllegalArgumentException("month out of range:" + month); ++ ++ if (era != GregorianCalendar.AD) ++ return (int) (((transitions[0] << OFFSET_SHIFT) >> OFFSET_SHIFT) * 1000); ++ ++ GregorianCalendar cal = new GregorianCalendar((TimeZone) gmtZone); ++ cal.set(year, month, day, 0, 0, 0); ++ if (cal.get(Calendar.DAY_OF_MONTH) != day) ++ throw new IllegalArgumentException("day out of range"); ++ ++ long date = cal.getTime().getTime() - rawOffset + millis; ++ long d = (date >= 0 ? date / 1000 : (date + 1) / 1000 - 1); ++ long transition = findTransition(d); ++ ++ // For times on or after last transition use lastRule. ++ if (transition == Long.MAX_VALUE) ++ return lastRule.getOffset(era, year, month, day, dayOfWeek, millis); ++ ++ return (int) (((transition << OFFSET_SHIFT) >> OFFSET_SHIFT) * 1000); ++ } ++ ++ private long findTransition(long secs) ++ { ++ if (secs < (transitions[0] >> SECS_SHIFT)) ++ return transitions[0]; ++ ++ if (secs >= (transitions[transitions.length-1] >> SECS_SHIFT)) ++ return Long.MAX_VALUE; ++ ++ long val = (secs + 1) << SECS_SHIFT; ++ int lo = 1; ++ int hi = transitions.length; ++ int mid = 1; ++ while (lo < hi) ++ { ++ mid = (lo + hi) / 2; ++ // secs < (transitions[mid-1] >> SECS_SHIFT) ++ if (val <= transitions[mid-1]) ++ hi = mid; ++ // secs >= (transitions[mid] >> SECS_SHIFT) ++ else if (val > transitions[mid]) ++ lo = mid + 1; ++ else ++ break; ++ } ++ return transitions[mid]; ++ } ++ ++ /** ++ * Returns the time zone offset to GMT in milliseconds, ignoring ++ * day light savings. ++ * @return the time zone offset. ++ */ ++ public int getRawOffset() ++ { ++ return rawOffset; ++ } ++ ++ /** ++ * Sets the standard time zone offset to GMT. ++ * @param rawOffset The time offset from GMT in milliseconds. ++ */ ++ public void setRawOffset(int rawOffset) ++ { ++ this.rawOffset = rawOffset; ++ lastRule.setRawOffset(rawOffset); ++ } ++ ++ private void computeDSTSavings() ++ { ++ if (lastRule.useDaylightTime()) ++ { ++ dstSavings = lastRule.getDSTSavings(); ++ useDaylight = true; ++ } ++ else ++ { ++ dstSavings = 0; ++ useDaylight = false; ++ // lastRule might say no DST is in effect simply because ++ // the DST rules are too complex for SimpleTimeZone, say ++ // for Asia/Jerusalem. ++ // Look at the last DST offset if it is newer than current time. ++ long currentSecs = System.currentTimeMillis() / 1000; ++ int i; ++ for (i = transitions.length - 1; ++ i >= 0 && currentSecs < (transitions[i] >> SECS_SHIFT); ++ i--) ++ if ((transitions[i] & IS_DST) != 0) ++ { ++ dstSavings = (int) (((transitions[i] << OFFSET_SHIFT) ++ >> OFFSET_SHIFT) * 1000) ++ - rawOffset; ++ useDaylight = true; ++ break; ++ } ++ } ++ } ++ ++ /** ++ * Gets the daylight savings offset. This is a positive offset in ++ * milliseconds with respect to standard time. Typically this ++ * is one hour, but for some time zones this may be half an our. ++ * @return the daylight savings offset in milliseconds. ++ */ ++ public int getDSTSavings() ++ { ++ return dstSavings; ++ } ++ ++ /** ++ * Returns if this time zone uses daylight savings time. ++ * @return true, if we use daylight savings time, false otherwise. ++ */ ++ public boolean useDaylightTime() ++ { ++ return useDaylight; ++ } ++ ++ /** ++ * Determines if the given date is in daylight savings time. ++ * @return true, if it is in daylight savings time, false otherwise. ++ */ ++ public boolean inDaylightTime(Date date) ++ { ++ long d = date.getTime(); ++ d = (d >= 0 ? d / 1000 : (d + 1) / 1000 - 1); ++ long transition = findTransition(d); ++ ++ // For times on or after last transition use lastRule. ++ if (transition == Long.MAX_VALUE) ++ return lastRule.inDaylightTime(date); ++ ++ return (transition & IS_DST) != 0; ++ } ++ ++ /** ++ * Generates the hashCode for the SimpleDateFormat object. It is ++ * the rawOffset, possibly, if useDaylightSavings is true, xored ++ * with startYear, startMonth, startDayOfWeekInMonth, ..., endTime. ++ */ ++ public synchronized int hashCode() ++ { ++ int hash = lastRule.hashCode(); ++ // FIXME - hash transitions? ++ return hash; ++ } ++ ++ public synchronized boolean equals(Object o) ++ { ++ if (! hasSameRules((TimeZone) o)) ++ return false; ++ ++ ZoneInfo zone = (ZoneInfo) o; ++ return getID().equals(zone.getID()); ++ } ++ ++ /** ++ * Test if the other time zone uses the same rule and only ++ * possibly differs in ID. This implementation for this particular ++ * class will return true if the other object is a ZoneInfo, ++ * the raw offsets and useDaylight are identical and if useDaylight ++ * is true, also the start and end datas are identical. ++ * @return true if this zone uses the same rule. ++ */ ++ public boolean hasSameRules(TimeZone o) ++ { ++ if (this == o) ++ return true; ++ if (! (o instanceof ZoneInfo)) ++ return false; ++ ZoneInfo zone = (ZoneInfo) o; ++ if (zone.hashCode() != hashCode() || rawOffset != zone.rawOffset) ++ return false; ++ if (! lastRule.equals(zone.lastRule)) ++ return false; ++ // FIXME - compare transitions? ++ return true; ++ } ++ ++ /** ++ * Returns a string representation of this ZoneInfo object. ++ * @return a string representation of this ZoneInfo object. ++ */ ++ public String toString() ++ { ++ return getClass().getName() + "[" + "id=" + getID() + ",offset=" ++ + rawOffset + ",transitions=" + transitions.length ++ + ",useDaylight=" + useDaylight ++ + (useDaylight ? (",dstSavings=" + dstSavings) : "") ++ + ",lastRule=" + lastRule.toString() + "]"; ++ } ++ ++ /** ++ * Reads zic(8) compiled timezone data file from file ++ * and returns a TimeZone class describing it, either ++ * SimpleTimeZone or ZoneInfo depending on whether ++ * it can be described by SimpleTimeZone rule or not. ++ */ ++ public static TimeZone readTZFile(String id, String file) ++ { ++ DataInputStream dis = null; ++ try ++ { ++ FileInputStream fis = new FileInputStream(file); ++ BufferedInputStream bis = new BufferedInputStream(fis); ++ dis = new DataInputStream(bis); ++ ++ // Make sure we are reading a tzfile. ++ byte[] tzif = new byte[5]; ++ dis.readFully(tzif); ++ int tzif2 = 4; ++ if (tzif[0] == 'T' && tzif[1] == 'Z' ++ && tzif[2] == 'i' && tzif[3] == 'f') ++ { ++ if (tzif[4] >= '2') ++ tzif2 = 8; ++ // Reserved bytes ++ skipFully(dis, 16 - 1); ++ } ++ else ++ // Darwin has tzdata files that don't start with the TZif marker ++ skipFully(dis, 16 - 5); ++ ++ int ttisgmtcnt = dis.readInt(); ++ int ttisstdcnt = dis.readInt(); ++ int leapcnt = dis.readInt(); ++ int timecnt = dis.readInt(); ++ int typecnt = dis.readInt(); ++ int charcnt = dis.readInt(); ++ if (tzif2 == 8) ++ { ++ skipFully(dis, timecnt * (4 + 1) + typecnt * (4 + 1 + 1) + charcnt ++ + leapcnt * (4 + 4) + ttisgmtcnt + ttisstdcnt); ++ ++ dis.readFully(tzif); ++ if (tzif[0] != 'T' || tzif[1] != 'Z' || tzif[2] != 'i' ++ || tzif[3] != 'f' || tzif[4] < '2') ++ return null; ++ ++ // Reserved bytes ++ skipFully(dis, 16 - 1); ++ ttisgmtcnt = dis.readInt(); ++ ttisstdcnt = dis.readInt(); ++ leapcnt = dis.readInt(); ++ timecnt = dis.readInt(); ++ typecnt = dis.readInt(); ++ charcnt = dis.readInt(); ++ } ++ ++ // Sanity checks ++ if (typecnt <= 0 || timecnt < 0 || charcnt < 0 ++ || leapcnt < 0 || ttisgmtcnt < 0 || ttisstdcnt < 0 ++ || ttisgmtcnt > typecnt || ttisstdcnt > typecnt) ++ return null; ++ ++ // Transition times ++ long[] times = new long[timecnt]; ++ for (int i = 0; i < timecnt; i++) ++ if (tzif2 == 8) ++ times[i] = dis.readLong(); ++ else ++ times[i] = (long) dis.readInt(); ++ ++ // Transition types ++ int[] types = new int[timecnt]; ++ for (int i = 0; i < timecnt; i++) ++ { ++ types[i] = dis.readByte(); ++ if (types[i] < 0) ++ types[i] += 256; ++ if (types[i] >= typecnt) ++ return null; ++ } ++ ++ // Types ++ int[] offsets = new int[typecnt]; ++ int[] typeflags = new int[typecnt]; ++ for (int i = 0; i < typecnt; i++) ++ { ++ offsets[i] = dis.readInt(); ++ if (offsets[i] >= IS_DST / 2 || offsets[i] <= -IS_DST / 2) ++ return null; ++ int dst = dis.readByte(); ++ int abbrind = dis.readByte(); ++ if (abbrind < 0) ++ abbrind += 256; ++ if (abbrind >= charcnt) ++ return null; ++ typeflags[i] = (dst != 0 ? (1 << 8) : 0) + abbrind; ++ } ++ ++ // Abbrev names ++ byte[] names = new byte[charcnt]; ++ dis.readFully(names); ++ ++ // Leap transitions, for now ignore ++ skipFully(dis, leapcnt * (tzif2 + 4) + ttisstdcnt + ttisgmtcnt); ++ ++ // tzIf2 format has optional POSIX TZ env string ++ String tzstr = null; ++ if (tzif2 == 8 && dis.readByte() == '\n') ++ { ++ tzstr = dis.readLine(); ++ if (tzstr.length() <= 0) ++ tzstr = null; ++ } ++ ++ // Get std/dst_offset and dst/non-dst time zone names. ++ int std_ind = -1; ++ int dst_ind = -1; ++ if (timecnt == 0) ++ std_ind = 0; ++ else ++ for (int i = timecnt - 1; i >= 0; i--) ++ { ++ if (std_ind == -1 && (typeflags[types[i]] & (1 << 8)) == 0) ++ std_ind = types[i]; ++ else if (dst_ind == -1 && (typeflags[types[i]] & (1 << 8)) != 0) ++ dst_ind = types[i]; ++ if (dst_ind != -1 && std_ind != -1) ++ break; ++ } ++ ++ if (std_ind == -1) ++ return null; ++ ++ int j = typeflags[std_ind] & 255; ++ while (j < charcnt && names[j] != 0) ++ j++; ++ String std_zonename = new String(names, typeflags[std_ind] & 255, ++ j - (typeflags[std_ind] & 255), ++ "ASCII"); ++ ++ String dst_zonename = ""; ++ if (dst_ind != -1) ++ { ++ j = typeflags[dst_ind] & 255; ++ while (j < charcnt && names[j] != 0) ++ j++; ++ dst_zonename = new String(names, typeflags[dst_ind] & 255, ++ j - (typeflags[dst_ind] & 255), "ASCII"); ++ } ++ ++ // Only use gmt offset when necessary. ++ // Also special case GMT+/- timezones. ++ String std_offset_string = ""; ++ String dst_offset_string = ""; ++ if (tzstr == null ++ && (dst_ind != -1 ++ || (offsets[std_ind] != 0 ++ && !std_zonename.startsWith("GMT+") ++ && !std_zonename.startsWith("GMT-")))) ++ { ++ std_offset_string = Integer.toString(-offsets[std_ind] / 3600); ++ int seconds = -offsets[std_ind] % 3600; ++ if (seconds != 0) ++ { ++ if (seconds < 0) ++ seconds *= -1; ++ if (seconds < 600) ++ std_offset_string += ":0" + Integer.toString(seconds / 60); ++ else ++ std_offset_string += ":" + Integer.toString(seconds / 60); ++ seconds = seconds % 60; ++ if (seconds >= 10) ++ std_offset_string += ":" + Integer.toString(seconds); ++ else if (seconds > 0) ++ std_offset_string += ":0" + Integer.toString(seconds); ++ } ++ ++ if (dst_ind != -1 && offsets[dst_ind] != offsets[std_ind] + 3600) ++ { ++ dst_offset_string = Integer.toString(-offsets[dst_ind] / 3600); ++ seconds = -offsets[dst_ind] % 3600; ++ if (seconds != 0) ++ { ++ if (seconds < 0) ++ seconds *= -1; ++ if (seconds < 600) ++ dst_offset_string ++ += ":0" + Integer.toString(seconds / 60); ++ else ++ dst_offset_string ++ += ":" + Integer.toString(seconds / 60); ++ seconds = seconds % 60; ++ if (seconds >= 10) ++ dst_offset_string += ":" + Integer.toString(seconds); ++ else if (seconds > 0) ++ dst_offset_string += ":0" + Integer.toString(seconds); ++ } ++ } ++ } ++ ++ /* ++ * If no tzIf2 POSIX TZ string is available and the timezone ++ * uses DST, try to guess the last rule by trying to make ++ * sense from transitions at 5 years in the future and onwards. ++ * tzdata actually uses only 3 forms of rules: ++ * fixed date within a month, e.g. change on April, 5th ++ * 1st weekday on or after Nth: change on Sun>=15 in April ++ * last weekday in a month: change on lastSun in April ++ */ ++ String[] change_spec = { null, null }; ++ if (tzstr == null && dst_ind != -1 && timecnt > 10) ++ { ++ long nowPlus5y = System.currentTimeMillis() / 1000 ++ + 5 * 365 * 86400; ++ int first; ++ ++ for (first = timecnt - 1; first >= 0; first--) ++ if (times[first] < nowPlus5y ++ || (types[first] != std_ind && types[first] != dst_ind) ++ || types[first] != types[timecnt - 2 + ((first ^ timecnt) & 1)]) ++ break; ++ first++; ++ ++ if (timecnt - first >= 10 && types[timecnt - 1] != types[timecnt - 2]) ++ { ++ GregorianCalendar cal ++ = new GregorianCalendar(new SimpleTimeZone(0, "GMT")); ++ ++ int[] values = new int[2 * 11]; ++ int i; ++ for (i = timecnt - 1; i >= first; i--) ++ { ++ int base = (i % 2) * 11; ++ int offset = offsets[types[i > first ? i - 1 : i + 1]]; ++ cal.setTime(new Date((times[i] + offset) * 1000)); ++ if (i >= timecnt - 2) ++ { ++ values[base + 0] = cal.get(Calendar.YEAR); ++ values[base + 1] = cal.get(Calendar.MONTH); ++ values[base + 2] = cal.get(Calendar.DAY_OF_MONTH); ++ values[base + 3] ++ = cal.getActualMaximum(Calendar.DAY_OF_MONTH); ++ values[base + 4] = cal.get(Calendar.DAY_OF_WEEK); ++ values[base + 5] = cal.get(Calendar.HOUR_OF_DAY); ++ values[base + 6] = cal.get(Calendar.MINUTE); ++ values[base + 7] = cal.get(Calendar.SECOND); ++ values[base + 8] = values[base + 2]; // Range start ++ values[base + 9] = values[base + 2]; // Range end ++ values[base + 10] = 0; // Determined type ++ } ++ else ++ { ++ int year = cal.get(Calendar.YEAR); ++ int month = cal.get(Calendar.MONTH); ++ int day_of_month = cal.get(Calendar.DAY_OF_MONTH); ++ int month_days ++ = cal.getActualMaximum(Calendar.DAY_OF_MONTH); ++ int day_of_week = cal.get(Calendar.DAY_OF_WEEK); ++ int hour = cal.get(Calendar.HOUR_OF_DAY); ++ int minute = cal.get(Calendar.MINUTE); ++ int second = cal.get(Calendar.SECOND); ++ if (year != values[base + 0] - 1 ++ || month != values[base + 1] ++ || hour != values[base + 5] ++ || minute != values[base + 6] ++ || second != values[base + 7]) ++ break; ++ if (day_of_week == values[base + 4]) ++ { ++ // Either a Sun>=8 or lastSun rule. ++ if (day_of_month < values[base + 8]) ++ values[base + 8] = day_of_month; ++ if (day_of_month > values[base + 9]) ++ values[base + 9] = day_of_month; ++ if (values[base + 10] < 0) ++ break; ++ if (values[base + 10] == 0) ++ { ++ values[base + 10] = 1; ++ // If day of month > 28, this is ++ // certainly lastSun rule. ++ if (values[base + 2] > 28) ++ values[base + 2] = 3; ++ // If day of month isn't in the last ++ // week, it can't be lastSun rule. ++ else if (values[base + 2] ++ <= values[base + 3] - 7) ++ values[base + 3] = 2; ++ } ++ if (values[base + 10] == 1) ++ { ++ // If day of month is > 28, this is ++ // certainly lastSun rule. ++ if (day_of_month > 28) ++ values[base + 10] = 3; ++ // If day of month isn't in the last ++ // week, it can't be lastSun rule. ++ else if (day_of_month <= month_days - 7) ++ values[base + 10] = 2; ++ } ++ else if ((values[base + 10] == 2 ++ && day_of_month > 28) ++ || (values[base + 10] == 3 ++ && day_of_month <= month_days - 7)) ++ break; ++ } ++ else ++ { ++ // Must be fixed day in month rule. ++ if (day_of_month != values[base + 2] ++ || values[base + 10] > 0) ++ break; ++ values[base + 4] = day_of_week; ++ values[base + 10] = -1; ++ } ++ values[base + 0] -= 1; ++ } ++ } ++ ++ if (i < first) ++ { ++ for (i = 0; i < 2; i++) ++ { ++ int base = 11 * i; ++ if (values[base + 10] == 0) ++ continue; ++ if (values[base + 10] == -1) ++ { ++ int[] dayCount ++ = { 0, 31, 59, 90, 120, 151, ++ 181, 212, 243, 273, 304, 334 }; ++ int d = dayCount[values[base + 1] ++ - Calendar.JANUARY]; ++ d += values[base + 2]; ++ change_spec[i] = ",J" + Integer.toString(d); ++ } ++ else if (values[base + 10] == 2) ++ { ++ // If we haven't seen all days of the week, ++ // we can't be sure what the rule really is. ++ if (values[base + 8] + 6 != values[base + 9]) ++ continue; ++ ++ int d; ++ d = values[base + 1] - Calendar.JANUARY + 1; ++ // E.g. Sun >= 5 is not representable in POSIX ++ // TZ env string, use ",Am.n.d" extension ++ // where m is month 1 .. 12, n is the date on ++ // or after which it happens and d is day ++ // of the week, 0 .. 6. So Sun >= 5 in April ++ // is ",A4.5.0". ++ if ((values[base + 8] % 7) == 1) ++ { ++ change_spec[i] = ",M" + Integer.toString(d); ++ d = (values[base + 8] + 6) / 7; ++ } ++ else ++ { ++ change_spec[i] = ",A" + Integer.toString(d); ++ d = values[base + 8]; ++ } ++ change_spec[i] += "." + Integer.toString(d); ++ d = values[base + 4] - Calendar.SUNDAY; ++ change_spec[i] += "." + Integer.toString(d); ++ } ++ else ++ { ++ // If we don't know whether this is lastSun or ++ // Sun >= 22 rule. That can be either because ++ // there was insufficient number of ++ // transitions, or February, where it is quite ++ // probable we haven't seen any 29th dates. ++ // For February, assume lastSun rule, otherwise ++ // punt. ++ if (values[base + 10] == 1 ++ && values[base + 1] != Calendar.FEBRUARY) ++ continue; ++ ++ int d; ++ d = values[base + 1] - Calendar.JANUARY + 1; ++ change_spec[i] = ",M" + Integer.toString(d); ++ d = values[base + 4] - Calendar.SUNDAY; ++ change_spec[i] += ".5." + Integer.toString(d); ++ } ++ ++ // Don't add time specification if time is ++ // 02:00:00. ++ if (values[base + 5] != 2 ++ || values[base + 6] != 0 ++ || values[base + 7] != 0) ++ { ++ int d = values[base + 5]; ++ change_spec[i] += "/" + Integer.toString(d); ++ if (values[base + 6] != 0 || values[base + 7] != 0) ++ { ++ d = values[base + 6]; ++ if (d < 10) ++ change_spec[i] ++ += ":0" + Integer.toString(d); ++ else ++ change_spec[i] += ":" + Integer.toString(d); ++ d = values[base + 7]; ++ if (d >= 10) ++ change_spec[i] ++ += ":" + Integer.toString(d); ++ else if (d > 0) ++ change_spec[i] ++ += ":0" + Integer.toString(d); ++ } ++ } ++ } ++ if (types[(timecnt - 1) & -2] == std_ind) ++ { ++ String tmp = change_spec[0]; ++ change_spec[0] = change_spec[1]; ++ change_spec[1] = tmp; ++ } ++ } ++ } ++ } ++ ++ if (tzstr == null) ++ { ++ tzstr = std_zonename + std_offset_string; ++ if (change_spec[0] != null && change_spec[1] != null) ++ tzstr += dst_zonename + dst_offset_string ++ + change_spec[0] + change_spec[1]; ++ } ++ ++ if (timecnt == 0) ++ return new SimpleTimeZone(offsets[std_ind] * 1000, ++ id != null ? id : tzstr); ++ ++ SimpleTimeZone endRule = createLastRule(tzstr); ++ if (endRule == null) ++ return null; ++ ++ /* Finally adjust the times array into the form the constructor ++ * expects. times[0] is special, the offset and DST flag there ++ * are for all times before that transition. Use the first non-DST ++ * type. For all other transitions, the data file has the type ++ * () for the time interval starting ++ */ ++ for (int i = 0; i < typecnt; i++) ++ if ((typeflags[i] & (1 << 8)) == 0) ++ { ++ times[0] = (times[0] << SECS_SHIFT) | (offsets[i] & OFFSET_MASK); ++ break; ++ } ++ ++ for (int i = 1; i < timecnt; i++) ++ times[i] = (times[i] << SECS_SHIFT) ++ | (offsets[types[i - 1]] & OFFSET_MASK) ++ | ((typeflags[types[i - 1]] & (1 << 8)) != 0 ? IS_DST : 0); ++ ++ return new ZoneInfo(offsets[std_ind] * 1000, id != null ? id : tzstr, ++ times, endRule); ++ } ++ catch (IOException ioe) ++ { ++ // Parse error, not a proper tzfile. ++ return null; ++ } ++ finally ++ { ++ try ++ { ++ if (dis != null) ++ dis.close(); ++ } ++ catch(IOException ioe) ++ { ++ // Error while close, nothing we can do. ++ } ++ } ++ } ++ ++ /** ++ * Skips the requested number of bytes in the given InputStream. ++ * Throws EOFException if not enough bytes could be skipped. ++ * Negative numbers of bytes to skip are ignored. ++ */ ++ private static void skipFully(InputStream is, long l) throws IOException ++ { ++ while (l > 0) ++ { ++ long k = is.skip(l); ++ if (k <= 0) ++ throw new EOFException(); ++ l -= k; ++ } ++ } ++ ++ /** ++ * Create a SimpleTimeZone from a POSIX TZ environment string, ++ * see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html ++ * for details. ++ * It supports also an extension, where Am.n.d rule (m 1 .. 12, n 1 .. 25, d ++ * 0 .. 6) describes day of week d on or after nth day of month m. ++ * Say A4.5.0 is Sun>=5 in April. ++ */ ++ private static SimpleTimeZone createLastRule(String tzstr) ++ { ++ String stdName = null; ++ int stdOffs; ++ int dstOffs; ++ try ++ { ++ int idLength = tzstr.length(); ++ ++ int index = 0; ++ int prevIndex; ++ char c; ++ ++ // get std ++ do ++ c = tzstr.charAt(index); ++ while (c != '+' && c != '-' && c != ',' && c != ':' ++ && ! Character.isDigit(c) && c != '\0' && ++index < idLength); ++ ++ if (index >= idLength) ++ return new SimpleTimeZone(0, tzstr); ++ ++ stdName = tzstr.substring(0, index); ++ prevIndex = index; ++ ++ // get the std offset ++ do ++ c = tzstr.charAt(index++); ++ while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) ++ && index < idLength); ++ if (index < idLength) ++ index--; ++ ++ { // convert the dst string to a millis number ++ String offset = tzstr.substring(prevIndex, index); ++ prevIndex = index; ++ ++ if (offset.charAt(0) == '+' || offset.charAt(0) == '-') ++ stdOffs = parseTime(offset.substring(1)); ++ else ++ stdOffs = parseTime(offset); ++ ++ if (offset.charAt(0) == '-') ++ stdOffs = -stdOffs; ++ ++ // TZ timezone offsets are positive when WEST of the meridian. ++ stdOffs = -stdOffs; ++ } ++ ++ // Done yet? (Format: std offset) ++ if (index >= idLength) ++ return new SimpleTimeZone(stdOffs, stdName); ++ ++ // get dst ++ do ++ c = tzstr.charAt(index); ++ while (c != '+' && c != '-' && c != ',' && c != ':' ++ && ! Character.isDigit(c) && c != '\0' && ++index < idLength); ++ ++ // Done yet? (Format: std offset dst) ++ if (index >= idLength) ++ return new SimpleTimeZone(stdOffs, stdName); ++ ++ // get the dst offset ++ prevIndex = index; ++ do ++ c = tzstr.charAt(index++); ++ while ((c == '-' || c == '+' || c == ':' || Character.isDigit(c)) ++ && index < idLength); ++ if (index < idLength) ++ index--; ++ ++ if (index == prevIndex && (c == ',' || c == ';')) ++ { ++ // Missing dst offset defaults to one hour ahead of standard ++ // time. ++ dstOffs = stdOffs + 60 * 60 * 1000; ++ } ++ else ++ { // convert the dst string to a millis number ++ String offset = tzstr.substring(prevIndex, index); ++ prevIndex = index; ++ ++ if (offset.charAt(0) == '+' || offset.charAt(0) == '-') ++ dstOffs = parseTime(offset.substring(1)); ++ else ++ dstOffs = parseTime(offset); ++ ++ if (offset.charAt(0) == '-') ++ dstOffs = -dstOffs; ++ ++ // TZ timezone offsets are positive when WEST of the meridian. ++ dstOffs = -dstOffs; ++ } ++ ++ // Done yet? (Format: std offset dst offset) ++ if (index >= idLength) ++ return new SimpleTimeZone(stdOffs, stdName); ++ ++ // get the DST rule ++ if (tzstr.charAt(index) == ',' ++ || tzstr.charAt(index) == ';') ++ { ++ index++; ++ int offs = index; ++ while (tzstr.charAt(index) != ',' ++ && tzstr.charAt(index) != ';') ++ index++; ++ String startTime = tzstr.substring(offs, index); ++ index++; ++ String endTime = tzstr.substring(index); ++ ++ index = startTime.indexOf('/'); ++ int startMillis; ++ int endMillis; ++ String startDate; ++ String endDate; ++ if (index != -1) ++ { ++ startDate = startTime.substring(0, index); ++ startMillis = parseTime(startTime.substring(index + 1)); ++ } ++ else ++ { ++ startDate = startTime; ++ // if time isn't given, default to 2:00:00 AM. ++ startMillis = 2 * 60 * 60 * 1000; ++ } ++ index = endTime.indexOf('/'); ++ if (index != -1) ++ { ++ endDate = endTime.substring(0, index); ++ endMillis = parseTime(endTime.substring(index + 1)); ++ } ++ else ++ { ++ endDate = endTime; ++ // if time isn't given, default to 2:00:00 AM. ++ endMillis = 2 * 60 * 60 * 1000; ++ } ++ ++ int[] start = getDateParams(startDate); ++ int[] end = getDateParams(endDate); ++ return new SimpleTimeZone(stdOffs, tzstr, start[0], start[1], ++ start[2], startMillis, end[0], end[1], ++ end[2], endMillis, (dstOffs - stdOffs)); ++ } ++ } ++ ++ catch (IndexOutOfBoundsException _) ++ { ++ } ++ catch (NumberFormatException _) ++ { ++ } ++ ++ return null; ++ } ++ ++ /** ++ * Parses and returns the params for a POSIX TZ date field, ++ * in the format int[]{ month, day, dayOfWeek }, following the ++ * SimpleTimeZone constructor rules. ++ */ ++ private static int[] getDateParams(String date) ++ { ++ int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; ++ int month; ++ int type = 0; ++ ++ if (date.charAt(0) == 'M' || date.charAt(0) == 'm') ++ type = 1; ++ else if (date.charAt(0) == 'A' || date.charAt(0) == 'a') ++ type = 2; ++ ++ if (type > 0) ++ { ++ int day; ++ ++ // Month, week of month, day of week ++ // "Mm.w.d". d is between 0 (Sunday) and 6. Week w is ++ // between 1 and 5; Week 1 is the first week in which day d ++ // occurs and Week 5 specifies the last d day in the month. ++ // Month m is between 1 and 12. ++ ++ // Month, day of month, day of week ++ // ZoneInfo extension, not in POSIX ++ // "Am.n.d". d is between 0 (Sunday) and 6. Day of month n is ++ // between 1 and 25. Month m is between 1 and 12. ++ ++ month = Integer.parseInt(date.substring(1, date.indexOf('.'))); ++ int week = Integer.parseInt(date.substring(date.indexOf('.') + 1, ++ date.lastIndexOf('.'))); ++ int dayOfWeek = Integer.parseInt(date.substring(date.lastIndexOf('.') ++ + 1)); ++ dayOfWeek++; // Java day of week is one-based, Sunday is first day. ++ ++ if (type == 2) ++ { ++ day = week; ++ dayOfWeek = -dayOfWeek; ++ } ++ else if (week == 5) ++ day = -1; // last day of month is -1 in java, 5 in TZ ++ else ++ { ++ // First day of week starting on or after. For example, ++ // to specify the second Sunday of April, set month to ++ // APRIL, day-of-month to 8, and day-of-week to -SUNDAY. ++ day = (week - 1) * 7 + 1; ++ dayOfWeek = -dayOfWeek; ++ } ++ ++ month--; // Java month is zero-based. ++ return new int[] { month, day, dayOfWeek }; ++ } ++ ++ // julian day, either zero-based 0<=n<=365 (incl feb 29) ++ // or one-based 1<=n<=365 (no feb 29) ++ int julianDay; // Julian day ++ ++ if (date.charAt(0) != 'J' || date.charAt(0) != 'j') ++ { ++ julianDay = Integer.parseInt(date.substring(1)); ++ julianDay++; // make 1-based ++ // Adjust day count to include feb 29. ++ dayCount = new int[] ++ { ++ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 ++ }; ++ } ++ else ++ // 1-based julian day ++ julianDay = Integer.parseInt(date); ++ ++ int i = 11; ++ while (i > 0) ++ if (dayCount[i] < julianDay) ++ break; ++ else ++ i--; ++ julianDay -= dayCount[i]; ++ month = i; ++ return new int[] { month, julianDay, 0 }; ++ } ++ ++ /** ++ * Parses a time field hh[:mm[:ss]], returning the result ++ * in milliseconds. No leading sign. ++ */ ++ private static int parseTime(String time) ++ { ++ int millis = 0; ++ int i = 0; ++ ++ while (i < time.length()) ++ if (time.charAt(i) == ':') ++ break; ++ else ++ i++; ++ millis = 60 * 60 * 1000 * Integer.parseInt(time.substring(0, i)); ++ if (i >= time.length()) ++ return millis; ++ ++ int iprev = ++i; ++ while (i < time.length()) ++ if (time.charAt(i) == ':') ++ break; ++ else ++ i++; ++ millis += 60 * 1000 * Integer.parseInt(time.substring(iprev, i)); ++ if (i >= time.length()) ++ return millis; ++ ++ millis += 1000 * Integer.parseInt(time.substring(++i)); ++ return millis; ++ } ++} diff --git a/SOURCES/gcc32-libgcc_eh-hidden.patch b/SOURCES/gcc32-libgcc_eh-hidden.patch new file mode 100644 index 0000000..eafd7da --- /dev/null +++ b/SOURCES/gcc32-libgcc_eh-hidden.patch @@ -0,0 +1,29 @@ +--- gcc/mklibgcc.in.jj 2006-05-22 14:03:31.000000000 -0400 ++++ gcc/mklibgcc.in 2006-05-22 14:03:31.000000000 -0400 +@@ -310,10 +310,24 @@ for ml in $MULTILIBS; do + + if [ "$SHLIB_LINK" ]; then + ++ if [ "@libgcc_visibility@" = yes ]; then ++ libgcc_eh_objS= ++ echo "" ++ for o in $libgcc_eh_objs; do ++ # .oS objects will have all non-local symbol definitions .hidden ++ oS=`echo ${o} | sed s~${objext}'$~.oS~g'` ++ echo "${oS}: stmp-dirs libgcc/${dir}/stacknote.s ${o}" ++ echo ' @( $(NM_FOR_TARGET) '${SHLIB_NM_FLAGS} ${o}' | $(AWK) '\''NF == 3 { print "\t.hidden", $$3 }'\''; cat libgcc/${dir}/stacknote.s ) | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -r -nostdinc -nostdlib -o $@ '${o}' -xassembler -' ++ libgcc_eh_objS="${libgcc_eh_objS} ${oS}" ++ done ++ else ++ libgcc_eh_objS="$libgcc_eh_objs" ++ fi ++ + echo "" +- echo "${dir}/libgcc_eh.a: $libgcc_eh_objs" ++ echo "${dir}/libgcc_eh.a: $libgcc_eh_objS" + echo " -rm -rf ${dir}/libgcc_eh.a" +- echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_objs ++ echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_objS + echo ' if $(RANLIB_TEST_FOR_TARGET) ; then' \\ + echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc_eh.a ';' \\ + echo ' else true; fi;' diff --git a/SOURCES/gcc32-libjava-jar-timestamps.patch b/SOURCES/gcc32-libjava-jar-timestamps.patch new file mode 100644 index 0000000..5a00838 --- /dev/null +++ b/SOURCES/gcc32-libjava-jar-timestamps.patch @@ -0,0 +1,78 @@ +2004-08-12 Jakub Jelinek + + * Makefile.am (libgcj-@gcc_version@.jar): Set timestamp of all files + and directories in the jar file to the youngest of gcc/ChangeLog, + gcc/java/ChangeLog and libjava/ChangeLog. Sort the file/directory + list before passing it to fastjar. + * Makefile.in: Rebuilt. + +--- libjava/Makefile.am 2003-02-03 23:58:32.000000000 +0100 ++++ libjava/Makefile.am 2004-08-12 13:21:35.928177346 +0200 +@@ -170,9 +170,29 @@ all_java_class_files = $(all_java_source + libgcj-@gcc_version@.jar: $(all_java_class_files) + -@rm -f libgcj-@gcc_version@.jar + ## Note that we explicitly want to include directory information. +- find java gnu javax org -type d -o -type f -name '*.class' | \ +- sed -e '/\/\./d' -e '/\/xlib/d' | \ +- $(ZIP) cfM0E@ $@ ++ # The following is an attempt to have libgcj-*.jar files ++ # from the same GCC version identical accross the architectures. ++ JARDIR=`mktemp -d ../$@.XXXXXX` || exit 1; \ ++ for d in `find java gnu javax org -type d \ ++ | sed -e '/\/\./d' -e '/\/xlib/d'`; do \ ++ mkdir -p $$JARDIR/$$d; \ ++ done; \ ++ touch -r $(srcdir)/../gcc/ChangeLog $$JARDIR.stamp; \ ++ [ $(srcdir)/../gcc/java/ChangeLog -nt $$JARDIR.stamp ] \ ++ && touch -r $(srcdir)/../gcc/java/ChangeLog $$JARDIR.stamp; \ ++ [ $(srcdir)/ChangeLog -nt $$JARDIR.stamp ] \ ++ && touch -r $(srcdir)/ChangeLog $$JARDIR.stamp; \ ++ for f in `find java gnu javax org -type f -name '*.class' \ ++ | sed -e '/\/\./d' -e '/\/xlib/d'`; do \ ++ cp $$f $$JARDIR/$$f; \ ++ touch -r $$JARDIR.stamp $$JARDIR/$$f; \ ++ done; \ ++ touch -r $$JARDIR.stamp `find $$JARDIR -type d`; \ ++ cd $$JARDIR; \ ++ find java gnu javax org -type d -o -type f | \ ++ LC_ALL=C sort | $(ZIP) cfM0E@ ../libjava/$@ || exit 1; \ ++ cd -; \ ++ rm -rf $$JARDIR $$JARDIR.stamp + + MOSTLYCLEANFILES = $(javao_files) $(nat_files) $(nat_headers) $(c_files) $(x_javao_files) $(x_nat_files) $(x_nat_headers) + CLEANFILES = libgcj-@gcc_version@.jar +--- libjava/Makefile.in 2003-02-03 23:58:32.000000000 +0100 ++++ libjava/Makefile.in 2004-08-12 13:21:22.928440630 +0200 +@@ -3280,9 +3280,29 @@ install-exec-hook: + + libgcj-@gcc_version@.jar: $(all_java_class_files) + -@rm -f libgcj-@gcc_version@.jar +- find java gnu javax org -type d -o -type f -name '*.class' | \ +- sed -e '/\/\./d' -e '/\/xlib/d' | \ +- $(ZIP) cfM0E@ $@ ++ # The following is an attempt to have libgcj-*.jar files ++ # from the same GCC version identical accross the architectures. ++ JARDIR=`mktemp -d ../$@.XXXXXX` || exit 1; \ ++ for d in `find java gnu javax org -type d \ ++ | sed -e '/\/\./d' -e '/\/xlib/d'`; do \ ++ mkdir -p $$JARDIR/$$d; \ ++ done; \ ++ touch -r $(srcdir)/../gcc/ChangeLog $$JARDIR.stamp; \ ++ [ $(srcdir)/../gcc/java/ChangeLog -nt $$JARDIR.stamp ] \ ++ && touch -r $(srcdir)/../gcc/java/ChangeLog $$JARDIR.stamp; \ ++ [ $(srcdir)/ChangeLog -nt $$JARDIR.stamp ] \ ++ && touch -r $(srcdir)/ChangeLog $$JARDIR.stamp; \ ++ for f in `find java gnu javax org -type f -name '*.class' \ ++ | sed -e '/\/\./d' -e '/\/xlib/d'`; do \ ++ cp $$f $$JARDIR/$$f; \ ++ touch -r $$JARDIR.stamp $$JARDIR/$$f; \ ++ done; \ ++ touch -r $$JARDIR.stamp `find $$JARDIR -type d`; \ ++ cd $$JARDIR; \ ++ find java gnu javax org -type d -o -type f | \ ++ LC_ALL=C sort | $(ZIP) cfM0E@ ../libjava/$@ || exit 1; \ ++ cd -; \ ++ rm -rf $$JARDIR $$JARDIR.stamp + + clean-local: + find . -name '*.class' -print | xargs rm -f diff --git a/SOURCES/gcc32-libstdc++-fully-dynamic-strings.patch b/SOURCES/gcc32-libstdc++-fully-dynamic-strings.patch new file mode 100644 index 0000000..32cd729 --- /dev/null +++ b/SOURCES/gcc32-libstdc++-fully-dynamic-strings.patch @@ -0,0 +1,60 @@ +2004-10-28 Paolo Carlini + + PR libstdc++/16612 + * include/bits/basic_string.h (basic_string()): When + _GLIBCXX_FULLY_DYNAMIC_STRING is defined, don't deal with _S_empty_rep. + * include/bits/basic_string.tcc (_S_construct): Likewise. + +--- libstdc++-v3/include/bits/basic_string.tcc.jj 2002-11-09 18:42:55.000000000 +0100 ++++ libstdc++-v3/include/bits/basic_string.tcc 2004-11-12 14:17:19.946131774 +0100 +@@ -77,8 +77,10 @@ namespace std + _S_construct(_InIter __beg, _InIter __end, const _Alloc& __a, + input_iterator_tag) + { ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); ++#endif + // Avoid reallocation for common case. + _CharT __buf[100]; + size_type __i = 0; +@@ -139,11 +141,13 @@ namespace std + { + size_type __dnew = static_cast(distance(__beg, __end)); + ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__beg == __end && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); ++#endif + + // NB: Not required, but considered best practice. +- if (__builtin_expect(__beg == _InIter(), 0)) ++ if (__builtin_expect(__beg == _InIter() && __beg != __end, 0)) + __throw_logic_error("attempt to create string with null pointer"); + + // Check for out_of_range and length_error exceptions. +@@ -166,8 +170,10 @@ namespace std + basic_string<_CharT, _Traits, _Alloc>:: + _S_construct(size_type __n, _CharT __c, const _Alloc& __a) + { ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + if (__n == 0 && __a == _Alloc()) + return _S_empty_rep()._M_refcopy(); ++#endif + + // Check for out_of_range and length_error exceptions. + _Rep* __r = _Rep::_S_create(__n, __a); +--- libstdc++-v3/include/bits/basic_string.h.jj 2002-05-22 15:39:29.000000000 +0200 ++++ libstdc++-v3/include/bits/basic_string.h 2004-11-12 14:14:42.831975711 +0100 +@@ -923,7 +923,11 @@ namespace std + template + inline basic_string<_CharT, _Traits, _Alloc>:: + basic_string() ++#ifndef _GLIBCXX_FULLY_DYNAMIC_STRING + : _M_dataplus(_S_empty_rep()._M_refcopy(), _Alloc()) { } ++#else ++ : _M_dataplus(_S_construct(size_type(), _CharT(), _Alloc()), _Alloc()) { } ++#endif + + // operator+ + template diff --git a/SOURCES/gcc32-libstdc++-limits.patch b/SOURCES/gcc32-libstdc++-limits.patch new file mode 100644 index 0000000..62fc602 --- /dev/null +++ b/SOURCES/gcc32-libstdc++-limits.patch @@ -0,0 +1,163 @@ +2004-10-06 Jakub Jelinek + + * config/os/gnu-linux/bits/os_defines.h: Define + __glibcpp_{float,double,long_double}* macros. + * config/cpu/x86-64/bits/cpu_limits.h (__glibcpp_long_bits): Only + define to 64 if __x86_64__. + * include/std/std_limits.h (__glibcpp_f*_round_error): Only define + if not yet defined. + +--- libstdc++-v3/config/os/gnu-linux/bits/os_defines.h.jj 2002-06-03 17:33:17.000000000 +0200 ++++ libstdc++-v3/config/os/gnu-linux/bits/os_defines.h 2004-10-06 20:07:16.601101686 +0200 +@@ -73,4 +73,87 @@ typedef __loff_t __off64_t; + #define __glibcpp_long_double_bits 64 + #endif + ++/* RHEL3 hack. */ ++#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__IBMCPP__) \ ++ && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__) \ ++ || defined(__s390__) || defined(__s390x__) || defined(__powerpc__) \ ++ || defined(__powerpc64__)) ++#define __glibcpp_float_has_quiet_NaN true ++#define __glibcpp_float_has_signaling_NaN true ++#define __glibcpp_float_has_denorm denorm_present ++#define __glibcpp_float_has_infinity true ++#define __glibcpp_float_round_style round_to_nearest ++#define __glibcpp_float_is_iec559 true ++#define __glibcpp_double_has_quiet_NaN true ++#define __glibcpp_double_has_signaling_NaN true ++#define __glibcpp_double_has_denorm denorm_present ++#define __glibcpp_double_has_infinity true ++#define __glibcpp_double_round_style round_to_nearest ++#define __glibcpp_double_is_iec559 true ++#define __glibcpp_long_double_has_quiet_NaN true ++#define __glibcpp_long_double_has_signaling_NaN true ++#define __glibcpp_long_double_has_denorm denorm_present ++#define __glibcpp_long_double_has_infinity true ++#define __glibcpp_long_double_round_style round_to_nearest ++#define __glibcpp_long_double_is_iec559 true ++ ++#define __glibcpp_f32_round_error 0.5F ++#define __glibcpp_f64_round_error 0.5 ++#define __glibcpp_f80_round_error 0.5L ++#define __glibcpp_f96_round_error 0.5L ++#define __glibcpp_f128_round_error 0.5L ++ ++#define __glibcpp_float_infinity 1.0e+40F ++#define __glibcpp_double_infinity 1.0e+320 ++#define __glibcpp_long_double_infinity 1.0e+5000L ++ ++#define __glibcpp_float_denorm_min 1.40129846e-45F ++#define __glibcpp_double_denorm_min 4.9406564584124654e-324 ++ ++#define __glibcpp_float_quiet_NaN \ ++ (__extension__ ((union { unsigned int __l; float __d; }) \ ++ { __l: 0x7fc00000 }).__d) ++#define __glibcpp_double_quiet_NaN \ ++ (__extension__ ((union { unsigned long long __l; double __d; }) \ ++ { __l: 0x7ff8000000000000ULL }).__d) ++ ++#define __glibcpp_float_signaling_NaN \ ++ (__extension__ ({ union { unsigned int __l; float __d; } __u; \ ++ __u.__l = 0x7fa00000; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++#define __glibcpp_double_signaling_NaN \ ++ (__extension__ ({ union { unsigned long long __l; double __d; } __u; \ ++ __u.__l = 0x7ff4000000000000ULL; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++ ++#if __glibcpp_long_double_bits == 80 ++ ++#define __glibcpp_long_double_denorm_min 3.64519953188247460253e-4951L ++#define __glibcpp_long_double_quiet_NaN \ ++ (__extension__ ({ union { unsigned long long __l[2]; \ ++ long double __d; } __u; \ ++ __u.__l[0] = 0xcULL << 60; __u.__l[1] = 0x7fff; \ ++ __u.__d; })) ++#define __glibcpp_long_double_signaling_NaN \ ++ (__extension__ ({ union { unsigned long long __l[2]; \ ++ long double __d; } __u; \ ++ __u.__l[0] = 0xaULL << 60; __u.__l[1] = 0x7fff; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++ ++#else ++ ++#define __glibcpp_long_double_denorm_min 4.9406564584124654e-324L ++#define __glibcpp_long_double_quiet_NaN \ ++ (__extension__ ((union { unsigned long long __l; long double __d; }) \ ++ { __l: 0x7ff8000000000000ULL }).__d) ++#define __glibcpp_long_double_signaling_NaN \ ++ (__extension__ ({ union { unsigned long long __l; \ ++ long double __d; } __u; \ ++ __u.__l = 0x7ff4000000000000ULL; \ ++ __asm ("" : : "r" (&__u) : "memory"); __u.__d; })) ++ ++#endif ++ ++#endif ++ + #endif +--- libstdc++-v3/config/cpu/x86-64/bits/cpu_limits.h.jj 2002-01-12 23:14:42.000000000 +0100 ++++ libstdc++-v3/config/cpu/x86-64/bits/cpu_limits.h 2004-10-06 17:13:39.369189090 +0200 +@@ -28,7 +28,9 @@ + #ifndef _GLIBCPP_CPU_LIMITS + #define _GLIBCPP_CPU_LIMITS 1 + ++#ifdef __x86_64__ + #define __glibcpp_long_bits 64 ++#endif + + #define __glibcpp_long_double_bits 80 + +--- libstdc++-v3/include/std/std_limits.h.jj 2002-10-16 16:12:23.000000000 +0200 ++++ libstdc++-v3/include/std/std_limits.h 2004-10-06 19:59:26.602318867 +0200 +@@ -180,7 +180,9 @@ + #define __glibcpp_f32_digits10 6 + #define __glibcpp_f32_radix 2 + #define __glibcpp_f32_epsilon 1.19209290e-07F ++#ifndef __glibcpp_f32_round_error + #define __glibcpp_f32_round_error 1.0F ++#endif + #define __glibcpp_f32_min_exponent -125 + #define __glibcpp_f32_min_exponent10 -37 + #define __glibcpp_f32_max_exponent 128 +@@ -191,7 +193,9 @@ + #define __glibcpp_f64_digits10 15 + #define __glibcpp_f64_radix 2 + #define __glibcpp_f64_epsilon 2.2204460492503131e-16 ++#ifndef __glibcpp_f64_round_error + #define __glibcpp_f64_round_error 1.0 ++#endif + #define __glibcpp_f64_min_exponent -1021 + #define __glibcpp_f64_min_exponent10 -307 + #define __glibcpp_f64_max_exponent 1024 +@@ -202,7 +206,9 @@ + #define __glibcpp_f80_digits10 18 + #define __glibcpp_f80_radix 2 + #define __glibcpp_f80_epsilon 1.08420217248550443401e-19L ++#ifndef __glibcpp_f80_round_error + #define __glibcpp_f80_round_error 1.0L ++#endif + #define __glibcpp_f80_min_exponent -16381 + #define __glibcpp_f80_min_exponent10 -4931 + #define __glibcpp_f80_max_exponent 16384 +@@ -213,7 +219,9 @@ + #define __glibcpp_f96_digits10 18 + #define __glibcpp_f96_radix 2 + #define __glibcpp_f96_epsilon 1.08420217248550443401e-19L ++#ifndef __glibcpp_f96_round_error + #define __glibcpp_f96_round_error 1.0L ++#endif + #define __glibcpp_f96_min_exponent -16382 + #define __glibcpp_f96_min_exponent10 -4931 + #define __glibcpp_f96_max_exponent 16384 +@@ -224,7 +232,9 @@ + #define __glibcpp_f128_digits10 33 + #define __glibcpp_f128_radix 2 + #define __glibcpp_f128_epsilon 1.925929944387235853055977942584927319E-34L ++#ifndef __glibcpp_f128_round_error + #define __glibcpp_f128_round_error 1.0L ++#endif + #define __glibcpp_f128_min_exponent -16381 + #define __glibcpp_f128_min_exponent10 -4931 + #define __glibcpp_f128_max_exponent 16384 diff --git a/SOURCES/gcc32-libstdc++-pr9659.patch b/SOURCES/gcc32-libstdc++-pr9659.patch new file mode 100644 index 0000000..b8b452f --- /dev/null +++ b/SOURCES/gcc32-libstdc++-pr9659.patch @@ -0,0 +1,24 @@ +2003-02-11 Scott Snyder + + PR libstdc++/9659 + * include/bits/fstream.tcc (seekoff): Avoid operator+ + for pos_type. + +--- libstdc++-v3/include/bits/fstream.tcc 4 Feb 2003 22:42:32 -0000 1.47 ++++ libstdc++-v3/include/bits/fstream.tcc 13 Feb 2003 21:39:02 -0000 1.48 +@@ -450,9 +450,12 @@ namespace std + pos_type __tmp = + _M_file.seekoff(__off, ios_base::cur, __mode); + if (__tmp >= 0) +- // Seek successful. +- __ret = __tmp + +- std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos; ++ { ++ // Seek successful. ++ __ret = __tmp; ++ __ret += ++ std::max(this->_M_out_cur, this->_M_in_cur) - _M_filepos; ++ } + } + } + _M_last_overflowed = false; diff --git a/SOURCES/gcc32-libstdc++-symver.patch b/SOURCES/gcc32-libstdc++-symver.patch new file mode 100644 index 0000000..60ecc32 --- /dev/null +++ b/SOURCES/gcc32-libstdc++-symver.patch @@ -0,0 +1,98 @@ +2004-07-13 Jakub Jelinek + + * acinclude.m4 (glibcxx_shared_libgcc): Correct + glibcxx_shared_libgcc test for multilibs. + * aclocal.m4: Rebuilt. + * configure: Rebuilt. + +--- libstdc++-v3/acinclude.m4.jj 2003-01-28 10:51:32.000000000 +0100 ++++ libstdc++-v3/acinclude.m4 2004-08-12 14:54:01.657789664 +0200 +@@ -2208,6 +2208,23 @@ ac_save_CFLAGS="$CFLAGS" + CFLAGS=' -lgcc_s' + AC_TRY_LINK( , [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no) + CFLAGS="$ac_save_CFLAGS" ++if test $glibcpp_shared_libgcc = no; then ++ cat > conftest.c <&1 >/dev/null \ ++ | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'` ++changequote([,])dnl ++ rm -f conftest.c conftest.so ++ if test x${glibcpp_libgcc_s_suffix+set} = xset; then ++ CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix" ++ AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes) ++ CFLAGS="$ac_save_CFLAGS" ++ fi ++fi + AC_MSG_RESULT($glibcpp_shared_libgcc) + + # For GNU ld, we need at least this version. It's 2.12 in the same format +--- libstdc++-v3/aclocal.m4.jj 2003-02-14 09:30:26.000000000 +0100 ++++ libstdc++-v3/aclocal.m4 2004-08-12 14:57:06.460552615 +0200 +@@ -2220,6 +2220,23 @@ ac_save_CFLAGS="$CFLAGS" + CFLAGS=' -lgcc_s' + AC_TRY_LINK( , [return 0], glibcpp_shared_libgcc=yes, glibcpp_shared_libgcc=no) + CFLAGS="$ac_save_CFLAGS" ++if test $glibcpp_shared_libgcc = no; then ++ cat > conftest.c <&1 >/dev/null \ ++ | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'` ++changequote([,])dnl ++ rm -f conftest.c conftest.so ++ if test x${glibcpp_libgcc_s_suffix+set} = xset; then ++ CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix" ++ AC_TRY_LINK(, [return 0;], glibcpp_shared_libgcc=yes) ++ CFLAGS="$ac_save_CFLAGS" ++ fi ++fi + AC_MSG_RESULT($glibcpp_shared_libgcc) + + # For GNU ld, we need at least this version. It's 2.12 in the same format +--- libstdc++-v3/configure.jj 2003-02-14 09:30:58.000000000 +0100 ++++ libstdc++-v3/configure 2004-08-12 14:57:49.978961900 +0200 +@@ -22090,6 +22090,36 @@ else + fi + rm -f conftest* + CFLAGS="$ac_save_CFLAGS" ++if test $glibcpp_shared_libgcc = no; then ++ cat > conftest.c <&1 >/dev/null \ ++ | sed -n 's/^.* -lgcc_s\([^ ]*\) .*$/\1/p'` ++ rm -f conftest.c conftest.so ++ if test x${glibcpp_libgcc_s_suffix+set} = xset; then ++ CFLAGS=" -lgcc_s$glibcpp_libgcc_s_suffix" ++ cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ++ rm -rf conftest* ++ glibcpp_shared_libgcc=yes ++else ++ echo "configure: failed program was:" >&5 ++ cat conftest.$ac_ext >&5 ++fi ++rm -f conftest* ++ CFLAGS="$ac_save_CFLAGS" ++ fi ++fi + echo "$ac_t""$glibcpp_shared_libgcc" 1>&6 + + # For GNU ld, we need at least this version. It's 2.12 in the same format diff --git a/SOURCES/gcc32-libstdc++-symver2.patch b/SOURCES/gcc32-libstdc++-symver2.patch new file mode 100644 index 0000000..ba0430b --- /dev/null +++ b/SOURCES/gcc32-libstdc++-symver2.patch @@ -0,0 +1,36 @@ +2005-05-13 Jakub Jelinek + + * src/globals.cc (_GLIBCPP_ASM_SYMVER): For non-PIC, redefine to a + hidden alias. + * src/locale.cc (_GLIBCPP_ASM_SYMVER): Likewise. + +--- libstdc++-v3/src/globals.cc.jj 2002-10-23 01:24:11.000000000 +0200 ++++ libstdc++-v3/src/globals.cc 2005-05-13 12:30:26.000000000 +0200 +@@ -33,6 +33,12 @@ + #include + #include + ++#ifndef PIC ++# undef _GLIBCPP_ASM_SYMVER ++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \ ++ asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur); ++#endif ++ + // On AIX, and perhaps other systems, library initialization order is + // not guaranteed. For example, the static initializers for the main + // program might run before the static initializers for this library. +--- libstdc++-v3/src/locale.cc.jj 2003-01-17 18:44:45.000000000 +0100 ++++ libstdc++-v3/src/locale.cc 2005-05-13 13:02:36.000000000 +0200 +@@ -34,6 +34,12 @@ + #include + #include + ++#ifndef PIC ++# undef _GLIBCPP_ASM_SYMVER ++# define _GLIBCPP_ASM_SYMVER(cur, old, version) \ ++ asm (".globl " #old "\n\t.hidden " #old "\n\t.set " #old "," #cur); ++#endif ++ + namespace __gnu_cxx + { + // Defined in globals.cc. diff --git a/SOURCES/gcc32-multi32-hack.patch b/SOURCES/gcc32-multi32-hack.patch new file mode 100644 index 0000000..488839c --- /dev/null +++ b/SOURCES/gcc32-multi32-hack.patch @@ -0,0 +1,76 @@ +This is an optimization hack which should only be present +in a sparc 32bit driver of the compiler compiled with +host/target/build sparc64-redhat-linux --with-cpu=v7. +As long long HOST_WIDE_INT slows things down, we can have in +addition to the sparc64-*/3.2/{cc1,cc1plus} +sparc-*/3.2/{cc1,cc1plus} binaries which are suitable for compiling +-m32 code only, but use long HOST_WIDE_INT. + +--- gcc/gcc.c.jj Thu Aug 1 17:41:31 2002 ++++ gcc/gcc.c Fri Sep 6 16:48:10 2002 +@@ -3184,6 +3184,8 @@ process_command (argc, argv) + int have_c = 0; + int have_o = 0; + int lang_n_infiles = 0; ++ int m64 = 0; ++ int used_B = 0; + #ifdef MODIFY_TARGET_NAME + int is_modify_target_name; + int j; +@@ -3565,6 +3567,7 @@ warranty; not even for MERCHANTABILITY o + spec_machine = p + 1; + + warn_std_ptr = &warn_std; ++ used_B = 1; + break; + + case 'B': +@@ -3627,6 +3630,7 @@ warranty; not even for MERCHANTABILITY o + PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0); + add_prefix (&include_prefixes, concat (value, "include", NULL), + NULL, PREFIX_PRIORITY_B_OPT, 0, NULL, 0); ++ used_B = 1; + n_switches++; + } + break; +@@ -3731,6 +3735,13 @@ warranty; not even for MERCHANTABILITY o + #endif + goto normal_switch; + ++ /* HACK START */ ++ case 'm': ++ if (p[1] == '6' && p[2] == '4') ++ m64 = 1; ++ /* FALLTHROUGH */ ++ /* HACK END */ ++ + default: + normal_switch: + +@@ -3798,6 +3809,26 @@ warranty; not even for MERCHANTABILITY o + /* Use 2 as fourth arg meaning try just the machine as a suffix, + as well as trying the machine and the version. */ + #ifndef OS2 ++ /* HACK START */ ++ if (!m64 && !used_B && !strncmp (spec_machine, "sparc64-", 8)) ++ { ++ const char *sparc32_exec_prefix = ++ concat (standard_exec_prefix, "sparc-", spec_machine + 8, ++ dir_separator_str, spec_version, dir_separator_str, NULL); ++ add_prefix (&exec_prefixes, sparc32_exec_prefix, "GCC", ++ PREFIX_PRIORITY_LAST, 0, warn_std_ptr, 0); ++ } ++ /* HACK END */ ++ /* HACK START */ ++ if (!m64 && !used_B && !strncmp (spec_machine, "ppc64-", 6)) ++ { ++ const char *ppc32_exec_prefix = ++ concat (standard_exec_prefix, "ppc-", spec_machine + 6, ++ dir_separator_str, spec_version, dir_separator_str, NULL); ++ add_prefix (&exec_prefixes, ppc32_exec_prefix, "GCC", ++ PREFIX_PRIORITY_LAST, 0, warn_std_ptr, 0); ++ } ++ /* HACK END */ + add_prefix (&exec_prefixes, standard_exec_prefix, "GCC", + PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0); + add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS", diff --git a/SOURCES/gcc32-null-pointer-check-noncc0.patch b/SOURCES/gcc32-null-pointer-check-noncc0.patch new file mode 100644 index 0000000..bd4bf8d --- /dev/null +++ b/SOURCES/gcc32-null-pointer-check-noncc0.patch @@ -0,0 +1,67 @@ +2004-02-26 Alan Modra + + PR rtl-optimization/14279 + * gcse.c (delete_null_pointer_checks_1): Do not delete CC setter + unless HAVE_cc0. + +2004-12-22 Jakub Jelinek + + * gcc.c-torture/execute/20041222-1.c: New test. + +--- gcc/gcse.c.jj 2003-03-10 17:42:09.000000000 +0100 ++++ gcc/gcse.c 2004-12-22 12:03:32.272762070 +0100 +@@ -5428,8 +5428,10 @@ delete_null_pointer_checks_1 (block_reg, + } + + delete_insn (last_insn); ++#ifdef HAVE_cc0 + if (compare_and_branch == 2) + delete_insn (earliest); ++#endif + purge_dead_edges (BASIC_BLOCK (bb)); + + /* Don't check this block again. (Note that BLOCK_END is +--- gcc/testsuite/gcc.c-torture/execute/20041222-1.c.jj 2004-12-22 12:07:50.446611220 +0100 ++++ gcc/testsuite/gcc.c-torture/execute/20041222-1.c 2004-12-22 11:34:45.000000000 +0100 +@@ -0,0 +1,41 @@ ++extern void abort (void); ++extern void exit (int); ++ ++struct S ++{ ++ void *a; ++ unsigned int b; ++}; ++ ++void ++__attribute__((noinline)) ++bar (struct S *x) ++{ ++ if (x->b != 2) ++ abort (); ++} ++ ++void ++__attribute__((noinline)) ++foo (struct S *x) ++{ ++ if (! x->a) ++ { ++ struct S *y, *z; ++ y = x; ++ if (y) ++ ++y->b; ++ z = x; ++ if (z) ++ ++z->b; ++ bar (x); ++ } ++} ++ ++int ++main (void) ++{ ++ struct S s = { 0, 0 }; ++ foo (&s); ++ exit (0); ++} diff --git a/SOURCES/gcc32-obstack-lvalues.patch b/SOURCES/gcc32-obstack-lvalues.patch new file mode 100644 index 0000000..0374687 --- /dev/null +++ b/SOURCES/gcc32-obstack-lvalues.patch @@ -0,0 +1,114 @@ +2003-10-22 Joseph S. Myers + + * obstack.h: Merge the following change from gnulib: + 2003-10-21 Paul Eggert + * obstack.h (obstack_1grow_fast): Properly parenthesize arg. + (obstack_ptr_grow_fast, obstack_int_grow_fast): + Don't use lvalue casts, as GCC plans to remove support for them + in GCC 3.5. Reported by Joseph S. Myers. This bug + was also present in the non-GCC version, indicating that this + code had always been buggy and had never been widely used. + (obstack_1grow, obstack_ptr_grow, obstack_int_grow, obstack_blank): + Use the fast variant of each macro, rather than copying the + definiens of the fast variant; that way, we'll be more likely to + catch future bugs in the fast variants. + +--- include/obstack.h 14 Mar 2001 19:44:38 -0000 1.5 ++++ include/obstack.h 22 Oct 2003 22:28:20 -0000 1.6 +@@ -343,7 +343,7 @@ extern int obstack_exit_failure; + + #endif + +-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) ++#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar)) + + #define obstack_blank_fast(h,n) ((h)->next_free += (n)) + +@@ -411,7 +411,7 @@ __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, 1); \ +- *(__o->next_free)++ = (datum); \ ++ obstack_1grow_fast (__o, datum); \ + (void) 0; }) + + /* These assume that the obstack alignment is good enough for pointers or ints, +@@ -423,19 +423,28 @@ __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (void *)); \ +- *((void **)__o->next_free)++ = ((void *)datum); \ +- (void) 0; }) ++ obstack_ptr_grow_fast (__o, datum); }) + + # define obstack_int_grow(OBSTACK,datum) \ + __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (int) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (int)); \ +- *((int *)__o->next_free)++ = ((int)datum); \ ++ obstack_int_grow_fast (__o, datum); }) ++ ++# define obstack_ptr_grow_fast(OBSTACK,aptr) \ ++__extension__ \ ++({ struct obstack *__o1 = (OBSTACK); \ ++ *(const void **) __o1->next_free = (aptr); \ ++ __o1->next_free += sizeof (const void *); \ + (void) 0; }) + +-# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr) +-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint) ++# define obstack_int_grow_fast(OBSTACK,aint) \ ++__extension__ \ ++({ struct obstack *__o1 = (OBSTACK); \ ++ *(int *) __o1->next_free = (aint); \ ++ __o1->next_free += sizeof (int); \ ++ (void) 0; }) + + # define obstack_blank(OBSTACK,length) \ + __extension__ \ +@@ -443,7 +452,7 @@ __extension__ \ + int __len = (length); \ + if (__o->chunk_limit - __o->next_free < __len) \ + _obstack_newchunk (__o, __len); \ +- __o->next_free += __len; \ ++ obstack_blank_fast (__o, __len); \ + (void) 0; }) + + # define obstack_alloc(OBSTACK,length) \ +@@ -530,26 +539,29 @@ __extension__ \ + # define obstack_1grow(h,datum) \ + ( (((h)->next_free + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), 1), 0) : 0), \ +- (*((h)->next_free)++ = (datum))) ++ obstack_1grow_fast (h, datum)) + + # define obstack_ptr_grow(h,datum) \ + ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ +- (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum))) ++ obstack_ptr_grow_fast (h, datum)) + + # define obstack_int_grow(h,datum) \ + ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ +- (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum))) ++ obstack_int_grow_fast (h, datum)) ++ ++# define obstack_ptr_grow_fast(h,aptr) \ ++ (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr)) + +-# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr) +-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint) ++# define obstack_int_grow_fast(h,aint) \ ++ (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr)) + + # define obstack_blank(h,length) \ + ( (h)->temp = (length), \ + (((h)->chunk_limit - (h)->next_free < (h)->temp) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ +- ((h)->next_free += (h)->temp)) ++ obstack_blank_fast (h, (h)->temp)) + + # define obstack_alloc(h,length) \ + (obstack_blank ((h), (length)), obstack_finish ((h))) diff --git a/SOURCES/gcc32-ppc-altivec-ap.patch b/SOURCES/gcc32-ppc-altivec-ap.patch new file mode 100644 index 0000000..fa13148 --- /dev/null +++ b/SOURCES/gcc32-ppc-altivec-ap.patch @@ -0,0 +1,37 @@ +2004-03-30 Hartmut Penner + + PR 11591 + * config/rs6000/rs6000.c (rs6000_legitimate_address): + Allow any offset to argument pointer in no-strict case. + +2002-04-16 Jakub Jelinek + + * gcc.dg/altivec-5.c: New test. + +--- gcc/config/rs6000/rs6000.c 25 Mar 2004 17:43:19 -0000 1.616 ++++ gcc/config/rs6000/rs6000.c 30 Mar 2004 08:25:30 -0000 1.617 +@@ -3267,7 +3267,8 @@ rs6000_legitimate_address (enum machine_ + if (! reg_ok_strict + && GET_CODE (x) == PLUS + && GET_CODE (XEXP (x, 0)) == REG +- && XEXP (x, 0) == virtual_stack_vars_rtx ++ && (XEXP (x, 0) == virtual_stack_vars_rtx ++ || XEXP (x, 0) == arg_pointer_rtx) + && GET_CODE (XEXP (x, 1)) == CONST_INT) + return 1; + if (legitimate_offset_address_p (mode, x, reg_ok_strict)) +--- gcc/testsuite/gcc.dg/altivec-5.c.jj 2004-10-25 23:16:31.270583520 +0200 ++++ gcc/testsuite/gcc.dg/altivec-5.c 2004-10-25 23:16:40.327975169 +0200 +@@ -0,0 +1,12 @@ ++/* { dg-do compile { target powerpc*-*-* } } */ ++/* { dg-options "-maltivec -O2 -m32" } */ ++ ++#define vector __attribute__((vector_size(16))) ++ ++void foo (const unsigned long x, ++ vector signed int a, vector signed int b) ++{ ++ unsigned char d[64]; ++ ++ __builtin_altivec_stvewx (b, 0, d); ++} diff --git a/SOURCES/gcc32-ppc-movdi_internal64.patch b/SOURCES/gcc32-ppc-movdi_internal64.patch new file mode 100644 index 0000000..573c7ed --- /dev/null +++ b/SOURCES/gcc32-ppc-movdi_internal64.patch @@ -0,0 +1,149 @@ +2004-07-25 David Edelsohn + + PR target/16239 + * config/rs6000/rs6000.md (movdi_internal64): Further disparage + f->f. + +2002-11-06 David Edelsohn + + PR target/8480, optimization/8328 + * config/rs6000/rs6000.md (movdi_internal64): Discourage + FPR to FPR moves. + +2004-12-22 Ben Elliston + + PR optimization/8328 + * gcc.dg/pr8328.c: New test. + +--- gcc/config/rs6000/rs6000.md 16 Jul 2003 11:40:06 -0000 ++++ gcc/config/rs6000/rs6000.md 22 Dec 2004 08:31:18 -0000 +@@ -8749,7 +8749,7 @@ + }") + + (define_insn "*movdi_internal64" +- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,f,f,m,r,*h,*h") ++ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,??f,f,m,r,*h,*h") + (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))] + "TARGET_POWERPC64 + && (gpc_reg_operand (operands[0], DImode) + +--- gcc/testsuite/gcc.dg/pr8328.c 1 Jan 1970 00:00:00 -0000 ++++ gcc/testsuite/gcc.dg/pr8328.c 22 Dec 2004 08:31:18 -0000 +@@ -0,0 +1,117 @@ ++/* { dg-do compile { target powerpc64-*-linux* } } */ ++/* { dg-options "-O3" } */ ++ ++/* This test case comes from the original PR. */ ++ ++struct list ++{ ++ unsigned short type; ++ unsigned int len; ++ void *data; ++ short *ind; ++}; ++ ++extern int foo (int *); ++extern int bar (void); ++extern int qwe (struct list *); ++extern long check (int *); ++extern void display (int *); ++extern void trace (int *); ++ ++int ++myfunc (int *opts, char *str) ++{ ++ short num; ++ int loc; ++ int start; ++ int len; ++ int code; ++ int rc = 0; ++ ++ if (code && (rc = check (opts))) ++ goto exit; ++ ++ foo (&code); ++ { ++ struct list mylist[1]; ++ mylist[0].type = 960; ++ mylist[0].len = 4; ++ mylist[0].data = (void *) &loc; ++ mylist[0].ind = 0L; ++ qwe (mylist); ++ } ++ bar (); ++ ++ if (code && (rc = check (opts))) ++ goto exit; ++ ++ foo (&code); ++ bar (); ++ ++ if (code && (rc = check (opts))) ++ goto exit; ++ ++ if (opts) ++ trace (opts); ++ ++ display (opts); ++ ++ while (code >= 0) ++ { ++ foo (&code); ++ { ++ struct list mylist[1]; ++ mylist[0].type = 500; ++ mylist[0].len = 2; ++ mylist[0].data = (void *) # ++ mylist[0].ind = 0L; ++ qwe (mylist); ++ } ++ bar (); ++ { ++ struct list mylist[3]; ++ mylist[0].type = 960; ++ mylist[0].len = 4; ++ mylist[0].data = (void *) &loc; ++ mylist[0].ind = 0L; ++ mylist[1].type = 496; ++ mylist[1].len = 4; ++ mylist[1].data = (void *) &start; ++ mylist[1].ind = 0L; ++ mylist[2].type = 496; ++ mylist[2].len = 4; ++ mylist[2].data = (void *) &len; ++ mylist[2].ind = 0L; ++ qwe (mylist); ++ } ++ { ++ struct list mylist[4]; ++ mylist[0].type = 460; ++ mylist[0].len = 129; ++ mylist[0].data = (void *) str; ++ mylist[0].ind = 0L; ++ mylist[1].type = 460; ++ mylist[1].len = 129; ++ mylist[1].data = (void *) str; ++ mylist[1].ind = 0L; ++ mylist[2].type = 460; ++ mylist[2].len = 9; ++ mylist[2].data = (void *) str; ++ mylist[2].ind = 0L; ++ mylist[3].type = 500; ++ mylist[3].len = 2; ++ mylist[3].data = (void *) str; ++ mylist[3].ind = 0L; ++ qwe (mylist); ++ } ++ } ++ ++ exit: ++ { ++ struct list mylist[1]; ++ mylist[0].data = (void *) &loc; ++ mylist[0].ind = 0L; ++ qwe (mylist); ++ } ++ return (rc); ++} diff --git a/SOURCES/gcc32-ppc-mpowerpc64.patch b/SOURCES/gcc32-ppc-mpowerpc64.patch new file mode 100644 index 0000000..5874d6d --- /dev/null +++ b/SOURCES/gcc32-ppc-mpowerpc64.patch @@ -0,0 +1,24 @@ +2004-10-26 Jakub Jelinek + + * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Disallow + -m32 -mpowerpc64 and -m64 -mno-powerpc64. + +--- gcc/config/rs6000/linux64.h.jj 2004-02-28 12:27:45.000000000 +0100 ++++ gcc/config/rs6000/linux64.h 2004-10-26 12:45:20.399107248 +0200 +@@ -142,6 +142,16 @@ Boston, MA 02111-1307, USA. */ + flag_pic = 0; \ + error ("-m32 and -maddr32 are incompatible"); \ + } \ ++ if (TARGET_32BIT && TARGET_POWERPC64) \ ++ { \ ++ error ("-mpowerpc64 can't be used for 32-bit compilation"); \ ++ target_flags &= ~MASK_POWERPC64; \ ++ } \ ++ else if (TARGET_64BIT && !TARGET_POWERPC64) \ ++ { \ ++ error ("-mno-powerpc64 can't be used for 64-bit compilation"); \ ++ target_flags |= MASK_POWERPC64 | MASK_POWERPC; \ ++ } \ + } \ + while (0) + diff --git a/SOURCES/gcc32-ppc64-crtsavres.patch b/SOURCES/gcc32-ppc64-crtsavres.patch new file mode 100644 index 0000000..7c0dd58 --- /dev/null +++ b/SOURCES/gcc32-ppc64-crtsavres.patch @@ -0,0 +1,14 @@ +2004-08-18 Jakub Jelinek + + * config/rs6000/crtsavres.asm (.fres): Add .align 2. + +--- gcc/config/rs6000/crtsavres.asm.jj 2002-02-19 20:40:41.000000000 +0100 ++++ gcc/config/rs6000/crtsavres.asm 2004-08-18 10:58:01.952395671 +0200 +@@ -358,6 +358,7 @@ FUNC_END(_savef14) + + /* Routines for restoring floating point registers, called by the compiler. */ + ++ .align 2 + .fres: + FUNC_START(_restf14) lfd 14,-144(1) /* restore fp registers */ + FUNC_START(_restf15) lfd 15,-136(1) diff --git a/SOURCES/gcc32-ppc64-m32-m64-multilib-only.patch b/SOURCES/gcc32-ppc64-m32-m64-multilib-only.patch new file mode 100644 index 0000000..00dbeac --- /dev/null +++ b/SOURCES/gcc32-ppc64-m32-m64-multilib-only.patch @@ -0,0 +1,22 @@ +--- gcc/config/rs6000/t-linux64 2003-06-03 05:11:45.000000000 -0400 ++++ gcc/config/rs6000/t-linux64 2003-06-11 17:07:16.000000000 -0400 +@@ -4,13 +4,13 @@ LIB2FUNCS_EXTRA = tramp.S $(srcdir)/conf + # Modify the shared lib version file + SHLIB_MKMAP_OPTS = -v dotsyms=1 + +-MULTILIB_OPTIONS = m64/m32 msoft-float +-MULTILIB_DIRNAMES = 64 32 nof ++MULTILIB_OPTIONS = m64/m32 ++MULTILIB_DIRNAMES = 64 32 + MULTILIB_EXTRA_OPTS = fPIC mstrict-align +-MULTILIB_EXCEPTIONS = m64/msoft-float +-MULTILIB_EXCLUSIONS = m64/!m32/msoft-float +-MULTILIB_OSDIRNAMES = ../lib64 ../lib nof +-MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) ++MULTILIB_EXCEPTIONS = ++MULTILIB_EXCLUSIONS = ++MULTILIB_OSDIRNAMES = ../lib64 ../lib ++MULTILIB_MATCHES = + + TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC + diff --git a/SOURCES/gcc32-ppc64-stack-boundary.patch b/SOURCES/gcc32-ppc64-stack-boundary.patch new file mode 100644 index 0000000..a01a86e --- /dev/null +++ b/SOURCES/gcc32-ppc64-stack-boundary.patch @@ -0,0 +1,30 @@ +2005-09-23 Alexandre Oliva + + * config/rs6000/sysv4.h (PREFERRED_STACK_BOUNDARY): New, + same as STACK_BOUNDARY as in rs6000.h. + +--- gcc/config/rs6000/sysv4.h.orig ++++ gcc/config/rs6000/sysv4.h +@@ -395,6 +395,22 @@ do { \ + #undef STACK_BOUNDARY + #define STACK_BOUNDARY (TARGET_ALTIVEC_ABI ? 128 : 64) + ++/* The definition above is actually wrong, since it doesn't use ++ 128-bit alignment on ppc64 like the ABI mandates. It was removed ++ in newer versions of GCC. The correct definition would be the one ++ below, from rs6000.h. Unfortunately, changing it would increase ++ the stack alignment expectations of newly-compiled functions, that ++ might be called by functions compiled with the old compiler. If ++ the latter didn't keep the stack sufficiently aligned. This may ++ happen if the latter uses alloca() or dynamically-sized arrays. We ++ compensate for the error here, getting the compiler to keep the ++ stack aligned to the correct boundary, but not assuming it is ++ sufficiently aligned. Code that still assumes proper alignment ++ will fail and require recompilation with this patch or a newer ++ compiler, but most of the code will work without change. */ ++#define PREFERRED_STACK_BOUNDARY \ ++ ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128) ++ + /* Real stack boundary as mandated by the appropriate ABI. */ + #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128) + diff --git a/SOURCES/gcc32-pr12799.patch b/SOURCES/gcc32-pr12799.patch new file mode 100644 index 0000000..aee7f8d --- /dev/null +++ b/SOURCES/gcc32-pr12799.patch @@ -0,0 +1,111 @@ +2005-10-02 Jakub Jelinek + + PR optimization/12799 + * gcc.c-torture/execute/20051002-1.c: New test. + +2003-11-02 Eric Botcazou + + PR optimization/12799 + * reload1.c (reload_cse_move2add): Generate the add2 + patterns manually. + + * gcc.dg/20031102-1.c: New test. + +--- gcc/reload1.c.jj 2003-10-31 11:42:15.000000000 +0100 ++++ gcc/reload1.c 2005-10-02 21:52:08.000000000 +0200 +@@ -9176,8 +9176,13 @@ reload_cse_move2add (first) + success = validate_change (insn, &SET_SRC (pat), reg, 0); + else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET) + && have_add2_insn (reg, new_src)) +- success = validate_change (insn, &PATTERN (insn), +- gen_add2_insn (reg, new_src), 0); ++ { ++ rtx newpat = gen_rtx_SET (VOIDmode, reg, ++ gen_rtx_PLUS (GET_MODE (reg), ++ reg, new_src)); ++ success ++ = validate_change (insn, &PATTERN (insn), newpat, 0); ++ } + reg_set_luid[regno] = move2add_luid; + reg_mode[regno] = GET_MODE (reg); + reg_offset[regno] = INTVAL (src); +@@ -9227,9 +9232,15 @@ reload_cse_move2add (first) + else if ((rtx_cost (new_src, PLUS) + < COSTS_N_INSNS (1) + rtx_cost (src3, SET)) + && have_add2_insn (reg, new_src)) +- success +- = validate_change (next, &PATTERN (next), +- gen_add2_insn (reg, new_src), 0); ++ { ++ rtx newpat ++ = gen_rtx_SET (VOIDmode, reg, ++ gen_rtx_PLUS (GET_MODE (reg), ++ reg, new_src)); ++ success ++ = validate_change (next, &PATTERN (next), ++ newpat, 0); ++ } + if (success) + delete_insn (insn); + insn = next; +--- gcc/testsuite/gcc.dg/20031102-1.c.jj 1 Jan 1970 00:00:00 -0000 ++++ gcc/testsuite/gcc.dg/20031102-1.c 2 Nov 2003 08:32:23 -0000 1.1 +@@ -0,0 +1,37 @@ ++/* PR optimization/12799 */ ++/* Origin: Pratap Subrahmanyam */ ++ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++/* { dg-options "-O2 -march=i686" { target i686-*-* } } */ ++ ++/* Verify that reload_cse_move2add doesn't add unexpected CLOBBERs. */ ++ ++extern void abort(void); ++ ++int loo = 1; ++ ++__inline__ char InlineFunc(void) ++{ ++ return __builtin_expect(!!(loo == 1), 1); ++} ++ ++int FooBar(void) ++{ ++ int i; ++ int var1 = InlineFunc() ? 2046 : 1023; ++ int var2 = InlineFunc() ? 512 : 1024; ++ ++ for (i = 0; i < var1; i++) ++ ; ++ ++ if (InlineFunc() && var2 != 512) ++ abort(); ++ ++ return 0; ++} ++ ++int main(void) ++{ ++ return FooBar(); ++} +--- gcc/testsuite/gcc.c-torture/execute/20051002-1.c.jj 2005-09-19 08:33:21.659531528 +0200 ++++ gcc/testsuite/gcc.c-torture/execute/20051002-1.c 2005-10-02 20:38:54.000000000 +0200 +@@ -0,0 +1,18 @@ ++/* PR optimization/12799 */ ++extern void abort (void); ++ ++unsigned int ++foo (unsigned long a) ++{ ++ if (a >= 0xffffffffUL) ++ return 0xffffffff; ++ return a; ++} ++ ++int ++main () ++{ ++ if (foo (0) != 0) ++ abort (); ++ return 0; ++} diff --git a/SOURCES/gcc32-pr13041.patch b/SOURCES/gcc32-pr13041.patch new file mode 100644 index 0000000..3ca4854 --- /dev/null +++ b/SOURCES/gcc32-pr13041.patch @@ -0,0 +1,37 @@ +2003-11-27 Eric Botcazou + + PR optimization/13041 + * final.c (frame_pointer_needed): Fix comment. + * reload1.c (reload): Decrease alignment of the frame + pointer if it was used for register allocation. + +--- gcc/final.c 1 Nov 2003 00:48:50 -0000 1.294 ++++ gcc/final.c 27 Nov 2003 06:45:24 -0000 1.295 +@@ -171,8 +171,8 @@ CC_STATUS cc_prev_status; + char regs_ever_live[FIRST_PSEUDO_REGISTER]; + + /* Nonzero means current function must be given a frame pointer. +- Set in stmt.c if anything is allocated on the stack there. +- Set in reload1.c if anything is allocated on the stack there. */ ++ Initialized in function.c to 0. Set only in reload1.c as per ++ the needs of the function. */ + + int frame_pointer_needed; + +--- gcc/reload1.c 21 Nov 2003 05:49:05 -0000 1.413 ++++ gcc/reload1.c 27 Nov 2003 06:45:25 -0000 1.414 +@@ -1241,6 +1241,14 @@ reload (rtx first, int global) + by this, so unshare everything here. */ + unshare_all_rtl_again (first); + ++#ifdef STACK_BOUNDARY ++ /* init_emit has set the alignment of the hard frame pointer ++ to STACK_BOUNDARY. It is very likely no longer valid if ++ the hard frame pointer was used for register allocation. */ ++ if (!frame_pointer_needed) ++ REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; ++#endif ++ + return failure; + } + diff --git a/SOURCES/gcc32-pr13106.patch b/SOURCES/gcc32-pr13106.patch new file mode 100644 index 0000000..7b6137a --- /dev/null +++ b/SOURCES/gcc32-pr13106.patch @@ -0,0 +1,37 @@ +2005-09-23 Alexandre Oliva + + * decl.c (finish_function): Skip no-return-statment warning if + the return type uses template parms. + + * g++.dg/warn/return-void-1.C: New test. + +--- gcc/cp/decl.c.orig ++++ gcc/cp/decl.c +@@ -14475,7 +14475,8 @@ finish_function (flags) + && !DECL_NAME (DECL_RESULT (fndecl)) + /* Normally, with -Wreturn-type, flow will complain. Unless we're an + inline function, as we might never be compiled separately. */ +- && (DECL_INLINE (fndecl) || processing_template_decl)) ++ && (DECL_INLINE (fndecl) || processing_template_decl) ++ && !uses_template_parms (TREE_TYPE (fntype))) + warning ("no return statement in function returning non-void"); + + /* Clear out memory we no longer need. */ +--- gcc/testsuite/g++.dg/warn/return-void-1.C ++++ gcc/testsuite/g++.dg/warn/return-void-1.C +@@ -0,0 +1,15 @@ ++// { dg-do compile } ++// { dg-options "-Wall" } ++ ++template T dummy1() {} ++template T dummy2() {} // { dg-warning "end of non-void" } ++template inline T dummy3() {} ++template inline T dummy4() {} // { dg-warning "end of non-void|no return statement" } ++ ++int main() ++{ ++ dummy1(); ++ dummy2(); // { dg-warning "instantiated from here" } ++ dummy3(); ++ dummy4(); // { dg-warning "instantiated from here" } ++} diff --git a/SOURCES/gcc32-pr18300.patch b/SOURCES/gcc32-pr18300.patch new file mode 100644 index 0000000..2a5cce6 --- /dev/null +++ b/SOURCES/gcc32-pr18300.patch @@ -0,0 +1,166 @@ +2005-09-07 Jakub Jelinek + + PR target/18300 + * config/i386/i386.c (classify_argument): Only use different + iterators for nested loops if nested loops sharing the same + iterator would hang. + +2004-11-13 Zak Kipling + + PR target/18300 + * config/i386/i386.c (classify_argument): Fix infinite loop when + passing object with 3 or more base classes by value. + +--- gcc/config/i386/i386.c.jj 2005-07-21 11:01:36.000000000 +0200 ++++ gcc/config/i386/i386.c 2005-09-07 14:22:19.000000000 +0200 +@@ -1784,8 +1784,17 @@ classify_argument (mode, type, classes, + { + tree bases = TYPE_BINFO_BASETYPES (type); + int n_bases = TREE_VEC_LENGTH (bases); +- int i; +- ++ int i, basenum; ++ enum x86_64_reg_class saveclasses[MAX_CLASSES]; ++ bool seen[MAX_CLASSES]; ++ ++ /* PR target/18300: The following code mistakenly uses the same ++ iterator variable in both nested for loops. But to preserve ++ binary compatibility, do whatever this code used to do before ++ unless old GCC would hang in an infinite loop. In that case ++ use whatever GCC 4.0+ does. */ ++ memset (seen, 0, sizeof (seen)); ++ memcpy (saveclasses, classes, sizeof (saveclasses)); + for (i = 0; i < n_bases; ++i) + { + tree binfo = TREE_VEC_ELT (bases, i); +@@ -1793,6 +1802,12 @@ classify_argument (mode, type, classes, + int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; + tree type = BINFO_TYPE (binfo); + ++ if (i < MAX_CLASSES) ++ { ++ if (seen[i]) ++ break; ++ seen[i] = true; ++ } + num = classify_argument (TYPE_MODE (type), + type, subclasses, + (offset + bit_offset) % 256); +@@ -1805,6 +1820,32 @@ classify_argument (mode, type, classes, + merge_classes (subclasses[i], classes[i + pos]); + } + } ++ if (i < n_bases) ++ { ++ /* Older GCC 3.[0-4].x would hang in the above loop, so ++ don't worry about backwards compatibility and ++ just DTRT. */ ++ memcpy (classes, saveclasses, sizeof (saveclasses)); ++ for (basenum = 0; basenum < n_bases; ++basenum) ++ { ++ tree binfo = TREE_VEC_ELT (bases, basenum); ++ int num; ++ int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; ++ tree type = BINFO_TYPE (binfo); ++ ++ num = classify_argument (TYPE_MODE (type), ++ type, subclasses, ++ (offset + bit_offset) % 256); ++ if (!num) ++ return 0; ++ for (i = 0; i < num; i++) ++ { ++ int pos = (offset + (bit_offset % 64)) / 8 / 8; ++ classes[i + pos] = ++ merge_classes (subclasses[i], classes[i + pos]); ++ } ++ } ++ } + } + /* And now merge the fields of structure. */ + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) +@@ -1872,8 +1913,17 @@ classify_argument (mode, type, classes, + { + tree bases = TYPE_BINFO_BASETYPES (type); + int n_bases = TREE_VEC_LENGTH (bases); +- int i; +- ++ int i, basenum; ++ enum x86_64_reg_class saveclasses[MAX_CLASSES]; ++ bool seen[MAX_CLASSES]; ++ ++ /* PR target/18300: The following code mistakenly uses the same ++ iterator variable in both nested for loops. But to preserve ++ binary compatibility, do whatever this code used to do before ++ unless old GCC would hang in an infinite loop. In that case ++ use whatever GCC 4.0+ does. */ ++ memset (seen, 0, sizeof (seen)); ++ memcpy (saveclasses, classes, sizeof (saveclasses)); + for (i = 0; i < n_bases; ++i) + { + tree binfo = TREE_VEC_ELT (bases, i); +@@ -1881,6 +1931,12 @@ classify_argument (mode, type, classes, + int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; + tree type = BINFO_TYPE (binfo); + ++ if (i < MAX_CLASSES) ++ { ++ if (seen[i]) ++ break; ++ seen[i] = true; ++ } + num = classify_argument (TYPE_MODE (type), + type, subclasses, + (offset + (bit_offset % 64)) % 256); +@@ -1893,6 +1949,32 @@ classify_argument (mode, type, classes, + merge_classes (subclasses[i], classes[i + pos]); + } + } ++ if (i < n_bases) ++ { ++ /* Older GCC 3.[0-4].x would hang in the above loop, so ++ don't worry about backwards compatibility and ++ just DTRT. */ ++ memcpy (classes, saveclasses, sizeof (saveclasses)); ++ for (basenum = 0; basenum < n_bases; ++basenum) ++ { ++ tree binfo = TREE_VEC_ELT (bases, basenum); ++ int num; ++ int offset = tree_low_cst (BINFO_OFFSET (binfo), 0) * 8; ++ tree type = BINFO_TYPE (binfo); ++ ++ num = classify_argument (TYPE_MODE (type), ++ type, subclasses, ++ (offset + (bit_offset % 64)) % 256); ++ if (!num) ++ return 0; ++ for (i = 0; i < num; i++) ++ { ++ int pos = (offset + (bit_offset % 64)) / 8 / 8; ++ classes[i + pos] = ++ merge_classes (subclasses[i], classes[i + pos]); ++ } ++ } ++ } + } + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { +--- gcc/testsuite/g++.dg/other/infloop-1.C 1 Jan 1970 00:00:00 -0000 ++++ gcc/testsuite/g++.dg/other/infloop-1.C 13 Nov 2004 23:09:08 -0000 1.1 +@@ -0,0 +1,16 @@ ++// PR 18300: This sends old compilers into an infinite loop on x86_64 ++// Testcase and patch contributed by Zak Kipling ++ ++struct base1 { }; ++struct base2 { }; ++struct base3 { }; ++ ++struct derived : base1, base2, base3 { }; ++ ++void foo(derived); ++ ++int main() ++{ ++ foo(derived()); ++} ++ diff --git a/SOURCES/gcc32-pr19005.patch b/SOURCES/gcc32-pr19005.patch new file mode 100644 index 0000000..a4f2442 --- /dev/null +++ b/SOURCES/gcc32-pr19005.patch @@ -0,0 +1,61 @@ +2005-05-13 Jakub Jelinek + + PR target/19005 + * config/i386/i386.md (swapqi): Use +q instead of +r constraints. + + * gcc.c-torture/execute/pr19005.c: New test. + +--- gcc/config/i386/i386.md.jj 2004-07-01 12:40:54.000000000 +0200 ++++ gcc/config/i386/i386.md 2005-05-13 13:56:14.000000000 +0200 +@@ -2107,8 +2107,8 @@ + }) + + (define_insn "*swapqi" +- [(set (match_operand:QI 0 "register_operand" "+r") +- (match_operand:QI 1 "register_operand" "+r")) ++ [(set (match_operand:QI 0 "register_operand" "+q") ++ (match_operand:QI 1 "register_operand" "+q")) + (set (match_dup 1) + (match_dup 0))] + "" +--- gcc/testsuite/gcc.c-torture/execute/pr19005.c.jj 2005-04-07 15:51:53.775361896 +0200 ++++ gcc/testsuite/gcc.c-torture/execute/pr19005.c 2005-05-13 13:33:21.000000000 +0200 +@@ -0,0 +1,38 @@ ++/* PR target/19005 */ ++extern void abort (void); ++ ++int v, s; ++ ++void ++bar (int a, int b) ++{ ++ unsigned char x = v; ++ ++ if (!s) ++ { ++ if (a != x || b != (unsigned char) (x + 1)) ++ abort (); ++ } ++ else if (a != (unsigned char) (x + 1) || b != x) ++ abort (); ++ s ^= 1; ++} ++ ++int ++foo (int x) ++{ ++ unsigned char a = x, b = x + 1; ++ ++ bar (a, b); ++ a ^= b; b ^= a; a ^= b; ++ bar (a, b); ++ return 0; ++} ++ ++int ++main (void) ++{ ++ for (v = -10; v < 266; v++) ++ foo (v); ++ return 0; ++} diff --git a/SOURCES/gcc32-pr26208-workaround.patch b/SOURCES/gcc32-pr26208-workaround.patch new file mode 100644 index 0000000..ed54694 --- /dev/null +++ b/SOURCES/gcc32-pr26208-workaround.patch @@ -0,0 +1,249 @@ +--- gcc/unwind-dw2.c.jj 2006-05-22 13:39:48.000000000 -0400 ++++ gcc/unwind-dw2.c 2006-05-22 13:48:20.000000000 -0400 +@@ -61,8 +61,8 @@ struct _Unwind_Context + void *ra; + void *lsda; + struct dwarf_eh_bases bases; ++#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1) + _Unwind_Word args_size; +- char signal_frame; + }; + + /* Byte size of every register managed by these routines. */ +@@ -201,7 +201,7 @@ _Unwind_GetIP (struct _Unwind_Context *c + inline _Unwind_Ptr + _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) + { +- *ip_before_insn = context->signal_frame != 0; ++ *ip_before_insn = (context->args_size & SIGNAL_FRAME_BIT) != 0; + return (_Unwind_Ptr) context->ra; + } + +@@ -758,7 +758,8 @@ execute_cfa_program (const unsigned char + reflected at the point immediately before the call insn. + In signal frames, return address is after last completed instruction, + so we add 1 to return address to make the comparison <=. */ +- while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame) ++ while (insn_ptr < insn_end ++ && fs->pc < context->ra + ((context->args_size & SIGNAL_FRAME_BIT) != 0)) + { + unsigned char insn = *insn_ptr++; + _Unwind_Word reg, utmp; +@@ -918,7 +919,14 @@ execute_cfa_program (const unsigned char + break; + + case DW_CFA_GNU_args_size: +- insn_ptr = read_uleb128 (insn_ptr, &context->args_size); ++ { ++ _Unwind_Word args_size; ++ insn_ptr = read_uleb128 (insn_ptr, &args_size); ++ if (args_size & SIGNAL_FRAME_BIT) ++ abort (); ++ context->args_size ++ = (context->args_size & SIGNAL_FRAME_BIT) | args_size; ++ } + break; + + case DW_CFA_GNU_negative_offset_extended: +@@ -945,10 +953,10 @@ uw_frame_state_for (struct _Unwind_Conte + const unsigned char *aug, *insn, *end; + + memset (fs, 0, sizeof (*fs)); +- context->args_size = 0; ++ context->args_size &= SIGNAL_FRAME_BIT; + context->lsda = 0; + +- fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1, ++ fde = _Unwind_Find_FDE (context->ra + ((context->args_size & SIGNAL_FRAME_BIT) != 0) - 1, + &context->bases); + if (fde == NULL) + { +@@ -1092,7 +1100,7 @@ __frame_state_for (void *pc_target, stru + state_in->cfa_offset = fs.cfa_offset; + state_in->cfa_reg = fs.cfa_reg; + state_in->retaddr_column = fs.retaddr_column; +- state_in->args_size = context.args_size; ++ state_in->args_size = context.args_size & ~SIGNAL_FRAME_BIT; + state_in->eh_ptr = fs.eh_ptr; + + #ifdef __linux__ +@@ -1287,7 +1295,10 @@ uw_update_context_1 (struct _Unwind_Cont + break; + } + +- context->signal_frame = fs->signal_frame; ++ if (fs->signal_frame) ++ context->args_size |= SIGNAL_FRAME_BIT; ++ else ++ context->args_size &= ~SIGNAL_FRAME_BIT; + + MD_FROB_UPDATE_CONTEXT (context, fs); + } +@@ -1403,9 +1414,9 @@ uw_install_context_1 (struct _Unwind_Con + + /* We adjust SP by the difference between CURRENT and TARGET's CFA. */ + if (STACK_GROWS_DOWNWARD) +- return target_cfa - current->cfa + target->args_size; ++ return target_cfa - current->cfa + (target->args_size & ~SIGNAL_FRAME_BIT); + else +- return current->cfa - target_cfa - target->args_size; ++ return current->cfa - target_cfa - (target->args_size & ~SIGNAL_FRAME_BIT); + } + #else + return 0; +--- libjava/exception.cc.jj 2006-05-22 13:39:48.000000000 -0400 ++++ libjava/exception.cc 2006-05-22 14:48:30.000000000 -0400 +@@ -31,6 +31,153 @@ namespace std + } + #include "unwind.h" + ++#if defined PIC && !defined __ia64__ ++ ++#include ++ ++extern "C" { ++ ++static void *libgcc_s_handle; ++ ++_Unwind_Reason_Code __attribute__((visibility ("hidden"))) ++_Unwind_RaiseException (struct _Unwind_Exception *exc) ++{ ++ static _Unwind_Reason_Code (*RaiseException) (struct _Unwind_Exception *); ++ ++ if (RaiseException == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ RaiseException = (__typeof (RaiseException)) ++ dlsym (libgcc_s_handle, "_Unwind_RaiseException"); ++ } ++ return RaiseException (exc); ++} ++ ++void __attribute__((visibility ("hidden"))) ++_Unwind_Resume (struct _Unwind_Exception *exc) ++{ ++ static void (*Resume) (struct _Unwind_Exception *); ++ ++ if (Resume == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ Resume = (__typeof (Resume)) ++ dlsym (libgcc_s_handle, "_Unwind_Resume"); ++ } ++ Resume (exc); ++} ++ ++__attribute__((visibility ("hidden"))) void * ++_Unwind_GetLanguageSpecificData (struct _Unwind_Context *ctx) ++{ ++ static void * (*GetLanguageSpecificData) (struct _Unwind_Context *); ++ ++ if (GetLanguageSpecificData == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ GetLanguageSpecificData = (__typeof (GetLanguageSpecificData)) ++ dlsym (libgcc_s_handle, "_Unwind_GetLanguageSpecificData"); ++ } ++ return GetLanguageSpecificData (ctx); ++} ++ ++_Unwind_Ptr __attribute__((visibility ("hidden"))) ++_Unwind_GetRegionStart (struct _Unwind_Context *ctx) ++{ ++ static _Unwind_Ptr (*GetRegionStart) (struct _Unwind_Context *); ++ ++ if (GetRegionStart == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ GetRegionStart = (__typeof (GetRegionStart)) ++ dlsym (libgcc_s_handle, "_Unwind_GetRegionStart"); ++ } ++ return GetRegionStart (ctx); ++} ++ ++_Unwind_Ptr __attribute__((visibility ("hidden"))) ++_Unwind_GetDataRelBase (struct _Unwind_Context *ctx) ++{ ++ static _Unwind_Ptr (*GetDataRelBase) (struct _Unwind_Context *); ++ ++ if (GetDataRelBase == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ GetDataRelBase = (__typeof (GetDataRelBase)) ++ dlsym (libgcc_s_handle, "_Unwind_GetDataRelBase"); ++ } ++ return GetDataRelBase (ctx); ++} ++ ++_Unwind_Ptr __attribute__((visibility ("hidden"))) ++_Unwind_GetTextRelBase (struct _Unwind_Context *ctx) ++{ ++ static _Unwind_Ptr (*GetTextRelBase) (struct _Unwind_Context *); ++ ++ if (GetTextRelBase == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ GetTextRelBase = (__typeof (GetTextRelBase)) ++ dlsym (libgcc_s_handle, "_Unwind_GetTextRelBase"); ++ } ++ return GetTextRelBase (ctx); ++} ++ ++_Unwind_Ptr __attribute__((visibility ("hidden"))) ++_Unwind_GetIPInfo (struct _Unwind_Context *ctx, int *ip) ++{ ++ static _Unwind_Ptr (*GetIPInfo) (struct _Unwind_Context *, int *ip); ++ ++ if (GetIPInfo == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ GetIPInfo = (__typeof (GetIPInfo)) ++ dlsym (libgcc_s_handle, "_Unwind_GetIPInfo"); ++ } ++ return GetIPInfo (ctx, ip); ++} ++ ++void __attribute__((visibility ("hidden"))) ++_Unwind_SetIP (struct _Unwind_Context *ctx, _Unwind_Ptr ip) ++{ ++ static void (*SetIP) (struct _Unwind_Context *, _Unwind_Ptr ip); ++ ++ if (SetIP == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ SetIP = (__typeof (SetIP)) ++ dlsym (libgcc_s_handle, "_Unwind_SetIP"); ++ } ++ SetIP (ctx, ip); ++} ++ ++void __attribute__((visibility ("hidden"))) ++_Unwind_SetGR (struct _Unwind_Context *ctx, int num, _Unwind_Ptr gr) ++{ ++ static void (*SetGR) (struct _Unwind_Context *, int num, _Unwind_Ptr gr); ++ ++ if (SetGR == NULL) ++ { ++ if (libgcc_s_handle == NULL) ++ libgcc_s_handle = dlopen ("libgcc_s.so.1", RTLD_LAZY); ++ SetGR = (__typeof (SetGR)) ++ dlsym (libgcc_s_handle, "_Unwind_SetGR"); ++ } ++ SetGR (ctx, num, gr); ++} ++ ++} ++ ++#endif ++ + struct alignment_test_struct + { + char space; diff --git a/SOURCES/gcc32-pr26208.patch b/SOURCES/gcc32-pr26208.patch new file mode 100644 index 0000000..bb64f2d --- /dev/null +++ b/SOURCES/gcc32-pr26208.patch @@ -0,0 +1,433 @@ +2006-02-27 Jakub Jelinek + + PR other/26208 + * unwind-dw2.c (struct _Unwind_Context): Add signal_frame field. + (_Unwind_FrameState): Add signal_frame field. + (extract_cie_info): Handle S flag in augmentation string. + (execute_cfa_program): If context->signal_frame, execute also + fs->pc == context->ra instructions. + (uw_frame_state_for): If context->signal_frame, don't subtract one + from context->ra to find FDE. + (uw_update_context_1): Set context->signal_frame to + fs->signal_frame. + (_Unwind_GetIPInfo): New function. + * unwind-c.c (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead + of _Unwind_GetIP. + * unwind-sjlj.c (_Unwind_GetIPInfo): New function. + * unwind.h (_Unwind_GetIPInfo): New prototype. + * libgcc-std.ver (_Unwind_GetIPInfo): Export @@GCC_4.2.0. + * config/ia64/unwind-ia64.c (_Unwind_GetIPInfo): New function. + * config/i386/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Set + (FS)->signal_frame. + * config/i386/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. + * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. + * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. + * config/s390/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Likewise. + + * libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Use + _Unwind_GetIPInfo instead of _Unwind_GetIP. + + * exception.cc (PERSONALITY_FUNCTION): Use _Unwind_GetIPInfo instead + of _Unwind_GetIP. + * include/i386-signal.h (MAKE_THROW_FRAME): Change into empty macro. + (HANDLE_DIVIDE_OVERFLOW): Don't adjust _res->eip if falling through + to throw. + * include/x86_64-signal.h (MAKE_THROW_FRAME): Change into empty + macro. + * include/powerpc-signal.h (MAKE_THROW_FRAME): Change into empty + macro. + +--- libjava/exception.cc.jj 2002-04-09 16:20:32.000000000 +0200 ++++ libjava/exception.cc 2006-04-25 15:33:37.000000000 +0200 +@@ -196,6 +196,7 @@ PERSONALITY_FUNCTION (int version, + int handler_switch_value; + bool saw_cleanup; + bool saw_handler; ++ int ip_before_insn = 0; + + + // Interface version check. +@@ -211,10 +212,10 @@ PERSONALITY_FUNCTION (int version, + goto install_context; + } + +- // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of ++ // FIXME: In Phase 1, record _Unwind_GetIPInfo in xh->obj as a part of + // the stack trace for this exception. This will only collect Java + // frames, but perhaps that is acceptable. +- // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site ++ // FIXME2: _Unwind_GetIPInfo is nonsensical for SJLJ, being a call-site + // index instead of a PC value. We could perhaps arrange for + // _Unwind_GetRegionStart to return context->fc->jbuf[1], which + // is the address of the handler label for __builtin_longjmp, but +@@ -229,7 +230,9 @@ PERSONALITY_FUNCTION (int version, + + // Parse the LSDA header. + p = parse_lsda_header (context, language_specific_data, &info); +- ip = _Unwind_GetIP (context) - 1; ++ ip = _Unwind_GetIPInfo (context, &ip_before_insn); ++ if (! ip_before_insn) ++ --ip; + landing_pad = 0; + action_record = 0; + handler_switch_value = 0; +--- libjava/include/i386-signal.h.jj 2002-03-18 23:27:01.000000000 +0100 ++++ libjava/include/i386-signal.h 2006-04-25 15:33:37.000000000 +0200 +@@ -22,19 +22,7 @@ details. */ + #define SIGNAL_HANDLER(_name) \ + static void _name (int _dummy) + +-#define MAKE_THROW_FRAME(_exception) \ +-do \ +-{ \ +- void **_p = (void **)&_dummy; \ +- struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p; \ +- \ +- /* Advance the program counter so that it is after the start of the \ +- instruction: the x86 exception handler expects \ +- the PC to point to the instruction after a call. */ \ +- _regs->eip += 2; \ +- \ +-} \ +-while (0) ++#define MAKE_THROW_FRAME(_exception) + + #define HANDLE_DIVIDE_OVERFLOW \ + do \ +@@ -84,14 +72,6 @@ do \ + _regs->eip = (unsigned long)_eip; \ + return; \ + } \ +- else \ +- { \ +- /* Advance the program counter so that it is after the start \ +- of the instruction: this is because the x86 exception \ +- handler expects the PC to point to the instruction after a \ +- call. */ \ +- _regs->eip += 2; \ +- } \ + } \ + } \ + while (0) +--- libjava/include/x86_64-signal.h.jj 2003-01-24 23:41:38.000000000 +0100 ++++ libjava/include/x86_64-signal.h 2006-04-25 15:34:23.000000000 +0200 +@@ -34,17 +34,7 @@ extern "C" + }; + } + +-#define MAKE_THROW_FRAME(_exception) \ +-do \ +-{ \ +- /* Advance the program counter so that it is after the start of the \ +- instruction: the x86_64 exception handler expects \ +- the PC to point to the instruction after a call. */ \ +- struct ucontext *_uc = (struct ucontext *)_p; \ +- struct sigcontext *_sc = (struct sigcontext *) &_uc->uc_mcontext; \ +- _sc->rip += 2; \ +-} \ +-while (0) ++#define MAKE_THROW_FRAME(_exception) + + #define RESTORE(name, syscall) RESTORE2 (name, syscall) + #define RESTORE2(name, syscall) \ +--- libjava/include/powerpc-signal.h.jj 2004-02-28 12:27:44.000000000 +0100 ++++ libjava/include/powerpc-signal.h 2006-04-25 15:33:37.000000000 +0200 +@@ -22,18 +22,12 @@ details. */ + #define SIGNAL_HANDLER(_name) \ + static void _name (int /* _signal */, struct sigcontext *_sc) + +-/* PPC either leaves PC pointing at a faulting instruction or the +- following instruction, depending on the signal. SEGV always does +- the former, so we adjust the saved PC to point to the following +- instruction. This is what the handler in libgcc expects. */ ++/* MD_FALBACK_FRAME_STATE_FOR takes care of special casing PC ++ before the faulting instruction, so we don't need to do anything ++ here. */ ++ ++#define MAKE_THROW_FRAME(_exception) + +-#define MAKE_THROW_FRAME(_exception) \ +-do \ +- { \ +- _sc->regs->nip += 4; \ +- } \ +-while (0) +- + /* For an explanation why we cannot simply use sigaction to + install the handlers, see i386-signal.h. */ + +--- libstdc++-v3/libsupc++/eh_personality.cc.jj 2003-06-11 15:08:13.000000000 +0200 ++++ libstdc++-v3/libsupc++/eh_personality.cc 2006-04-25 15:33:37.000000000 +0200 +@@ -201,6 +201,7 @@ PERSONALITY_FUNCTION (int version, + _Unwind_Ptr landing_pad, ip; + int handler_switch_value; + void *thrown_ptr = xh + 1; ++ int ip_before_insn = 0; + + // Interface version check. + if (version != 1) +@@ -227,7 +228,9 @@ PERSONALITY_FUNCTION (int version, + // Parse the LSDA header. + p = parse_lsda_header (context, language_specific_data, &info); + info.ttype_base = base_of_encoded_value (info.ttype_encoding, context); +- ip = _Unwind_GetIP (context) - 1; ++ ip = _Unwind_GetIPInfo (context, &ip_before_insn); ++ if (! ip_before_insn) ++ --ip; + landing_pad = 0; + action_record = 0; + handler_switch_value = 0; +--- gcc/libgcc-std.ver.jj 2004-02-28 12:16:53.000000000 +0100 ++++ gcc/libgcc-std.ver 2006-04-25 15:33:37.000000000 +0200 +@@ -210,3 +210,8 @@ GCC_3.4 { + __paritydi2 + __parityti2 + } ++ ++%inherit GCC_4.2.0 GCC_3.4 ++GCC_4.2.0 { ++ _Unwind_GetIPInfo ++} +--- gcc/unwind-c.c.jj 2003-06-11 15:08:12.000000000 +0200 ++++ gcc/unwind-c.c 2006-04-25 15:33:37.000000000 +0200 +@@ -93,6 +93,7 @@ PERSONALITY_FUNCTION (int version, + lsda_header_info info; + const unsigned char *language_specific_data, *p, *action_record; + _Unwind_Ptr landing_pad, ip; ++ int ip_before_insn = 0; + + if (version != 1) + return _URC_FATAL_PHASE1_ERROR; +@@ -110,7 +111,9 @@ PERSONALITY_FUNCTION (int version, + + /* Parse the LSDA header. */ + p = parse_lsda_header (context, language_specific_data, &info); +- ip = _Unwind_GetIP (context) - 1; ++ ip = _Unwind_GetIPInfo (context, &ip_before_insn); ++ if (! ip_before_insn) ++ --ip; + landing_pad = 0; + + #ifdef __USING_SJLJ_EXCEPTIONS__ +--- gcc/config/rs6000/linux.h.jj 2004-02-28 12:27:45.000000000 +0100 ++++ gcc/config/rs6000/linux.h 2006-04-25 15:36:47.000000000 +0200 +@@ -171,6 +171,7 @@ enum { SIGNAL_FRAMESIZE = 64 }; + (FS)->regs.reg[CR0_REGNO].loc.offset \ + = (long)&(sc_->regs->nip) - new_cfa_; \ + (FS)->retaddr_column = CR0_REGNO; \ ++ (FS)->signal_frame = 1; \ + goto SUCCESS; \ + } while (0) + +--- gcc/config/rs6000/linux64.h.jj 2004-10-29 09:35:44.000000000 +0200 ++++ gcc/config/rs6000/linux64.h 2006-04-25 15:37:14.000000000 +0200 +@@ -656,6 +656,7 @@ enum { SIGNAL_FRAMESIZE = 64 }; + (FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset \ + = (long)&(sc_->regs->nip) - new_cfa_; \ + (FS)->retaddr_column = ARG_POINTER_REGNUM; \ ++ (FS)->signal_frame = 1; \ + goto SUCCESS; \ + } while (0) + +@@ -720,6 +721,7 @@ enum { SIGNAL_FRAMESIZE = 64 }; + (FS)->regs.reg[CR0_REGNO].loc.offset \ + = (long)&(sc_->regs->nip) - new_cfa_; \ + (FS)->retaddr_column = CR0_REGNO; \ ++ (FS)->signal_frame = 1; \ + goto SUCCESS; \ + } while (0) + +--- gcc/config/s390/linux.h.jj 2003-10-31 11:36:50.000000000 +0100 ++++ gcc/config/s390/linux.h 2006-04-25 15:33:41.000000000 +0200 +@@ -339,6 +339,7 @@ do { + } __attribute__ ((__aligned__ (8))) sigregs_; \ + \ + sigregs_ *regs_; \ ++ int *signo_ = NULL; \ + \ + /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn */ \ + if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173)) \ +@@ -359,6 +360,7 @@ do { + } *uc_ = (CONTEXT)->cfa + 8 + 128; \ + \ + regs_ = &uc_->uc_mcontext; \ ++ signo_ = (CONTEXT)->cfa + sizeof(long); \ + } \ + \ + /* Old-style RT frame and all non-RT frames: \ +@@ -367,6 +369,11 @@ do { + else \ + { \ + regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8); \ ++ /* Recent kernels store the signal number immediately after \ ++ the sigregs; old kernels have the return trampoline at \ ++ this location. */ \ ++ if ((void *)(regs_ + 1) != (CONTEXT)->ra) \ ++ signo_ = (int *)(regs_ + 1); \ + } \ + \ + new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32; \ +@@ -393,6 +400,12 @@ do { + (FS)->regs.reg[32].loc.offset = (long)®s_->psw_addr - new_cfa_; \ + (FS)->retaddr_column = 32; \ + \ ++ /* SIGILL, SIGFPE and SIGTRAP are delivered with psw_addr \ ++ after the faulting instruction rather than before it. \ ++ Don't set FS->signal_frame in that case. */ \ ++ if (!signo_ || (*signo_ != 4 && *signo_ != 5 && *signo_ != 8)) \ ++ (FS)->signal_frame = 1; \ ++ \ + goto SUCCESS; \ + } while (0) + +--- gcc/config/i386/linux.h.jj 2003-06-11 14:56:49.000000000 +0200 ++++ gcc/config/i386/linux.h 2006-04-25 15:33:41.000000000 +0200 +@@ -280,6 +280,7 @@ Boston, MA 02111-1307, USA. */ + (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ + (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ + (FS)->retaddr_column = 8; \ ++ (FS)->signal_frame = 1; \ + goto SUCCESS; \ + } while (0) + #endif /* ifndef inhibit_libc */ +--- gcc/config/i386/linux64.h.jj 2003-06-11 14:56:49.000000000 +0200 ++++ gcc/config/i386/linux64.h 2006-04-25 15:33:41.000000000 +0200 +@@ -135,6 +135,7 @@ Boston, MA 02111-1307, USA. */ + (FS)->regs.reg[16].how = REG_SAVED_OFFSET; \ + (FS)->regs.reg[16].loc.offset = (long)&sc_->rip - new_cfa_; \ + (FS)->retaddr_column = 16; \ ++ (FS)->signal_frame = 1; \ + goto SUCCESS; \ + } while (0) + #else /* ifdef __x86_64__ */ +@@ -189,6 +190,7 @@ Boston, MA 02111-1307, USA. */ + (FS)->regs.reg[8].how = REG_SAVED_OFFSET; \ + (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_; \ + (FS)->retaddr_column = 8; \ ++ (FS)->signal_frame = 1; \ + goto SUCCESS; \ + } while (0) + #endif /* ifdef __x86_64__ */ +--- gcc/config/ia64/unwind-ia64.c.jj 2004-07-01 12:49:33.000000000 +0200 ++++ gcc/config/ia64/unwind-ia64.c 2006-04-25 15:33:41.000000000 +0200 +@@ -1700,6 +1700,13 @@ _Unwind_GetIP (struct _Unwind_Context *c + return context->rp; + } + ++inline _Unwind_Ptr ++_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) ++{ ++ *ip_before_insn = 0; ++ return context->rp; ++} ++ + /* Overwrite the return address for CONTEXT with VAL. */ + + inline void +--- gcc/unwind-sjlj.c.jj 2003-06-11 15:12:42.000000000 +0200 ++++ gcc/unwind-sjlj.c 2006-04-25 15:33:44.000000000 +0200 +@@ -197,6 +197,13 @@ _Unwind_GetIP (struct _Unwind_Context *c + return context->fc->call_site + 1; + } + ++_Unwind_Ptr ++_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) ++{ ++ *ip_before_insn = 0; ++ return context->fc->call_site + 1; ++} ++ + /* Set the return landing pad index in CONTEXT. */ + + void +--- gcc/unwind.h.jj 2003-09-04 11:16:10.000000000 +0200 ++++ gcc/unwind.h 2006-04-25 15:33:44.000000000 +0200 +@@ -136,6 +136,7 @@ extern _Unwind_Word _Unwind_GetGR (struc + extern void _Unwind_SetGR (struct _Unwind_Context *, int, _Unwind_Word); + + extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *); ++extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *); + extern void _Unwind_SetIP (struct _Unwind_Context *, _Unwind_Ptr); + + /* @@@ Retrieve the CFA of the given context. */ +--- gcc/unwind-dw2.c.jj 2003-07-16 13:38:32.000000000 +0200 ++++ gcc/unwind-dw2.c 2006-04-25 15:33:44.000000000 +0200 +@@ -62,6 +62,7 @@ struct _Unwind_Context + void *lsda; + struct dwarf_eh_bases bases; + _Unwind_Word args_size; ++ char signal_frame; + }; + + /* Byte size of every register managed by these routines. */ +@@ -117,6 +118,7 @@ typedef struct + unsigned char fde_encoding; + unsigned char lsda_encoding; + unsigned char saw_z; ++ unsigned char signal_frame; + void *eh_ptr; + } _Unwind_FrameState; + +@@ -193,6 +195,16 @@ _Unwind_GetIP (struct _Unwind_Context *c + return (_Unwind_Ptr) context->ra; + } + ++/* Retrieve the return address and flag whether that IP is before ++ or after first not yet fully executed instruction. */ ++ ++inline _Unwind_Ptr ++_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) ++{ ++ *ip_before_insn = context->signal_frame != 0; ++ return (_Unwind_Ptr) context->ra; ++} ++ + /* Overwrite the return address for CONTEXT with VAL. */ + + inline void +@@ -304,6 +316,13 @@ extract_cie_info (struct dwarf_cie *cie, + aug += 1; + } + ++ /* "S" indicates a signal frame. */ ++ else if (aug[0] == 'S') ++ { ++ fs->signal_frame = 1; ++ aug += 1; ++ } ++ + /* Otherwise we have an unknown augmentation string. + Bail unless we saw a 'z' prefix. */ + else +@@ -736,8 +755,10 @@ execute_cfa_program (const unsigned char + a different stack configuration that we are not interested in. We + assume that the call itself is unwind info-neutral; if not, or if + there are delay instructions that adjust the stack, these must be +- reflected at the point immediately before the call insn. */ +- while (insn_ptr < insn_end && fs->pc < context->ra) ++ reflected at the point immediately before the call insn. ++ In signal frames, return address is after last completed instruction, ++ so we add 1 to return address to make the comparison <=. */ ++ while (insn_ptr < insn_end && fs->pc < context->ra + context->signal_frame) + { + unsigned char insn = *insn_ptr++; + _Unwind_Word reg, utmp; +@@ -927,7 +948,8 @@ uw_frame_state_for (struct _Unwind_Conte + context->args_size = 0; + context->lsda = 0; + +- fde = _Unwind_Find_FDE (context->ra - 1, &context->bases); ++ fde = _Unwind_Find_FDE (context->ra + context->signal_frame - 1, ++ &context->bases); + if (fde == NULL) + { + /* Couldn't find frame unwind info for this function. Try a +@@ -1265,6 +1287,8 @@ uw_update_context_1 (struct _Unwind_Cont + break; + } + ++ context->signal_frame = fs->signal_frame; ++ + MD_FROB_UPDATE_CONTEXT (context, fs); + } + diff --git a/SOURCES/gcc32-pr3581.patch b/SOURCES/gcc32-pr3581.patch new file mode 100644 index 0000000..0f704dd --- /dev/null +++ b/SOURCES/gcc32-pr3581.patch @@ -0,0 +1,755 @@ +2002-04-26 Richard Henderson + + PR c/3581 + * c-common.c (fix_string_type): Split out of ... + (combine_strings): ... here. Take a varray, not a tree list. + (c_expand_builtin_printf): Use fix_string_type. + * c-common.h: Update decls. + * c-parse.in (string): Remove. Update all uses to use STRING + instead, and not call combine_strings. + (yylexstring): New. + (_yylex): Use it. + * c-typeck.c (simple_asm_stmt): Don't call combine_strings. + (build_asm_stmt): Likewise. + * objc/objc-act.c (my_build_string): Use fix_string_type. + (build_objc_string_object): Build varray for combine_strings. +cp/ + * parse.y (string): Remove. Update all uses to use STRING + instead, and not call combine_strings. + * rtti.c (tinfo_name): Use fix_string_type. + * semantics.c (finish_asm_stmt): Don't call combine_strings. + * spew.c (yylexstring): New. + (read_token): Use it. +testsuite/ + * g++.dg/parse/concat1.C: New test. + * gcc.dg/concat2.c: New test. + +--- gcc/objc/objc-act.c.jj 2002-09-24 15:08:15.000000000 +0200 ++++ gcc/objc/objc-act.c 2004-10-05 16:08:18.744519118 +0200 +@@ -1207,21 +1207,7 @@ my_build_string (len, str) + int len; + const char *str; + { +- int wide_flag = 0; +- tree a_string = build_string (len, str); +- +- /* Some code from combine_strings, which is local to c-parse.y. */ +- if (TREE_TYPE (a_string) == int_array_type_node) +- wide_flag = 1; +- +- TREE_TYPE (a_string) +- = build_array_type (wide_flag ? integer_type_node : char_type_node, +- build_index_type (build_int_2 (len - 1, 0))); +- +- TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */ +- TREE_STATIC (a_string) = 1; +- +- return a_string; ++ return fix_string_type (build_string (len, str)); + } + + /* Given a chain of STRING_CST's, build a static instance of +@@ -1247,7 +1233,23 @@ build_objc_string_object (strings) + + add_class_reference (constant_string_id); + +- string = combine_strings (strings); ++ if (TREE_CHAIN (strings)) ++ { ++ varray_type vstrings; ++ VARRAY_TREE_INIT (vstrings, 32, "strings"); ++ ++ for (; strings ; strings = TREE_CHAIN (strings)) ++ VARRAY_PUSH_TREE (vstrings, strings); ++ ++ string = combine_strings (vstrings); ++ ++ VARRAY_FREE (vstrings); ++ } ++ else ++ string = strings; ++ ++ string = fix_string_type (string); ++ + TREE_SET_CODE (string, STRING_CST); + length = TREE_STRING_LENGTH (string) - 1; + +--- gcc/c-common.h.jj 2003-09-16 16:57:44.000000000 +0200 ++++ gcc/c-common.h 2004-10-05 16:08:18.669532451 +0200 +@@ -524,8 +524,9 @@ extern void c_finish_else + extern void c_expand_end_cond PARAMS ((void)); + /* Validate the expression after `case' and apply default promotions. */ + extern tree check_case_value PARAMS ((tree)); +-/* Concatenate a list of STRING_CST nodes into one STRING_CST. */ +-extern tree combine_strings PARAMS ((tree)); ++extern tree fix_string_type PARAMS ((tree)); ++struct varray_head_tag; ++extern tree combine_strings PARAMS ((struct varray_head_tag *)); + extern void constant_expression_warning PARAMS ((tree)); + extern tree convert_and_check PARAMS ((tree, tree)); + extern void overflow_warning PARAMS ((tree)); +--- gcc/cp/rtti.c.jj 2002-12-08 21:43:27.000000000 +0100 ++++ gcc/cp/rtti.c 2004-10-05 16:08:18.721523207 +0200 +@@ -298,7 +298,7 @@ tinfo_name (type) + tree name_string; + + name = mangle_type_string (type); +- name_string = combine_strings (build_string (strlen (name) + 1, name)); ++ name_string = fix_string_type (build_string (strlen (name) + 1, name)); + return name_string; + } + +--- gcc/cp/semantics.c.jj 2003-03-28 22:03:02.000000000 +0100 ++++ gcc/cp/semantics.c 2004-10-05 16:08:18.723522851 +0200 +@@ -879,9 +879,6 @@ finish_asm_stmt (cv_qualifier, string, o + tree r; + tree t; + +- if (TREE_CHAIN (string)) +- string = combine_strings (string); +- + if (cv_qualifier != NULL_TREE + && cv_qualifier != ridpointers[(int) RID_VOLATILE]) + { +--- gcc/cp/parse.y.jj 2003-01-17 18:33:10.000000000 +0100 ++++ gcc/cp/parse.y 2004-10-05 16:08:18.717523918 +0200 +@@ -349,7 +349,7 @@ cp_parse_init () + %type PFUNCNAME maybe_identifier + %type paren_expr_or_null nontrivial_exprlist SELFNAME + %type expr_no_commas expr_no_comma_rangle +-%type cast_expr unary_expr primary string STRING ++%type cast_expr unary_expr primary STRING + %type reserved_declspecs boolean.literal + %type reserved_typespecquals + %type SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier +@@ -514,9 +514,8 @@ extdef: + { do_pending_inlines (); } + | template_def + { do_pending_inlines (); } +- | asm_keyword '(' string ')' ';' +- { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); +- assemble_asm ($3); } ++ | asm_keyword '(' STRING ')' ';' ++ { assemble_asm ($3); } + | extern_lang_string '{' extdefs_opt '}' + { pop_lang_context (); } + | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input +@@ -1587,10 +1586,10 @@ primary: + } + | CONSTANT + | boolean.literal +- | string ++ | STRING + { +- $$ = combine_strings ($$); +- /* combine_strings doesn't set up TYPE_MAIN_VARIANT of ++ $$ = fix_string_type ($$); ++ /* fix_string_type doesn't set up TYPE_MAIN_VARIANT of + a const array the way we want, so fix it. */ + if (flag_const_strings) + TREE_TYPE ($$) = build_cplus_array_type +@@ -1791,13 +1790,6 @@ boolean.literal: + { $$ = boolean_false_node; } + ; + +-/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ +-string: +- STRING +- | string STRING +- { $$ = chainon ($$, $2); } +- ; +- + nodecls: + /* empty */ + { +@@ -2091,8 +2083,8 @@ nomods_initdecls: + maybeasm: + /* empty */ + { $$ = NULL_TREE; } +- | asm_keyword '(' string ')' +- { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } ++ | asm_keyword '(' STRING ')' ++ { $$ = $3; } + ; + + initdcl: +@@ -3489,27 +3481,27 @@ simple_stmt: + { $$ = finish_return_stmt (NULL_TREE); } + | RETURN_KEYWORD expr ';' + { $$ = finish_return_stmt ($2); } +- | asm_keyword maybe_cv_qualifier '(' string ')' ';' ++ | asm_keyword maybe_cv_qualifier '(' STRING ')' ';' + { $$ = finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE, + NULL_TREE); + ASM_INPUT_P ($$) = 1; } + /* This is the case with just output operands. */ +- | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ')' ';' ++ | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ')' ';' + { $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); } + /* This is the case with input operands as well. */ +- | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' ++ | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':' + asm_operands ')' ';' + { $$ = finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); } +- | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ')' ';' ++ | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ')' ';' + { $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); } + /* This is the case with clobbered registers as well. */ +- | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' ++ | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':' + asm_operands ':' asm_clobbers ')' ';' + { $$ = finish_asm_stmt ($2, $4, $6, $8, $10); } +- | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ':' ++ | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ':' + asm_clobbers ')' ';' + { $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); } +- | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands SCOPE ++ | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands SCOPE + asm_clobbers ')' ';' + { $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); } + | GOTO '*' expr ';' +@@ -3670,10 +3662,10 @@ asm_operand: + ; + + asm_clobbers: +- string +- { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE);} +- | asm_clobbers ',' string +- { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); } ++ STRING ++ { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);} ++ | asm_clobbers ',' STRING ++ { $$ = tree_cons (NULL_TREE, $3, $1); } + ; + + /* This is what appears inside the parens in a function declarator. +--- gcc/cp/spew.c.jj 2002-11-09 18:39:59.000000000 +0100 ++++ gcc/cp/spew.c 2004-10-05 16:08:18.725522496 +0200 +@@ -102,6 +102,7 @@ static SPEW_INLINE int identifier_type P + static void scan_tokens PARAMS ((int)); + static void feed_defarg PARAMS ((tree)); + static void finish_defarg PARAMS ((void)); ++static void yylexstring PARAMS ((struct token *)); + static int read_token PARAMS ((struct token *)); + + static SPEW_INLINE int num_tokens PARAMS ((void)); +@@ -244,6 +245,43 @@ read_process_identifier (pyylval) + return IDENTIFIER; + } + ++/* Concatenate strings before returning them to the parser. This isn't quite ++ as good as having it done in the lexer, but it's better than nothing. */ ++ ++static void ++yylexstring (t) ++ struct token *t; ++{ ++ enum cpp_ttype next_type; ++ tree next; ++ ++ next_type = c_lex (&next); ++ if (next_type == CPP_STRING || next_type == CPP_WSTRING) ++ { ++ varray_type strings; ++ ++ VARRAY_TREE_INIT (strings, 32, "strings"); ++ VARRAY_PUSH_TREE (strings, t->yylval.ttype); ++ ++ do ++ { ++ VARRAY_PUSH_TREE (strings, next); ++ next_type = c_lex (&next); ++ } ++ while (next_type == CPP_STRING || next_type == CPP_WSTRING); ++ ++ t->yylval.ttype = combine_strings (strings); ++ last_token_id = t->yylval.ttype; ++ ++ VARRAY_FREE (strings); ++ } ++ ++ /* We will have always read one token too many. */ ++ _cpp_backup_tokens (parse_in, 1); ++ ++ t->yychar = STRING; ++} ++ + /* Read the next token from the input file. The token is written into + T, and its type number is returned. */ + static int +@@ -338,7 +376,7 @@ read_token (t) + + case CPP_STRING: + case CPP_WSTRING: +- t->yychar = STRING; ++ yylexstring (t); + break; + + default: +--- gcc/c-common.c.jj 2004-10-05 16:07:28.426465214 +0200 ++++ gcc/c-common.c 2004-10-05 16:08:18.646536539 +0200 +@@ -554,106 +554,17 @@ fname_decl (rid, id) + return decl; + } + +-/* Given a chain of STRING_CST nodes, +- concatenate them into one STRING_CST +- and give it a suitable array-of-chars data type. */ ++/* Given a STRING_CST, give it a suitable array-of-chars data type. */ + + tree +-combine_strings (strings) +- tree strings; ++fix_string_type (value) ++ tree value; + { +- tree value, t; +- int length = 1; +- int wide_length = 0; +- int wide_flag = 0; +- int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; +- int nchars; ++ const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; ++ const int wide_flag = TREE_TYPE (value) == wchar_array_type_node; + const int nchars_max = flag_isoc99 ? 4095 : 509; +- +- if (TREE_CHAIN (strings)) +- { +- /* More than one in the chain, so concatenate. */ +- char *p, *q; +- +- /* Don't include the \0 at the end of each substring, +- except for the last one. +- Count wide strings and ordinary strings separately. */ +- for (t = strings; t; t = TREE_CHAIN (t)) +- { +- if (TREE_TYPE (t) == wchar_array_type_node) +- { +- wide_length += (TREE_STRING_LENGTH (t) - wchar_bytes); +- wide_flag = 1; +- } +- else +- { +- length += (TREE_STRING_LENGTH (t) - 1); +- if (C_ARTIFICIAL_STRING_P (t) && !in_system_header) +- warning ("concatenation of string literals with __FUNCTION__ is deprecated"); +- } +- } +- +- /* If anything is wide, the non-wides will be converted, +- which makes them take more space. */ +- if (wide_flag) +- length = length * wchar_bytes + wide_length; +- +- p = xmalloc (length); +- +- /* Copy the individual strings into the new combined string. +- If the combined string is wide, convert the chars to ints +- for any individual strings that are not wide. */ +- +- q = p; +- for (t = strings; t; t = TREE_CHAIN (t)) +- { +- int len = (TREE_STRING_LENGTH (t) +- - ((TREE_TYPE (t) == wchar_array_type_node) +- ? wchar_bytes : 1)); +- if ((TREE_TYPE (t) == wchar_array_type_node) == wide_flag) +- { +- memcpy (q, TREE_STRING_POINTER (t), len); +- q += len; +- } +- else +- { +- int i, j; +- for (i = 0; i < len; i++) +- { +- if (BYTES_BIG_ENDIAN) +- { +- for (j=0; j<(WCHAR_TYPE_SIZE / BITS_PER_UNIT)-1; j++) +- *q++ = 0; +- *q++ = TREE_STRING_POINTER (t)[i]; +- } +- else +- { +- *q++ = TREE_STRING_POINTER (t)[i]; +- for (j=0; j<(WCHAR_TYPE_SIZE / BITS_PER_UNIT)-1; j++) +- *q++ = 0; +- } +- } +- } +- } +- if (wide_flag) +- { +- int i; +- for (i = 0; i < wchar_bytes; i++) +- *q++ = 0; +- } +- else +- *q = 0; +- +- value = build_string (length, p); +- free (p); +- } +- else +- { +- value = strings; +- length = TREE_STRING_LENGTH (value); +- if (TREE_TYPE (value) == wchar_array_type_node) +- wide_flag = 1; +- } ++ int length = TREE_STRING_LENGTH (value); ++ int nchars; + + /* Compute the number of elements, for the array type. */ + nchars = wide_flag ? length / wchar_bytes : length; +@@ -686,6 +597,111 @@ combine_strings (strings) + TREE_STATIC (value) = 1; + return value; + } ++ ++/* Given a VARRAY of STRING_CST nodes, concatenate them into one ++ STRING_CST. */ ++ ++tree ++combine_strings (strings) ++ varray_type strings; ++{ ++ const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT; ++ const int nstrings = VARRAY_ACTIVE_SIZE (strings); ++ tree value, t; ++ int length = 1; ++ int wide_length = 0; ++ int wide_flag = 0; ++ int i; ++ char *p, *q; ++ ++ /* Don't include the \0 at the end of each substring. Count wide ++ strings and ordinary strings separately. */ ++ for (i = 0; i < nstrings; ++i) ++ { ++ t = VARRAY_TREE (strings, i); ++ ++ if (TREE_TYPE (t) == wchar_array_type_node) ++ { ++ wide_length += TREE_STRING_LENGTH (t) - wchar_bytes; ++ wide_flag = 1; ++ } ++ else ++ { ++ length += (TREE_STRING_LENGTH (t) - 1); ++ if (C_ARTIFICIAL_STRING_P (t) && !in_system_header) ++ warning ("concatenation of string literals with __FUNCTION__ is deprecated"); ++ } ++ } ++ ++ /* If anything is wide, the non-wides will be converted, ++ which makes them take more space. */ ++ if (wide_flag) ++ length = length * wchar_bytes + wide_length; ++ ++ p = xmalloc (length); ++ ++ /* Copy the individual strings into the new combined string. ++ If the combined string is wide, convert the chars to ints ++ for any individual strings that are not wide. */ ++ ++ q = p; ++ for (i = 0; i < nstrings; ++i) ++ { ++ int len, this_wide; ++ ++ t = VARRAY_TREE (strings, i); ++ this_wide = TREE_TYPE (t) == wchar_array_type_node; ++ len = TREE_STRING_LENGTH (t) - (this_wide ? wchar_bytes : 1); ++ if (this_wide == wide_flag) ++ { ++ memcpy (q, TREE_STRING_POINTER (t), len); ++ q += len; ++ } ++ else ++ { ++ const int nzeros = (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - 1; ++ int j, k; ++ ++ if (BYTES_BIG_ENDIAN) ++ { ++ for (k = 0; k < len; k++) ++ { ++ for (j = 0; j < nzeros; j++) ++ *q++ = 0; ++ *q++ = TREE_STRING_POINTER (t)[k]; ++ } ++ } ++ else ++ { ++ for (k = 0; k < len; k++) ++ { ++ *q++ = TREE_STRING_POINTER (t)[k]; ++ for (j = 0; j < nzeros; j++) ++ *q++ = 0; ++ } ++ } ++ } ++ } ++ ++ /* Nul terminate the string. */ ++ if (wide_flag) ++ { ++ for (i = 0; i < wchar_bytes; i++) ++ *q++ = 0; ++ } ++ else ++ *q = 0; ++ ++ value = build_string (length, p); ++ free (p); ++ ++ if (wide_flag) ++ TREE_TYPE (value) = wchar_array_type_node; ++ else ++ TREE_TYPE (value) = char_array_type_node; ++ ++ return value; ++} + + static int is_valid_printf_arglist PARAMS ((tree)); + static rtx c_expand_builtin PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier)); +@@ -4062,7 +4078,7 @@ c_expand_builtin_printf (arglist, target + memcpy (newstr, TREE_STRING_POINTER (stripped_string), newlen - 1); + newstr[newlen - 1] = 0; + +- arglist = combine_strings (build_string (newlen, newstr)); ++ arglist = fix_string_type (build_string (newlen, newstr)); + arglist = build_tree_list (NULL_TREE, arglist); + fn = fn_puts; + } +--- gcc/testsuite/gcc.dg/concat2.c.jj 2004-10-05 16:08:18.746518763 +0200 ++++ gcc/testsuite/gcc.dg/concat2.c 2004-10-05 16:08:18.746518763 +0200 +@@ -0,0 +1,16 @@ ++/* PR c/3581 */ ++/* { dg-do compile } */ ++/* { dg-options "" } */ ++ ++/* Intended as a compile-time test for string literal concatenation. ++ The fact that the string isn't actually used in the resulting program ++ should allow this to compile for any target. */ ++ ++#define e0 "a" ++#define e1 e0 e0 e0 e0 e0 e0 e0 e0 e0 e0 ++#define e2 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 ++#define e3 e2 e2 e2 e2 e2 e2 e2 e2 e2 e2 ++#define e4 e3 e3 e3 e3 e3 e3 e3 e3 e3 e3 ++#define e5 e4 e4 e4 e4 e4 e4 e4 e4 e4 e4 ++ ++void foo() { (void)(e5); } +--- gcc/testsuite/g++.dg/parse/concat1.C.jj 2004-10-05 16:08:18.745518941 +0200 ++++ gcc/testsuite/g++.dg/parse/concat1.C 2004-10-05 16:08:18.745518941 +0200 +@@ -0,0 +1,15 @@ ++/* PR c/3581 */ ++/* { dg-do compile } */ ++ ++/* Intended as a compile-time test for string literal concatenation. ++ The fact that the string isn't actually used in the resulting program ++ should allow this to compile for any target. */ ++ ++#define e0 "a" ++#define e1 e0 e0 e0 e0 e0 e0 e0 e0 e0 e0 ++#define e2 e1 e1 e1 e1 e1 e1 e1 e1 e1 e1 ++#define e3 e2 e2 e2 e2 e2 e2 e2 e2 e2 e2 ++#define e4 e3 e3 e3 e3 e3 e3 e3 e3 e3 e3 ++#define e5 e4 e4 e4 e4 e4 e4 e4 e4 e4 e4 ++ ++void foo() { (void)(e5); } +--- gcc/c-parse.in.jj 2003-08-02 01:21:40.000000000 +0200 ++++ gcc/c-parse.in 2004-10-05 16:08:18.682530140 +0200 +@@ -148,7 +148,7 @@ end ifobjc + %type BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF + + %type identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist +-%type expr_no_commas cast_expr unary_expr primary string STRING ++%type expr_no_commas cast_expr unary_expr primary STRING + %type declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea + %type declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea + %type declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea +@@ -296,6 +296,7 @@ end ifc + static void yyprint PARAMS ((FILE *, int, YYSTYPE)); + static void yyerror PARAMS ((const char *)); + static int yylexname PARAMS ((void)); ++static int yylexstring PARAMS ((void)); + static inline int _yylex PARAMS ((void)); + static int yylex PARAMS ((void)); + static void init_reswords PARAMS ((void)); +@@ -623,8 +624,8 @@ primary: + $$ = build_external_ref ($1, yychar == '('); + } + | CONSTANT +- | string +- { $$ = combine_strings ($1); } ++ | STRING ++ { $$ = fix_string_type ($$); } + | VAR_FUNC_NAME + { $$ = fname_decl (C_RID_CODE ($$), $$); } + | '(' typename ')' '{' +@@ -735,29 +736,6 @@ ifobjc + end ifobjc + ; + +-/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ +-string: +- STRING +- | string STRING +- { +-ifc +- static int last_lineno = 0; +- static const char *last_input_filename = 0; +-end ifc +- $$ = chainon ($1, $2); +-ifc +- if (warn_traditional && !in_system_header +- && (lineno != last_lineno || !last_input_filename || +- strcmp (last_input_filename, input_filename))) +- { +- warning ("traditional C rejects string concatenation"); +- last_lineno = lineno; +- last_input_filename = input_filename; +- } +-end ifc +- } +- ; +- + ifobjc + /* Produces an STRING_CST with perhaps more STRING_CSTs chained + onto it, which is to be read as an ObjC string object. */ +@@ -1398,10 +1376,8 @@ notype_initdecls: + maybeasm: + /* empty */ + { $$ = NULL_TREE; } +- | ASM_KEYWORD '(' string ')' +- { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); +- $$ = $3; +- } ++ | ASM_KEYWORD '(' STRING ')' ++ { $$ = $3; } + ; + + initdcl: +@@ -2482,10 +2458,10 @@ asm_operand: + ; + + asm_clobbers: +- string +- { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); } +- | asm_clobbers ',' string +- { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); } ++ STRING ++ { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } ++ | asm_clobbers ',' STRING ++ { $$ = tree_cons (NULL_TREE, $3, $1); } + ; + + /* This is what appears inside the parens in a function declarator. +@@ -3683,6 +3659,59 @@ end ifobjc + return IDENTIFIER; + } + ++/* Concatenate strings before returning them to the parser. This isn't quite ++ as good as having it done in the lexer, but it's better than nothing. */ ++ ++static int ++yylexstring () ++{ ++ enum cpp_ttype next_type; ++ tree orig = yylval.ttype; ++ ++ next_type = c_lex (&yylval.ttype); ++ if (next_type == CPP_STRING ++ || next_type == CPP_WSTRING ++ || (next_type == CPP_NAME && yylexname () == STRING)) ++ { ++ varray_type strings; ++ ++ifc ++ static int last_lineno = 0; ++ static const char *last_input_filename = 0; ++ if (warn_traditional && !in_system_header ++ && (lineno != last_lineno || !last_input_filename || ++ strcmp (last_input_filename, input_filename))) ++ { ++ warning ("traditional C rejects string concatenation"); ++ last_lineno = lineno; ++ last_input_filename = input_filename; ++ } ++end ifc ++ ++ VARRAY_TREE_INIT (strings, 32, "strings"); ++ VARRAY_PUSH_TREE (strings, orig); ++ ++ do ++ { ++ VARRAY_PUSH_TREE (strings, yylval.ttype); ++ next_type = c_lex (&yylval.ttype); ++ } ++ while (next_type == CPP_STRING ++ || next_type == CPP_WSTRING ++ || (next_type == CPP_NAME && yylexname () == STRING)); ++ ++ yylval.ttype = combine_strings (strings); ++ ++ VARRAY_FREE (strings); ++ } ++ else ++ yylval.ttype = orig; ++ ++ /* We will have always read one token too many. */ ++ _cpp_backup_tokens (parse_in, 1); ++ ++ return STRING; ++} + + static inline int + _yylex () +@@ -3749,7 +3778,13 @@ _yylex () + return 0; + + case CPP_NAME: +- return yylexname (); ++ { ++ int ret = yylexname (); ++ if (ret == STRING) ++ return yylexstring (); ++ else ++ return ret; ++ } + + case CPP_NUMBER: + case CPP_CHAR: +@@ -3758,7 +3793,7 @@ _yylex () + + case CPP_STRING: + case CPP_WSTRING: +- return STRING; ++ return yylexstring (); + + /* This token is Objective-C specific. It gives the next token + special significance. */ +--- gcc/c-typeck.c.jj 2003-03-10 17:42:06.000000000 +0100 ++++ gcc/c-typeck.c 2004-10-05 16:08:48.926153031 +0200 +@@ -6890,9 +6890,6 @@ simple_asm_stmt (expr) + { + tree stmt; + +- if (TREE_CHAIN (expr)) +- expr = combine_strings (expr); +- + /* Simple asm statements are treated as volatile. */ + stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE], + expr, NULL_TREE, NULL_TREE, NULL_TREE)); +@@ -6917,8 +6914,6 @@ build_asm_stmt (cv_qualifier, string, ou + { + tree tail; + +- if (TREE_CHAIN (string)) +- string = combine_strings (string); + if (TREE_CODE (string) != STRING_CST) + { + error ("asm template is not a string constant"); diff --git a/SOURCES/gcc32-rh149250.patch b/SOURCES/gcc32-rh149250.patch new file mode 100644 index 0000000..4ef4284 --- /dev/null +++ b/SOURCES/gcc32-rh149250.patch @@ -0,0 +1,59 @@ +2002-09-08 Jan Hubicka + + * loop.c (loop_givs_reduce): Emit addition after. + +2005-07-19 Jakub Jelinek + + * g77.dg/20050719-1.f: New test. + +--- gcc/loop.c.jj 2003-10-06 12:15:37.000000000 +0200 ++++ gcc/loop.c 2005-07-19 11:49:08.000000000 +0200 +@@ -4684,7 +4684,7 @@ loop_givs_reduce (loop, bl) + rtx insert_before; + + if (! auto_inc_opt) +- insert_before = tv->insn; ++ insert_before = NEXT_INSN (tv->insn); + else if (auto_inc_opt == 1) + insert_before = NEXT_INSN (v->insn); + else +--- gcc/testsuite/g77.dg/20050719-1.f.jj 2005-07-19 12:00:18.000000000 +0200 ++++ gcc/testsuite/g77.dg/20050719-1.f 2005-07-19 12:01:31.000000000 +0200 +@@ -0,0 +1,37 @@ ++C Test for a strength reduction bug. ++C { dg-do run } ++C { dg-options "-O2 -fno-automatic" } ++ SUBROUTINE FOO(D) ++ INTEGER A,B,C,D,E,I,J,K ++ DIMENSION A(5,5),B(5,5),C(5,5),D(5,5) ++ DO I=1,5 ++ DO J=1,5 ++ A(I,J)=J ++ B(I,J)=1 ++ ENDDO ++ ENDDO ++ DO I=1,5 ++ DO J=1,5 ++ E=0 ++ DO K=1,5 ++ E=E+B(I,K)*A(K,J) ++ ENDDO ++ C(I,J)=E ++ ENDDO ++ ENDDO ++ DO I=1,5 ++ DO J=1,5 ++ D(I,J)=C(I,J) ++ ENDDO ++ ENDDO ++ END ++ ++ INTEGER D,I,J ++ DIMENSION D(5,5) ++ CALL FOO(D) ++ DO I=1,5 ++ DO J=1,5 ++ IF (D(I,J).NE.5*J) CALL ABORT ++ ENDDO ++ ENDDO ++ END diff --git a/SOURCES/gcc32-rh156185.patch b/SOURCES/gcc32-rh156185.patch new file mode 100644 index 0000000..87001a7 --- /dev/null +++ b/SOURCES/gcc32-rh156185.patch @@ -0,0 +1,51 @@ +2005-09-26 Alexandre Oliva + + 2002-08-13 Mark Mitchell + * decl.c (pushdecl_class_level): Honor requests to bind names to + OVERLOADs. + +2005-09-26 Alexandre Oliva + + * g++.dg/lookup/overload1.C: New. + +--- gcc/cp/decl.c.orig ++++ gcc/cp/decl.c +@@ -4369,8 +4369,9 @@ pushdecl_class_level (x) + register tree name; + + if (TREE_CODE (x) == OVERLOAD) +- x = OVL_CURRENT (x); +- name = DECL_NAME (x); ++ name = DECL_NAME (OVL_CURRENT (x)); ++ else ++ name = DECL_NAME (x); + + if (name) + { +--- gcc/testsuite/g++.dg/lookup/overload1.C ++++ gcc/testsuite/g++.dg/lookup/overload1.C +@@ -0,0 +1,24 @@ ++// { dg-do compile } ++ ++// This used to crash expanding the initializer, because instead of ++// pushing the OVERLOAD containing template and function decls, we'd ++// push only the first member of the overload list. The code below is ++// from the bug report at ++// https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=156185 ++ ++struct C { ++ template< class N > ++ static C *newInstance() { return new N; }; ++}; ++ ++typedef C*( *CreateFunc)(); ++ ++struct B { ++ B( CreateFunc _createf ){} ++}; ++ ++struct A : C { ++ static B b; ++}; ++ ++B A::b( newInstance ); diff --git a/SOURCES/gcc32-rh156291.patch b/SOURCES/gcc32-rh156291.patch new file mode 100644 index 0000000..d11f900 --- /dev/null +++ b/SOURCES/gcc32-rh156291.patch @@ -0,0 +1,29 @@ +2005-09-29 Alexandre Oliva + + * error.c (dump_type) : Print reworded message. + + * g++.dg/overload/unknown1.C: New. + +--- gcc/cp/error.c.orig 2005-09-29 16:02:59.000000000 -0300 ++++ gcc/cp/error.c 2005-09-29 16:03:13.000000000 -0300 +@@ -339,7 +339,7 @@ + switch (TREE_CODE (t)) + { + case UNKNOWN_TYPE: +- print_identifier (scratch_buffer, ""); ++ print_identifier (scratch_buffer, ""); + break; + + case TREE_LIST: +--- gcc/testsuite/g++.dg/overload/unknown1.C 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/g++.dg/overload/unknown1.C 2005-09-29 16:03:13.000000000 -0300 +@@ -0,0 +1,9 @@ ++// { dg-do compile } ++ ++void foo(void); ++int foo(int); ++template void bar(T f); ++ ++void baz() { ++ bar(foo); // { dg-error "" } ++} diff --git a/SOURCES/gcc32-rh173224.patch b/SOURCES/gcc32-rh173224.patch new file mode 100644 index 0000000..523f1b5 --- /dev/null +++ b/SOURCES/gcc32-rh173224.patch @@ -0,0 +1,58 @@ +2005-01-09 Alexandre Oliva + + * config/i386/i386.md: Adjust sse conditional move patterns to + match both nonimm® and reg&nonimm in compare operands. + +2006-04-25 Jakub Jelinek + + * gcc.dg/20060425-1.c: New test. + +--- gcc/config/i386/i386.md 2005-10-24 18:18:40.000000000 -0200 ++++ gcc/config/i386/i386.md 2006-01-09 16:16:06.000000000 -0200 +@@ -16815,25 +16815,30 @@ + (define_split + [(set (match_operand 0 "register_operand" "") + (if_then_else (match_operator 1 "comparison_operator" +- [(match_operand 4 "register_operand" "") ++ [(match_operand 4 "nonimmediate_operand" "") + (match_operand 5 "nonimmediate_operand" "")]) + (match_operand 2 "nonmemory_operand" "") + (match_operand 3 "nonmemory_operand" "")))] + "SSE_REG_P (operands[0]) && reload_completed ++ && ((REG_P (operands[4]) && REGNO (operands[4]) == REGNO (operands[0])) ++ || (REG_P (operands[5]) && REGNO (operands[5]) == REGNO (operands[0]))) + && (const0_operand (operands[2], GET_MODE (operands[0])) + || const0_operand (operands[3], GET_MODE (operands[0])))" +- [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)])) ++ [(set (match_dup 0) (match_op_dup 1 [(match_dup 4) (match_dup 5)])) + (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6) + (subreg:TI (match_dup 7) 0)))] + { + PUT_MODE (operands[1], GET_MODE (operands[0])); +- if (!sse_comparison_operator (operands[1], VOIDmode)) ++ if (REGNO (operands[4]) != REGNO (operands[0]) ++ || !sse_comparison_operator (operands[1], VOIDmode)) + { + rtx tmp = operands[5]; + operands[5] = operands[4]; + operands[4] = tmp; + PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1]))); + } ++ if (!sse_comparison_operator (operands[1], VOIDmode)) ++ abort (); + if (const0_operand (operands[2], GET_MODE (operands[0]))) + { + operands[7] = operands[3]; +--- gcc/testsuite/gcc.dg/20060425-1.c 2004-06-24 14:04:38.000000000 -0400 ++++ gcc/testsuite/gcc.dg/20060425-1.c 2006-04-25 09:15:04.000000000 -0400 +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2" } */ ++ ++double ++crashme (double v, double *p) ++{ ++ if (v < 0. && *p == 1.) ++ v = 0.; ++ return v; ++} diff --git a/SOURCES/gcc32-rh180778.patch b/SOURCES/gcc32-rh180778.patch new file mode 100644 index 0000000..ae9feb6 --- /dev/null +++ b/SOURCES/gcc32-rh180778.patch @@ -0,0 +1,116 @@ +2005-08-31 Richard Henderson + + * expr.c (expand_expr_real_1) : Force subregs + into a pseudo before applying gen_lowpart. + +2005-08-30 Richard Henderson + + PR target/23630 + * expr.c (expand_expr_real_1) : Use gen_lowpart + whenever the mode sizes match. + +2002-08-19 Geoffrey Keating + Steve Ellcey + + * machmode.h (SCALAR_INT_MODE_P): New macro to test for + scaler integer mode (MODE_INT or MODE_PARTIAL_INT). + +2006-02-22 Alexandre Oliva + + * gcc.dg/i386-mmx-3.c: New test. + +--- gcc/convert.c.orig 2003-08-01 20:24:42.000000000 -0300 ++++ gcc/convert.c 2006-02-24 03:51:35.000000000 -0300 +@@ -398,7 +398,7 @@ convert_to_integer (type, expr) + error ("can't convert between vector values of different size"); + return error_mark_node; + } +- return build1 (NOP_EXPR, type, expr); ++ return build1 (VIEW_CONVERT_EXPR, type, expr); + + default: + error ("aggregate value used where an integer was expected"); +@@ -478,7 +478,7 @@ convert_to_vector (type, expr) + error ("can't convert between vector values of different size"); + return error_mark_node; + } +- return build1 (NOP_EXPR, type, expr); ++ return build1 (VIEW_CONVERT_EXPR, type, expr); + + default: + error ("can't convert value to a vector"); +--- gcc/expr.c.orig 2006-02-22 15:50:38.000000000 -0300 ++++ gcc/expr.c 2006-02-24 04:49:59.000000000 -0300 +@@ -7641,16 +7641,28 @@ expand_expr (exp, target, tmode, modifie + case VIEW_CONVERT_EXPR: + op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier); + +- /* If the input and output modes are both the same, we are done. +- Otherwise, if neither mode is BLKmode and both are within a word, we +- can use gen_lowpart. If neither is true, make sure the operand is +- in memory and convert the MEM to the new mode. */ ++ /* If the input and output modes are both the same, we are done. */ + if (TYPE_MODE (type) == GET_MODE (op0)) + ; ++ /* If neither mode is BLKmode, and both modes are the same size ++ then we can use gen_lowpart. */ + else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode +- && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD +- && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD) +- op0 = gen_lowpart (TYPE_MODE (type), op0); ++ && GET_MODE_SIZE (TYPE_MODE (type)) ++ == GET_MODE_SIZE (GET_MODE (op0))) ++ { ++ if (GET_CODE (op0) == SUBREG) ++ op0 = force_reg (GET_MODE (op0), op0); ++ op0 = gen_lowpart (TYPE_MODE (type), op0); ++ } ++ /* If both modes are integral, then we can convert from one to the ++ other. */ ++ else if (SCALAR_INT_MODE_P (GET_MODE (op0)) ++ && SCALAR_INT_MODE_P (TYPE_MODE (type))) ++ op0 = convert_modes (TYPE_MODE (type), GET_MODE (op0), op0, ++ TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, ++ 0)))); ++ /* As a last resort, spill op0 to memory, and reload it in a ++ different mode. */ + else if (GET_CODE (op0) != MEM) + { + /* If the operand is not a MEM, force it into memory. Since we +--- gcc/machmode.h.orig 2002-02-19 07:13:31.000000000 -0300 ++++ gcc/machmode.h 2006-02-24 04:20:47.000000000 -0300 +@@ -75,6 +75,11 @@ extern const enum mode_class mode_class[ + (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \ + || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT) + ++/* Nonzero if MODE is a scalar integral mode. */ ++#define SCALAR_INT_MODE_P(MODE) \ ++ (GET_MODE_CLASS (MODE) == MODE_INT \ ++ || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT) ++ + /* Get the size in bytes of an object of mode MODE. */ + + extern const unsigned char mode_size[NUM_MACHINE_MODES]; +--- gcc/testsuite/gcc.dg/i386-mmx-3.c 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/gcc.dg/i386-mmx-3.c 2006-02-23 02:06:15.000000000 -0300 +@@ -0,0 +1,20 @@ ++/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ ++/* { dg-options "-O -mmmx" } */ ++ ++#include ++#include ++ ++void x(uint64_t *p_buffer) ++{ ++ __m64 mm0, mm1; ++ ++ mm0 = (__m64)(uint64_t)0; ++ ++ /* This makes no sense whatsoever, it's just the result of ++ minimization of a large testcase. */ ++ mm1 = _mm_srli_pi16(mm0, 0); ++ mm1 = _mm_slli_pi16(mm1, 1); ++ mm0 = _mm_adds_pi16(mm0, mm1); ++ ++ *p_buffer = (uint64_t)mm0; ++} diff --git a/SOURCES/gcc32-rh181894.patch b/SOURCES/gcc32-rh181894.patch new file mode 100644 index 0000000..6f1faef --- /dev/null +++ b/SOURCES/gcc32-rh181894.patch @@ -0,0 +1,133 @@ +2006-08-09 Alexandre Oliva + + * function.c (do_warn_unused_parameter): Do not issue warnings + for declarations in system headers. + +2006-02-22 Alexandre Oliva + + Backport and tweak: + 2004-05-06 Jan Hubicka + PR c/15004 + * function.c (do_warn_unused_parameter): Break out form ... + (expand_function_end): ... here. + * function.h (do_warn_unused_parameter): Declare. + +2006-02-22 Alexandre Oliva + + * decl2.c (finish_file): Issue warnings for unused parameters + of functions not expanded. + + * g++.dg/Wunused-parm-1.C: New. + +--- gcc/cp/decl2.c.orig 2003-08-12 11:12:25.000000000 -0300 ++++ gcc/cp/decl2.c 2006-08-09 16:59:09.000000000 -0300 +@@ -3551,6 +3551,17 @@ finish_file () + } + while (reconsider); + ++ if (warn_unused_parameter) ++ for (i = 0; i < deferred_fns_used; ++i) ++ { ++ tree decl = VARRAY_TREE (deferred_fns, i); ++ ++ /* Warn about unused parameters in functions we refrained from ++ synthesizing. */ ++ if (!TREE_ASM_WRITTEN (decl)) ++ do_warn_unused_parameter (decl); ++ } ++ + /* We give C linkage to static constructors and destructors. */ + push_lang_context (lang_name_c); + +--- gcc/function.c.orig 2003-10-31 08:42:15.000000000 -0200 ++++ gcc/function.c 2006-08-10 00:28:06.000000000 -0300 +@@ -6808,6 +6808,27 @@ use_return_register () + diddle_return_value (do_use_return_reg, NULL); + } + ++/* Warn about unused parms if extra warnings were specified. */ ++/* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this ++ warning. WARN_UNUSED_PARAMETER is negative when set by ++ -Wunused. */ ++void ++do_warn_unused_parameter (tree fn) ++{ ++ if (warn_unused_parameter > 0 ++ || (warn_unused_parameter < 0 && extra_warnings)) ++ { ++ tree decl; ++ ++ for (decl = DECL_ARGUMENTS (fn); ++ decl; decl = TREE_CHAIN (decl)) ++ if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL ++ && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl) ++ && ! DECL_IN_SYSTEM_HEADER (decl)) ++ warning_with_decl (decl, "unused parameter `%s'"); ++ } ++} ++ + /* Generate RTL for the end of the current function. + FILENAME and LINE are the current position in the source file. + +@@ -6907,21 +6928,8 @@ expand_function_end (filename, line, end + } + } + +- /* Warn about unused parms if extra warnings were specified. */ +- /* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this +- warning. WARN_UNUSED_PARAMETER is negative when set by +- -Wunused. */ +- if (warn_unused_parameter > 0 +- || (warn_unused_parameter < 0 && extra_warnings)) +- { +- tree decl; +- +- for (decl = DECL_ARGUMENTS (current_function_decl); +- decl; decl = TREE_CHAIN (decl)) +- if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL +- && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl)) +- warning_with_decl (decl, "unused parameter `%s'"); +- } ++ if (warn_unused_parameter) ++ do_warn_unused_parameter (current_function_decl); + + /* Delete handlers for nonlocal gotos if nothing uses them. */ + if (nonlocal_goto_handler_slots != 0 +--- gcc/function.h.orig 2003-06-11 09:56:49.000000000 -0300 ++++ gcc/function.h 2006-08-09 16:59:09.000000000 -0300 +@@ -614,3 +614,5 @@ extern void init_virtual_regs PARAMS (( + + /* Called once, at initialization, to initialize function.c. */ + extern void init_function_once PARAMS ((void)); ++ ++extern void do_warn_unused_parameter PARAMS ((tree)); +--- gcc/testsuite/g++.dg/warn/Wunused-parm-1.C 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/g++.dg/warn/Wunused-parm-1.C 2006-08-09 16:59:09.000000000 -0300 +@@ -0,0 +1,27 @@ ++// Test whether we issue warnings for unused parameters, even for ++// inline functions that are not emitted (without optimization, we ++// always emit them). ++// { dg-do compile } ++// { dg-options "-Wunused-parameter -O" } ++ ++static inline int foo(int var) { // { dg-warning "unused parameter" } ++ return 0; ++} ++ ++static inline int foo2(int var) { // { dg-warning "unused parameter" } ++ return 0; ++} ++ ++static inline int bar(int var) { ++ return var; ++} ++ ++static inline int bar2(int var) { ++ return var; ++} ++ ++int main() { ++ foo (1); ++ bar (2); ++ return 0; ++} diff --git a/SOURCES/gcc32-rh186252.patch b/SOURCES/gcc32-rh186252.patch new file mode 100644 index 0000000..c2e1544 --- /dev/null +++ b/SOURCES/gcc32-rh186252.patch @@ -0,0 +1,117 @@ +2004-05-01 Ulrich Weigand + + PR middle-end/15054 + * expr.c (expand_expr_real): Do not call preserve_temp_slots + on a TARGET_EXPR temp. + * function.c (assign_stack_temp_for_type): Set 'keep' flag for + TARGET_EXPR temp slots. + + * g++.dg/opt/pr15054.C: New test. + +2006-04-25 Jakub Jelinek + + * g++.dg/opt/pr15054-2.C: New test. + +--- gcc/expr.c.orig 2006-02-24 04:51:46.000000000 -0300 ++++ gcc/expr.c 2006-04-11 03:53:02.000000000 -0300 +@@ -8676,8 +8676,6 @@ expand_expr (exp, target, tmode, modifie + else + { + target = assign_temp (type, 2, 0, 1); +- /* All temp slots at this level must not conflict. */ +- preserve_temp_slots (target); + SET_DECL_RTL (slot, target); + if (TREE_ADDRESSABLE (slot)) + put_var_into_stack (slot); +--- gcc/function.c.orig 2006-02-24 04:51:52.000000000 -0300 ++++ gcc/function.c 2006-04-11 03:53:02.000000000 -0300 +@@ -803,7 +803,7 @@ assign_stack_temp_for_type (mode, size, + if (keep == 2) + { + p->level = target_temp_slot_level; +- p->keep = 0; ++ p->keep = 1; + } + else if (keep == 3) + { +--- gcc/testsuite/g++.dg/opt/pr15054.C 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/g++.dg/opt/pr15054.C 2006-04-11 03:54:31.000000000 -0300 +@@ -0,0 +1,36 @@ ++// PR middle-end/15054 ++// This used to abort due to overlapping stack temporaries. ++ ++// { dg-do run } ++// { dg-options "-O" } ++ ++extern "C" void abort (void); ++ ++struct pointer ++{ ++ void* ptr; ++ ++ pointer(void* x = 0) : ptr(x) {} ++ pointer(const pointer& x) : ptr(x.ptr) {} ++}; ++ ++struct element ++{ ++ int canary; ++ ++ element() : canary(123) { } ++ ~element() { pointer(); if (canary != 123) abort (); } ++}; ++ ++inline pointer ++insert(const element& x) ++{ ++ return pointer(new element(x)); ++} ++ ++int ++main (void) ++{ ++ insert(element()); ++ return 0; ++} +--- gcc/testsuite/g++.dg/opt/pr15054-2.C 2006-04-19 19:21:31.748476000 +0200 ++++ gcc/testsuite/g++.dg/opt/pr15054-2.C 2006-04-25 15:55:07.000000000 +0200 +@@ -0,0 +1,39 @@ ++// PR middle-end/15054 ++ ++// { dg-do run } ++// { dg-options "-O2" } ++ ++extern "C" void abort (void); ++ ++void ++__attribute__((noinline)) ++check (long x, long y) ++{ ++ if (x != y) ++ abort (); ++} ++ ++struct A ++{ ++ A() : a(2) { check (a, 2); } ++ ~A() { check (a, 2); } ++private: ++ long a; ++}; ++ ++class B { ++ long b; ++ B& operator =(const B& ); ++public: ++ B (long p) : b(p) { check (b, 6); } ++ B (const B& p) : b(p.b) { check (b, 6); } ++ ~B () { check (b, 6); A obj; check (b, 6); } ++ B foo() { return B(*this); } ++}; ++ ++int main () ++{ ++ B o(6); ++ o.foo().foo(); ++ return 0; ++} diff --git a/SOURCES/gcc32-rh226706.patch b/SOURCES/gcc32-rh226706.patch new file mode 100644 index 0000000..2091e8f --- /dev/null +++ b/SOURCES/gcc32-rh226706.patch @@ -0,0 +1,37 @@ +2007-02-13 Alexandre Oliva + + * reload1.c (fixup_abnormal_edges): Backport relevant portion of + fix for PR rtl-optimization/23601. + + * g++.dg/eh/bz226706.C: New + +--- gcc/reload1.c 2006-10-13 04:32:14.000000000 -0300 ++++ gcc/reload1.c 2007-02-13 03:22:08.000000000 -0200 +@@ -9524,7 +9524,10 @@ fixup_abnormal_edges () + && insn != bb->head) + insn = PREV_INSN (insn); + if (GET_CODE (insn) != CALL_INSN && !can_throw_internal (insn)) +- abort (); ++ { ++ purge_dead_edges (bb); ++ continue; ++ } + bb->end = insn; + inserted = true; + insn = NEXT_INSN (insn); +--- gcc/testsuite/g++.dg/eh/bz226706.C 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/g++.dg/eh/bz226706.C 2007-02-13 03:30:16.000000000 -0200 +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-fnon-call-exceptions -fPIC -O2" } */ ++ ++void foo() { ++ try { ++ float y = 10; ++ while (y > 0) { ++ double z = (y / 10); ++ y = z; ++ } ++ } ++ catch (...) {} ++} diff --git a/SOURCES/gcc32-s390-reload-dup.patch b/SOURCES/gcc32-s390-reload-dup.patch new file mode 100644 index 0000000..d751a7c --- /dev/null +++ b/SOURCES/gcc32-s390-reload-dup.patch @@ -0,0 +1,77 @@ +2002-09-26 Ulrich Weigand + + * reload.c (dup_replacements): New function. + (find_reloads): Use it to duplicate replacements at the top level + of match_dup operands. + +2004-10-25 Jakub Jelinek + + * gcc.c-torture/execute/20041025-1.c: New test. + +--- gcc/reload.c.jj 2003-04-08 15:51:07.000000000 +0200 1.190 ++++ gcc/reload.c 2004-10-25 13:10:48.056167117 +0200 1.191 +@@ -244,6 +244,7 @@ static enum reg_class find_valid_class P + unsigned int)); + static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode, int)); + static void push_replacement PARAMS ((rtx *, int, enum machine_mode)); ++static void dup_replacements PARAMS ((rtx *, rtx *)); + static void combine_reloads PARAMS ((void)); + static int find_reusable_reload PARAMS ((rtx *, rtx, enum reg_class, + enum reload_type, int, int)); +@@ -1578,6 +1579,25 @@ push_replacement (loc, reloadnum, mode) + r->mode = mode; + } + } ++ ++/* Duplicate any replacement we have recorded to apply at ++ location ORIG_LOC to also be performed at DUP_LOC. ++ This is used in insn patterns that use match_dup. */ ++ ++static void ++dup_replacements (dup_loc, orig_loc) ++ rtx *dup_loc; ++ rtx *orig_loc; ++{ ++ int i, n = n_replacements; ++ ++ for (i = 0; i < n; i++) ++ { ++ struct replacement *r = &replacements[i]; ++ if (r->where == orig_loc) ++ push_replacement (dup_loc, r->what, r->mode); ++ } ++} + + /* Transfer all replacements that used to be in reload FROM to be in + reload TO. */ +@@ -3969,9 +3989,7 @@ find_reloads (insn, replace, ind_levels, + { + int opno = recog_data.dup_num[i]; + *recog_data.dup_loc[i] = *recog_data.operand_loc[opno]; +- if (operand_reloadnum[opno] >= 0) +- push_replacement (recog_data.dup_loc[i], operand_reloadnum[opno], +- insn_data[insn_code_number].operand[opno].mode); ++ dup_replacements (recog_data.dup_loc[i], recog_data.operand_loc[opno]); + } + + #if 0 +--- gcc/testsuite/gcc.c-torture/execute/20041025-1.c.jj 2004-10-25 13:13:28.604657996 +0200 ++++ gcc/testsuite/gcc.c-torture/execute/20041025-1.c 2004-10-25 13:11:43.119389360 +0200 +@@ -0,0 +1,17 @@ ++extern void abort (void); ++ ++void ++foo (int a, int b, int c, int d, int e, void **f) ++{ ++ char g[4096]; ++ if (f == 0 || *f != 0) ++ abort (); ++} ++ ++int ++main (void) ++{ ++ void *x = 0; ++ foo (0, 1, 2, 3, 4, &x); ++ return 0; ++} diff --git a/SOURCES/gcc32-s390x-compile.patch b/SOURCES/gcc32-s390x-compile.patch new file mode 100644 index 0000000..7f6ad4b --- /dev/null +++ b/SOURCES/gcc32-s390x-compile.patch @@ -0,0 +1,10 @@ +--- gcc/builtins.c.jj 2004-02-28 06:14:54.000000000 -0500 ++++ gcc/builtins.c 2006-08-10 06:35:16.000000000 -0400 +@@ -41,6 +41,7 @@ Software Foundation, 59 Temple Place - S + #include "predict.h" + #include "tm_p.h" + #include "target.h" ++#include "integrate.h" + + #define CALLED_AS_BUILT_IN(NODE) \ + (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10)) diff --git a/SOURCES/gcc32-tablejump-cleanup.patch b/SOURCES/gcc32-tablejump-cleanup.patch new file mode 100644 index 0000000..f26a2fa --- /dev/null +++ b/SOURCES/gcc32-tablejump-cleanup.patch @@ -0,0 +1,222 @@ +2005-01-03 Jakub Jelinek + + * cfgrtl.c (try_redirect_by_replacing_jump): Add 2 arguments to + tablejump_p. + + * gcc.c-torture/compile/20050103-1.c: New test. + +2003-07-20 Josef Zlomek + + * cfgcleanup.c (merge_blocks_move_successor_nojumps): Use tablejump_p. + * ifcvt.c (find_if_block): Added 2 arguments to tablejump_p. + * jump.c (tablejump_p): Added 2 arguments. + * rtl.h (tablejump_p): Likewise. + +--- gcc/rtl.h.jj 2003-06-11 14:58:17.000000000 +0200 ++++ gcc/rtl.h 2005-01-03 17:32:46.113937897 +0100 +@@ -1793,7 +1793,7 @@ extern rtx pc_set PARAMS ((rtx)); + extern rtx condjump_label PARAMS ((rtx)); + extern int simplejump_p PARAMS ((rtx)); + extern int returnjump_p PARAMS ((rtx)); +-extern int tablejump_p PARAMS ((rtx)); ++extern int tablejump_p PARAMS ((rtx, rtx *, rtx *)); + extern int onlyjump_p PARAMS ((rtx)); + extern int only_sets_cc0_p PARAMS ((rtx)); + extern int sets_cc0_p PARAMS ((rtx)); +--- gcc/cfgrtl.c.jj 2003-04-08 15:50:58.000000000 +0200 ++++ gcc/cfgrtl.c 2005-01-03 17:37:59.150837447 +0100 +@@ -674,7 +674,7 @@ try_redirect_by_replacing_jump (e, targe + if (tmp || !onlyjump_p (insn)) + return false; + +- if ((!optimize || flow2_completed) && tablejump_p (insn)) ++ if ((!optimize || flow2_completed) && tablejump_p (insn, NULL, NULL)) + return false; + + /* Avoid removing branch with side effects. */ +--- gcc/cfgcleanup.c.jj 2003-08-02 01:18:22.000000000 +0200 ++++ gcc/cfgcleanup.c 2005-01-03 17:32:10.010407336 +0100 +@@ -691,25 +691,20 @@ merge_blocks_move_successor_nojumps (a, + basic_block a, b; + { + rtx barrier, real_b_end; ++ rtx label, table; + + real_b_end = b->end; +- barrier = NEXT_INSN (b->end); + +- /* Recognize a jump table following block B. */ +- if (barrier +- && GET_CODE (barrier) == CODE_LABEL +- && NEXT_INSN (barrier) +- && GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN +- && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC +- || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC)) ++ /* If there is a jump table following block B temporarily add the jump table ++ to block B so that it will also be moved to the correct location. */ ++ if (tablejump_p (b->end, &label, &table) ++ && prev_active_insn (label) == b->end) + { +- /* Temporarily add the table jump insn to b, so that it will also +- be moved to the correct location. */ +- b->end = NEXT_INSN (barrier); +- barrier = NEXT_INSN (b->end); ++ b->end = table; + } + + /* There had better have been a barrier there. Delete it. */ ++ barrier = NEXT_INSN (b->end); + if (barrier && GET_CODE (barrier) == BARRIER) + delete_insn (barrier); + +--- gcc/jump.c.jj 2003-08-01 22:38:45.000000000 +0200 ++++ gcc/jump.c 2005-01-03 17:36:59.744484787 +0100 +@@ -1099,20 +1099,32 @@ simplejump_p (insn) + && GET_CODE (SET_DEST (PATTERN (insn))) == PC + && GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF); + } +-/* Return 1 if INSN is an tablejump. */ ++ ++/* If INSN is a tablejump return 1 and store the label (before jump table) to ++ *LABELP and the jump table to *TABLEP. LABELP and TABLEP may be NULL. */ + + int +-tablejump_p (insn) ++tablejump_p (insn, labelp, tablep) + rtx insn; ++ rtx *labelp; ++ rtx *tablep; + { +- rtx table; +- return (GET_CODE (insn) == JUMP_INSN +- && JUMP_LABEL (insn) +- && NEXT_INSN (JUMP_LABEL (insn)) +- && (table = next_active_insn (JUMP_LABEL (insn))) +- && GET_CODE (table) == JUMP_INSN +- && (GET_CODE (PATTERN (table)) == ADDR_VEC +- || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC)); ++ rtx label, table; ++ ++ if (GET_CODE (insn) == JUMP_INSN ++ && (label = JUMP_LABEL (insn)) != NULL_RTX ++ && (table = next_active_insn (label)) != NULL_RTX ++ && GET_CODE (table) == JUMP_INSN ++ && (GET_CODE (PATTERN (table)) == ADDR_VEC ++ || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC)) ++ { ++ if (labelp) ++ *labelp = label; ++ if (tablep) ++ *tablep = table; ++ return 1; ++ } ++ return 0; + } + + /* Return nonzero if INSN is a (possibly) conditional jump +--- gcc/ifcvt.c.jj 2003-03-25 17:42:24.000000000 +0100 ++++ gcc/ifcvt.c 2005-01-03 17:32:10.012406978 +0100 +@@ -2046,7 +2046,7 @@ find_if_block (test_bb, then_edge, else_ + if (then_succ != NULL_EDGE + && (then_succ->succ_next != NULL_EDGE + || (then_succ->flags & EDGE_COMPLEX) +- || (flow2_completed && tablejump_p (then_bb->end)))) ++ || (flow2_completed && tablejump_p (then_bb->end, NULL, NULL)))) + return FALSE; + + /* If the THEN block has no successors, conditional execution can still +@@ -2094,7 +2094,7 @@ find_if_block (test_bb, then_edge, else_ + && else_bb->pred->pred_next == NULL_EDGE + && else_succ->succ_next == NULL_EDGE + && ! (else_succ->flags & EDGE_COMPLEX) +- && ! (flow2_completed && tablejump_p (else_bb->end))) ++ && ! (flow2_completed && tablejump_p (else_bb->end, NULL, NULL))) + join_bb = else_succ->dest; + + /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */ +--- gcc/testsuite/gcc.c-torture/compile/20050103-1.c.jj 2004-12-09 13:34:01.422415552 +0100 ++++ gcc/testsuite/gcc.c-torture/compile/20050103-1.c 2005-01-03 15:21:18.146431991 +0100 +@@ -0,0 +1,83 @@ ++extern void abort (void); ++ ++struct S ++{ ++ char *s1; ++ int s2; ++}; ++struct T ++{ ++ int t1; ++ struct S *t2; ++} *s1; ++ ++extern int bar (const struct T *, unsigned int, unsigned int, ++ const struct T *, unsigned int, unsigned int); ++ ++extern inline void * ++baz (void *x, const void *y, unsigned int z) ++{ ++ unsigned char *s1 = x; ++ const unsigned char *s2 = y; ++ ++ if (z > 4 || __builtin_constant_p (z)) ++ __builtin_memcpy (x, y, z); ++ else ++ switch (z) ++ { ++ case 4: ++ s1[3] = s2[3]; ++ case 3: ++ s1[2] = s2[2]; ++ case 2: ++ s1[1] = s2[1]; ++ case 1: ++ s1[0] = s2[0]; ++ case 0: ++ break; ++ } ++ ++ return x; ++} ++ ++extern inline int ++foo (struct T *b, unsigned int x, const void *y, unsigned int z) ++{ ++ if (!b || !z) ++ return 0; ++ if (x == b->t1) ++ { ++ struct S *r = b->t2; ++ baz (r->s1 + r->s2, y, z); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int ++test (struct T *a, struct T *b, struct T *c, struct T *d) ++{ ++ if (!a) ++ abort (); ++ if (!b) ++ abort (); ++ ++ if (bar (a, 1, a->t1, b, 1, b->t1) > 0) ++ abort (); ++ if (bar (a, 41, a->t1 - 40, b, 1, b->t1) > 0) ++ abort (); ++ ++ if (!c) ++ abort (); ++ if (!d) ++ abort (); ++ ++ if (bar (c, 1, c->t1, d, 1, d->t1) < 0) ++ abort (); ++ if (bar (c, 41, c->t1 - 40, d, 1, d->t1) < 0) ++ abort (); ++ ++ foo (s1, 0, "abcd", 4); ++ return 0; ++} diff --git a/SOURCES/gcc32-weakref.patch b/SOURCES/gcc32-weakref.patch new file mode 100644 index 0000000..49af1e5 --- /dev/null +++ b/SOURCES/gcc32-weakref.patch @@ -0,0 +1,859 @@ +2005-11-16 Alexandre Oliva + + * attribs.c (handle_weakref_attribute): New. + (c_common_attribute_table): Add weakref. + * defaults.h (ASM_OUTPUT_WEAKREF): Define. + * doc/extend.texi: Document weakref attribute. + * varasm.c (do_assemble_alias): Handle weakrefs. + (finish_aliases_1): Do not reject weakrefs to external symbols. + * gthr-posix.h: Define __gthrw. For all identifiers that + might be weak, introduce weakrefs or non-weak aliases with + __gthrw, and prefix all uses with __ghtrw. + * config/rs6000/rs6000.h (ASM_OUTPUT_WEAKREF): Define. + + * g++.old-deja/g++.ext/weakref1.C: New test. + * g++.old-deja/g++.ext/weakref1a.cc: New helper file. + +--- gcc/defaults.h.orig 2005-11-15 19:55:42.000000000 -0200 ++++ gcc/defaults.h 2005-11-16 13:38:28.000000000 -0200 +@@ -156,6 +156,25 @@ + #endif + #endif + ++/* This is how we tell the assembler that a symbol is a weak alias to ++ another symbol that doesn't require the other symbol to be defined. ++ Uses of the former will turn into weak uses of the latter, i.e., ++ uses that, in case the latter is undefined, will not cause errors, ++ and will add it to the symbol table as weak undefined. However, if ++ the latter is referenced directly, a strong reference prevails. */ ++#ifndef ASM_OUTPUT_WEAKREF ++#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE) \ ++ do \ ++ { \ ++ fprintf ((FILE), "\t.weakref\t"); \ ++ assemble_name ((FILE), (NAME)); \ ++ fprintf ((FILE), ","); \ ++ assemble_name ((FILE), (VALUE)); \ ++ fprintf ((FILE), "\n"); \ ++ } \ ++ while (0) ++#endif ++ + /* This determines whether or not we support weak symbols. */ + #ifndef SUPPORTS_WEAK + #if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) +--- gcc/doc/extend.texi.orig 2005-11-15 19:55:42.000000000 -0200 ++++ gcc/doc/extend.texi 2005-11-15 19:55:48.000000000 -0200 +@@ -2217,6 +2217,38 @@ + for ELF targets, and also for a.out targets when using the GNU assembler + and linker. + ++@item weakref ++@itemx weakref ("@var{target}") ++@cindex @code{weakref} attribute ++The @code{weakref} attribute marks a declaration as a weak reference. ++Without arguments, it should be accompanied by an @code{alias} attribute ++naming the target symbol. Optionally, the @var{target} may be given as ++an argument to @code{weakref} itself. In either case, @code{weakref} ++implicitly marks the declaration as @code{weak}. Without a ++@var{target}, given as an argument to @code{weakref} or to @code{alias}, ++@code{weakref} is equivalent to @code{weak}. ++ ++@smallexample ++extern int x() __attribute__ ((weakref ("y"))); ++/* is equivalent to... */ ++extern int x() __attribute__ ((weak, weakref, alias ("y"))); ++/* and to... */ ++extern int x() __attribute__ ((weakref)); ++extern int x() __attribute__ ((alias ("y"))); ++@end smallexample ++ ++A weak reference is an alias that does not by itself require a ++definition to be given for the target symbol. If the target symbol is ++only referenced through weak references, then the becomes a @code{weak} ++undefined symbol. If it is directly referenced, however, then such ++strong references prevail, and a definition will be required for the ++symbol, not necessarily in the same translation unit. ++ ++The effect is equivalent to moving all references to the alias to a ++separate translation unit, renaming the alias to the aliased symbol, ++declaring it as weak, compiling the two separate translation units and ++performing a reloadable link on them. ++ + @item malloc + @cindex @code{malloc} attribute + The @code{malloc} attribute is used to tell the compiler that a function +--- gcc/gthr-posix.h.orig 2005-11-15 19:55:42.000000000 -0200 ++++ gcc/gthr-posix.h 2005-11-15 19:55:48.000000000 -0200 +@@ -43,6 +43,42 @@ + #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER + #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT + ++#if SUPPORTS_WEAK && GTHREAD_USE_WEAK && defined __GNUC_RH_RELEASE__ && __GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 3 && __GNUC_RH_RELEASE__ > 53 && !defined __attribute__ ++# define __gthrw(name) \ ++ extern __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name))) ++ ++__gthrw(pthread_once); ++__gthrw(pthread_key_create); ++__gthrw(pthread_key_delete); ++__gthrw(pthread_getspecific); ++__gthrw(pthread_setspecific); ++__gthrw(pthread_create); ++ ++__gthrw(pthread_mutex_lock ); ++__gthrw(pthread_mutex_trylock ); ++__gthrw(pthread_mutex_unlock ); ++ ++#ifdef _LIBOBJC ++/* Objective C. */ ++__gthrw(pthread_cond_broadcast); ++__gthrw(pthread_cond_destroy); ++__gthrw(pthread_cond_init); ++__gthrw(pthread_cond_signal); ++__gthrw(pthread_cond_wait); ++__gthrw(pthread_exit); ++__gthrw(pthread_mutex_init); ++__gthrw(pthread_mutex_destroy); ++__gthrw(pthread_self); ++__gthrw(sched_get_priority_max); ++__gthrw(sched_get_priority_min); ++__gthrw(sched_yield); ++__gthrw(pthread_attr_destroy); ++__gthrw(pthread_attr_init); ++__gthrw(pthread_attr_setdetachstate); ++__gthrw(pthread_getschedparam); ++__gthrw(pthread_setschedparam); ++#endif ++#else + #if SUPPORTS_WEAK && GTHREAD_USE_WEAK + + #pragma weak pthread_once +@@ -76,11 +112,47 @@ + #pragma weak pthread_getschedparam + #pragma weak pthread_setschedparam + #endif ++#endif ++ ++#define __gthrw_pthread_once pthread_once ++#define __gthrw_pthread_key_create pthread_key_create ++#define __gthrw_pthread_key_delete pthread_key_delete ++#define __gthrw_pthread_getspecific pthread_getspecific ++#define __gthrw_pthread_setspecific pthread_setspecific ++#define __gthrw_pthread_create pthread_create ++ ++#define __gthrw_pthread_mutex_lock pthread_mutex_lock ++#define __gthrw_pthread_mutex_trylock pthread_mutex_trylock ++#define __gthrw_pthread_mutex_unlock pthread_mutex_unlock ++ ++#ifdef _LIBOBJC ++/* Objective C. */ ++#define __gthrw_pthread_cond_broadcast pthread_cond_broadcast ++#define __gthrw_pthread_cond_destroy pthread_cond_destroy ++#define __gthrw_pthread_cond_init pthread_cond_init ++#define __gthrw_pthread_cond_signal pthread_cond_signal ++#define __gthrw_pthread_cond_wait pthread_cond_wait ++#define __gthrw_pthread_exit pthread_exit ++#define __gthrw_pthread_mutex_init pthread_mutex_init ++#define __gthrw_pthread_mutex_destroy pthread_mutex_destroy ++#define __gthrw_pthread_self pthread_self ++#define __gthrw_sched_get_priority_max sched_get_priority_max ++#define __gthrw_sched_get_priority_min sched_get_priority_min ++#define __gthrw_sched_yield sched_yield ++#define __gthrw_pthread_attr_destroy pthread_attr_destroy ++#define __gthrw_pthread_attr_init pthread_attr_init ++#define __gthrw_pthread_attr_setdetachstate pthread_attr_setdetachstate ++#define __gthrw_pthread_getschedparam pthread_getschedparam ++#define __gthrw_pthread_setschedparam pthread_setschedparam ++#endif ++#endif ++ ++#if SUPPORTS_WEAK && GTHREAD_USE_WEAK + + static inline int + __gthread_active_p (void) + { +- static void *const __gthread_active_ptr = (void *) &pthread_create; ++ static void *const __gthread_active_ptr = (void *) &__gthrw_pthread_create; + return __gthread_active_ptr != 0; + } + +@@ -119,13 +191,13 @@ + if (__gthread_active_p ()) + { + /* Initialize the thread storage key */ +- if (pthread_key_create(&_objc_thread_storage, NULL) == 0) ++ if (__gthrw_pthread_key_create(&_objc_thread_storage, NULL) == 0) + { + /* The normal default detach state for threads is + * PTHREAD_CREATE_JOINABLE which causes threads to not die + * when you think they should. */ +- if (pthread_attr_init(&_objc_thread_attribs) == 0 +- && pthread_attr_setdetachstate(&_objc_thread_attribs, ++ if (__gthrw_pthread_attr_init(&_objc_thread_attribs) == 0 ++ && __gthrw_pthread_attr_setdetachstate(&_objc_thread_attribs, + PTHREAD_CREATE_DETACHED) == 0) + return 0; + } +@@ -139,8 +211,8 @@ + __gthread_objc_close_thread_system(void) + { + if (__gthread_active_p () +- && pthread_key_delete(_objc_thread_storage) == 0 +- && pthread_attr_destroy(&_objc_thread_attribs) == 0) ++ && __gthrw_pthread_key_delete(_objc_thread_storage) == 0 ++ && __gthrw_pthread_attr_destroy(&_objc_thread_attribs) == 0) + return 0; + + return -1; +@@ -158,7 +230,7 @@ + if (!__gthread_active_p ()) + return NULL; + +- if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) ) ++ if ( !(__gthrw_pthread_create(&new_thread_handle, NULL, (void *)func, arg)) ) + thread_id = (objc_thread_t) new_thread_handle; + else + thread_id = NULL; +@@ -173,17 +245,17 @@ + if (!__gthread_active_p()) + return -1; + else { +- pthread_t thread_id = pthread_self(); ++ pthread_t thread_id = __gthrw_pthread_self(); + int policy; + struct sched_param params; + int priority_min, priority_max; + +- if (pthread_getschedparam(thread_id, &policy, ¶ms) == 0) ++ if (__gthrw_pthread_getschedparam(thread_id, &policy, ¶ms) == 0) + { +- if ((priority_max = sched_get_priority_max(policy)) != 0) ++ if ((priority_max = __gthrw_sched_get_priority_max(policy)) != 0) + return -1; + +- if ((priority_min = sched_get_priority_min(policy)) != 0) ++ if ((priority_min = __gthrw_sched_get_priority_min(policy)) != 0) + return -1; + + if (priority > priority_max) +@@ -197,7 +269,7 @@ + * this should be a pointer to policy but pthread.h is universally + * at odds with this. + */ +- if (pthread_setschedparam(thread_id, policy, ¶ms) == 0) ++ if (__gthrw_pthread_setschedparam(thread_id, policy, ¶ms) == 0) + return 0; + } + return -1; +@@ -213,7 +285,7 @@ + int policy; + struct sched_param params; + +- if (pthread_getschedparam(pthread_self(), &policy, ¶ms) == 0) ++ if (__gthrw_pthread_getschedparam(__gthrw_pthread_self(), &policy, ¶ms) == 0) + return params.sched_priority; + else + return -1; +@@ -227,7 +299,7 @@ + __gthread_objc_thread_yield(void) + { + if (__gthread_active_p ()) +- sched_yield(); ++ __gthrw_sched_yield(); + } + + /* Terminate the current thread. */ +@@ -236,7 +308,7 @@ + { + if (__gthread_active_p ()) + /* exit the thread */ +- pthread_exit(&__objc_thread_exit_status); ++ __gthrw_pthread_exit(&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +@@ -247,7 +319,7 @@ + __gthread_objc_thread_id(void) + { + if (__gthread_active_p ()) +- return (objc_thread_t) pthread_self(); ++ return (objc_thread_t) __gthrw_pthread_self(); + else + return (objc_thread_t) 1; + } +@@ -257,7 +329,7 @@ + __gthread_objc_thread_set_data(void *value) + { + if (__gthread_active_p ()) +- return pthread_setspecific(_objc_thread_storage, value); ++ return __gthrw_pthread_setspecific(_objc_thread_storage, value); + else + { + thread_local_storage = value; +@@ -270,7 +342,7 @@ + __gthread_objc_thread_get_data(void) + { + if (__gthread_active_p ()) +- return pthread_getspecific(_objc_thread_storage); ++ return __gthrw_pthread_getspecific(_objc_thread_storage); + else + return thread_local_storage; + } +@@ -285,7 +357,7 @@ + { + mutex->backend = objc_malloc(sizeof(pthread_mutex_t)); + +- if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL)) ++ if (__gthrw_pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL)) + { + objc_free(mutex->backend); + mutex->backend = NULL; +@@ -306,18 +378,18 @@ + + /* + * Posix Threads specifically require that the thread be unlocked +- * for pthread_mutex_destroy to work. ++ * for __gthrw_pthread_mutex_destroy to work. + */ + + do + { +- count = pthread_mutex_unlock((pthread_mutex_t *)mutex->backend); ++ count = __gthrw_pthread_mutex_unlock((pthread_mutex_t *)mutex->backend); + if (count < 0) + return -1; + } + while (count); + +- if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend)) ++ if (__gthrw_pthread_mutex_destroy((pthread_mutex_t *)mutex->backend)) + return -1; + + objc_free(mutex->backend); +@@ -331,7 +403,7 @@ + __gthread_objc_mutex_lock(objc_mutex_t mutex) + { + if (__gthread_active_p () +- && pthread_mutex_lock((pthread_mutex_t *)mutex->backend) != 0) ++ && __gthrw_pthread_mutex_lock((pthread_mutex_t *)mutex->backend) != 0) + { + return -1; + } +@@ -344,7 +416,7 @@ + __gthread_objc_mutex_trylock(objc_mutex_t mutex) + { + if (__gthread_active_p () +- && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 0) ++ && __gthrw_pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 0) + { + return -1; + } +@@ -357,7 +429,7 @@ + __gthread_objc_mutex_unlock(objc_mutex_t mutex) + { + if (__gthread_active_p () +- && pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) != 0) ++ && __gthrw_pthread_mutex_unlock((pthread_mutex_t *)mutex->backend) != 0) + { + return -1; + } +@@ -375,7 +447,7 @@ + { + condition->backend = objc_malloc(sizeof(pthread_cond_t)); + +- if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL)) ++ if (__gthrw_pthread_cond_init((pthread_cond_t *)condition->backend, NULL)) + { + objc_free(condition->backend); + condition->backend = NULL; +@@ -392,7 +464,7 @@ + { + if (__gthread_active_p ()) + { +- if (pthread_cond_destroy((pthread_cond_t *)condition->backend)) ++ if (__gthrw_pthread_cond_destroy((pthread_cond_t *)condition->backend)) + return -1; + + objc_free(condition->backend); +@@ -406,7 +478,7 @@ + __gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) + { + if (__gthread_active_p ()) +- return pthread_cond_wait((pthread_cond_t *)condition->backend, ++ return __gthrw_pthread_cond_wait((pthread_cond_t *)condition->backend, + (pthread_mutex_t *)mutex->backend); + else + return 0; +@@ -417,7 +489,7 @@ + __gthread_objc_condition_broadcast(objc_condition_t condition) + { + if (__gthread_active_p ()) +- return pthread_cond_broadcast((pthread_cond_t *)condition->backend); ++ return __gthrw_pthread_cond_broadcast((pthread_cond_t *)condition->backend); + else + return 0; + } +@@ -427,7 +499,7 @@ + __gthread_objc_condition_signal(objc_condition_t condition) + { + if (__gthread_active_p ()) +- return pthread_cond_signal((pthread_cond_t *)condition->backend); ++ return __gthrw_pthread_cond_signal((pthread_cond_t *)condition->backend); + else + return 0; + } +@@ -438,7 +510,7 @@ + __gthread_once (__gthread_once_t *once, void (*func) (void)) + { + if (__gthread_active_p ()) +- return pthread_once (once, func); ++ return __gthrw_pthread_once (once, func); + else + return -1; + } +@@ -446,7 +518,7 @@ + static inline int + __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) + { +- return pthread_key_create (key, dtor); ++ return __gthrw_pthread_key_create (key, dtor); + } + + static inline int +@@ -454,7 +526,7 @@ + { + /* Just reset the key value to zero. */ + if (ptr) +- return pthread_setspecific (key, 0); ++ return __gthrw_pthread_setspecific (key, 0); + else + return 0; + } +@@ -462,26 +534,26 @@ + static inline int + __gthread_key_delete (__gthread_key_t key) + { +- return pthread_key_delete (key); ++ return __gthrw_pthread_key_delete (key); + } + + static inline void * + __gthread_getspecific (__gthread_key_t key) + { +- return pthread_getspecific (key); ++ return __gthrw_pthread_getspecific (key); + } + + static inline int + __gthread_setspecific (__gthread_key_t key, const void *ptr) + { +- return pthread_setspecific (key, ptr); ++ return __gthrw_pthread_setspecific (key, ptr); + } + + static inline int + __gthread_mutex_lock (__gthread_mutex_t *mutex) + { + if (__gthread_active_p ()) +- return pthread_mutex_lock (mutex); ++ return __gthrw_pthread_mutex_lock (mutex); + else + return 0; + } +@@ -490,7 +562,7 @@ + __gthread_mutex_trylock (__gthread_mutex_t *mutex) + { + if (__gthread_active_p ()) +- return pthread_mutex_trylock (mutex); ++ return __gthrw_pthread_mutex_trylock (mutex); + else + return 0; + } +@@ -499,7 +571,7 @@ + __gthread_mutex_unlock (__gthread_mutex_t *mutex) + { + if (__gthread_active_p ()) +- return pthread_mutex_unlock (mutex); ++ return __gthrw_pthread_mutex_unlock (mutex); + else + return 0; + } +--- gcc/varasm.c.orig 2005-11-15 19:55:42.000000000 -0200 ++++ gcc/varasm.c 2005-11-16 13:38:44.000000000 -0200 +@@ -5130,6 +5130,9 @@ + if (! TREE_USED (decl)) + continue; + ++ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) ++ continue; ++ + #ifdef ASM_WEAKEN_DECL + ASM_WEAKEN_DECL (asm_out_file, decl, name, NULL); + #else +@@ -5195,6 +5198,18 @@ + + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + ++ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) ++ { ++#ifdef ASM_OUTPUT_WEAKREF ++ ASM_OUTPUT_WEAKREF (asm_out_file, decl, ++ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), ++ IDENTIFIER_POINTER (target)); ++#else ++ error ("%Jweakref is not supported in this configuration", decl); ++#endif ++ return; ++ } ++ + #ifdef ASM_OUTPUT_DEF + /* Make name accessible from other files, if appropriate. */ + if (TREE_PUBLIC (decl)) +--- gcc/attribs.c.orig 2005-11-15 19:55:42.000000000 -0200 ++++ gcc/attribs.c 2005-11-15 19:55:48.000000000 -0200 +@@ -75,6 +75,8 @@ + bool *)); + static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int, + bool *)); ++static tree handle_weakref_attribute PARAMS ((tree *, tree, tree, int, ++ bool *)); + static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int, + bool *)); + static tree handle_tls_model_attribute PARAMS ((tree *, tree, tree, int, +@@ -140,6 +142,8 @@ + handle_weak_attribute }, + { "alias", 1, 1, true, false, false, + handle_alias_attribute }, ++ { "weakref", 0, 1, true, false, false, ++ handle_weakref_attribute }, + { "no_instrument_function", 0, 0, true, false, false, + handle_no_instrument_function_attribute }, + { "malloc", 0, 0, true, false, false, +@@ -1060,7 +1064,12 @@ + if (TREE_CODE (decl) == FUNCTION_DECL) + DECL_INITIAL (decl) = error_mark_node; + else +- DECL_EXTERNAL (decl) = 0; ++ { ++ if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) ++ DECL_EXTERNAL (decl) = 1; ++ else ++ DECL_EXTERNAL (decl) = 0; ++ } + } + else + { +@@ -1071,6 +1080,44 @@ + return NULL_TREE; + } + ++/* Handle a "weakref" attribute; arguments as in struct ++ attribute_spec.handler. */ ++ ++static tree ++handle_weakref_attribute (node, name, args, flags, no_add_attrs) ++ tree *node; ++ tree name ATTRIBUTE_UNUSED; ++ tree args; ++ int flags; ++ bool *no_add_attrs; ++{ ++ tree attr = NULL_TREE; ++ ++ /* The idea here is that `weakref("name")' mutates into `weakref, ++ alias("name")', and weakref without arguments, in turn, ++ implicitly adds weak. */ ++ ++ if (args) ++ { ++ attr = tree_cons (get_identifier ("alias"), args, attr); ++ attr = tree_cons (get_identifier ("weakref"), NULL_TREE, attr); ++ ++ *no_add_attrs = true; ++ } ++ else ++ { ++ if (lookup_attribute ("alias", DECL_ATTRIBUTES (*node))) ++ error ("%Jweakref attribute must appear before alias attribute", ++ *node); ++ ++ attr = tree_cons (get_identifier ("weak"), NULL_TREE, attr); ++ } ++ ++ decl_attributes (node, attr, flags); ++ ++ return NULL_TREE; ++} ++ + /* Handle an "visibility" attribute; arguments as in + struct attribute_spec.handler. */ + +--- gcc/testsuite/g++.old-deja/g++.ext/weakref1.C 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/g++.old-deja/g++.ext/weakref1.C 2005-11-15 19:55:48.000000000 -0200 +@@ -0,0 +1,226 @@ ++// execution test ++// Additional sources: weakref1a.cc ++ ++// Copyright 2005 Free Software Foundation, Inc. ++// Contributed by Alexandre Oliva ++ ++// Torture test for weakrefs. The first letter of an identifier ++// indicates whether/how it is defined; the second letter indicates ++// whether it is part of a variable or function test; the number that ++// follows is a test counter, and a letter that may follow enables ++// multiple identifiers within the same test (e.g., multiple weakrefs ++// or pointers to the same identifier). ++ ++// Identifiers starting with W are weakrefs; those with p are ++// pointers; those with g are global definitions; those with l are ++// local definitions; those with w are expected to be weak undefined ++// in the symbol table; those with u are expected to be marked as ++// non-weak undefined in the symbol table. ++ ++#include ++ ++#define USED __attribute__((used)) ++ ++extern "C" { ++typedef int vtype; ++ ++extern vtype wv1; ++extern vtype Wv1a __attribute__((weakref ("wv1"))); ++static vtype *pv1a USED = &Wv1a; ++extern vtype Wv1b __attribute__((weak, weakref, alias ("wv1"))); ++static vtype *pv1b USED = &Wv1b; ++extern vtype Wv1c __attribute__((weakref)); ++extern vtype Wv1c __attribute__((alias ("wv1"))); ++static vtype *pv1c USED = &Wv1c; ++ ++vtype gv2; ++extern vtype Wv2a __attribute__((weakref ("gv2"))); ++static vtype *pv2a USED = &Wv2a; ++ ++static vtype lv3; ++extern vtype Wv3a __attribute__((weakref ("lv3"))); ++static vtype *pv3a USED = &Wv3a; ++ ++extern vtype uv4; ++extern vtype Wv4a __attribute__((weakref ("uv4"))); ++static vtype *pv4a USED = &Wv4a; ++static vtype *pv4 USED = &uv4; ++ ++extern vtype Wv5a __attribute__((weakref ("uv5"))); ++static vtype *pv5a USED = &Wv5a; ++extern vtype uv5; ++static vtype *pv5 USED = &uv5; ++ ++extern vtype Wv6a __attribute__((weakref ("wv6"))); ++static vtype *pv6a USED = &Wv6a; ++extern vtype wv6; ++ ++extern vtype Wv7a __attribute__((weakref ("uv7"))); ++static vtype* USED fv7 (void) { ++ return &Wv7a; ++} ++extern vtype uv7; ++static vtype* USED fv7a (void) { ++ return &uv7; ++} ++ ++extern vtype uv8; ++static vtype* USED fv8a (void) { ++ return &uv8; ++} ++extern vtype Wv8a __attribute__((weakref ("uv8"))); ++static vtype* USED fv8 (void) { ++ return &Wv8a; ++} ++ ++extern vtype wv9 __attribute__((weak)); ++extern vtype Wv9a __attribute__((weakref ("wv9"))); ++static vtype *pv9a USED = &Wv9a; ++ ++extern vtype Wv10a __attribute__((weakref ("Wv10b"))); ++extern vtype Wv10b __attribute__((weakref ("Wv10c"))); ++extern vtype Wv10c __attribute__((weakref ("Wv10d"))); ++extern vtype Wv10d __attribute__((weakref ("wv10"))); ++extern vtype wv10; ++ ++extern vtype wv11; ++extern vtype Wv11d __attribute__((weakref ("wv11"))); ++extern vtype Wv11c __attribute__((weakref ("Wv11d"))); ++extern vtype Wv11b __attribute__((weakref ("Wv11c"))); ++extern vtype Wv11a __attribute__((weakref ("Wv11b"))); ++ ++extern vtype Wv12 __attribute__((weakref ("wv12"))); ++extern vtype wv12 __attribute__((weak)); ++ ++extern vtype Wv13 __attribute__((weakref ("wv13"))); ++extern vtype wv13 __attribute__((weak)); ++ ++extern vtype Wv14a __attribute__((weakref ("wv14"))); ++extern vtype Wv14b __attribute__((weakref ("wv14"))); ++extern vtype wv14 __attribute__((weak)); ++ ++typedef void ftype(void); ++ ++extern ftype wf1; ++extern ftype Wf1a __attribute__((weakref ("wf1"))); ++static ftype *pf1a USED = &Wf1a; ++extern ftype Wf1b __attribute__((weak, weakref, alias ("wf1"))); ++static ftype *pf1b USED = &Wf1b; ++extern ftype Wf1c __attribute__((weakref)); ++extern ftype Wf1c __attribute__((alias ("wf1"))); ++static ftype *pf1c USED = &Wf1c; ++ ++void gf2(void) {} ++extern ftype Wf2a __attribute__((weakref ("gf2"))); ++static ftype *pf2a USED = &Wf2a; ++ ++static void lf3(void) {} ++extern ftype Wf3a __attribute__((weakref ("lf3"))); ++static ftype *pf3a USED = &Wf3a; ++ ++extern ftype uf4; ++extern ftype Wf4a __attribute__((weakref ("uf4"))); ++static ftype *pf4a USED = &Wf4a; ++static ftype *pf4 USED = &uf4; ++ ++extern ftype Wf5a __attribute__((weakref ("uf5"))); ++static ftype *pf5a USED = &Wf5a; ++extern ftype uf5; ++static ftype *pf5 USED = &uf5; ++ ++extern ftype Wf6a __attribute__((weakref ("wf6"))); ++static ftype *pf6a USED = &Wf6a; ++extern ftype wf6; ++ ++extern ftype Wf7a __attribute__((weakref ("uf7"))); ++static ftype* USED ff7 (void) { ++ return &Wf7a; ++} ++extern ftype uf7; ++static ftype* USED ff7a (void) { ++ return &uf7; ++} ++ ++extern ftype uf8; ++static ftype* USED ff8a (void) { ++ return &uf8; ++} ++extern ftype Wf8a __attribute__((weakref ("uf8"))); ++static ftype* USED ff8 (void) { ++ return &Wf8a; ++} ++ ++extern ftype wf9 __attribute__((weak)); ++extern ftype Wf9a __attribute__((weakref ("wf9"))); ++static ftype *pf9a USED = &Wf9a; ++ ++extern ftype Wf10a __attribute__((weakref ("Wf10b"))); ++extern ftype Wf10b __attribute__((weakref ("Wf10c"))); ++extern ftype Wf10c __attribute__((weakref ("Wf10d"))); ++extern ftype Wf10d __attribute__((weakref ("wf10"))); ++extern ftype wf10; ++ ++extern ftype wf11; ++extern ftype Wf11d __attribute__((weakref ("wf11"))); ++extern ftype Wf11c __attribute__((weakref ("Wf11d"))); ++extern ftype Wf11b __attribute__((weakref ("Wf11c"))); ++extern ftype Wf11a __attribute__((weakref ("Wf11b"))); ++ ++extern ftype Wf12 __attribute__((weakref ("wf12"))); ++extern ftype wf12 __attribute__((weak)); ++ ++extern ftype Wf13 __attribute__((weakref ("wf13"))); ++extern ftype wf13 __attribute__((weak)); ++ ++extern ftype Wf14a __attribute__((weakref ("wf14"))); ++extern ftype Wf14b __attribute__((weakref ("wf14"))); ++extern ftype wf14 __attribute__((weak)); ++} ++ ++#define chk(p) do { if (!p) abort (); } while (0) ++ ++int main () { ++ chk (!pv1a); ++ chk (!pv1b); ++ chk (!pv1c); ++ chk (pv2a); ++ chk (pv3a); ++ chk (pv4a); ++ chk (pv4); ++ chk (pv5a); ++ chk (pv5); ++ chk (!pv6a); ++ chk (fv7 ()); ++ chk (fv7a ()); ++ chk (fv8 ()); ++ chk (fv8a ()); ++ chk (!pv9a); ++ chk (!&Wv10a); ++ chk (!&Wv11a); ++ chk (!&Wv12); ++ chk (!&wv12); ++ chk (!&wv13); ++ chk (!&Wv14a); ++ ++ chk (!pf1a); ++ chk (!pf1b); ++ chk (!pf1c); ++ chk (pf2a); ++ chk (pf3a); ++ chk (pf4a); ++ chk (pf4); ++ chk (pf5a); ++ chk (pf5); ++ chk (!pf6a); ++ chk (ff7 ()); ++ chk (ff7a ()); ++ chk (ff8 ()); ++ chk (ff8a ()); ++ chk (!pf9a); ++ chk (!&Wf10a); ++ chk (!&Wf11a); ++ chk (!&Wf12); ++ chk (!&wf12); ++ chk (!&wf13); ++ chk (!&Wf14a); ++} +--- gcc/testsuite/g++.old-deja/g++.ext/weakref1a.cc 1970-01-01 00:00:00.000000000 +0000 ++++ gcc/testsuite/g++.old-deja/g++.ext/weakref1a.cc 2005-11-15 19:55:48.000000000 -0200 +@@ -0,0 +1,10 @@ ++extern "C" { ++int uv4; ++int uv5; ++int uv7; ++int uv8; ++void uf4 (void) {} ++void uf5 (void) {} ++void uf7 (void) {} ++void uf8 (void) {} ++} +--- gcc/config/rs6000/rs6000.h.orig 2005-11-16 13:37:46.000000000 -0200 ++++ gcc/config/rs6000/rs6000.h 2005-11-16 14:10:01.000000000 -0200 +@@ -2487,6 +2487,24 @@ + while (0) + #endif + ++#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE) \ ++ do \ ++ { \ ++ fputs ("\t.weakref\t", (FILE)); \ ++ RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ ++ fputs (", ", (FILE)); \ ++ RS6000_OUTPUT_BASENAME ((FILE), (VALUE)); \ ++ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \ ++ && DEFAULT_ABI == ABI_AIX) \ ++ { \ ++ fputs ("\n\t.weakref\t.", (FILE)); \ ++ RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \ ++ fputs (", .", (FILE)); \ ++ RS6000_OUTPUT_BASENAME ((FILE), (VALUE)); \ ++ } \ ++ fputc ('\n', (FILE)); \ ++ } while (0) ++ + /* This implements the `alias' attribute. */ + #undef ASM_OUTPUT_DEF_FROM_DECLS + #define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \ diff --git a/SPECS/compat-gcc-32.spec b/SPECS/compat-gcc-32.spec new file mode 100644 index 0000000..7de6e96 --- /dev/null +++ b/SPECS/compat-gcc-32.spec @@ -0,0 +1,612 @@ +%define LIBSTDCXXDATE 20040818 +%define DATE 20040701 +%define gcc_version 3.2.3 +%define gcc_release 72 +%define _unpackaged_files_terminate_build 0 +%define multilib_64_archs sparc64 ppc64 s390x x86_64 +%define build_java 0 +%define _default_patch_fuzz 2 +%ifarch s390x +%define multilib_32_arch s390 +%endif +%ifarch sparc64 +%define multilib_32_arch sparc +%endif +%ifarch ppc64 +%define multilib_32_arch ppc +%endif +%ifarch x86_64 +%define multilib_32_arch i386 +%endif +Summary: The compatibility GNU Compiler Collection +Name: compat-gcc-32 +Version: %{gcc_version} +Release: %{gcc_release}%{?dist} +License: GPLv2+ with exceptions +Group: Development/Languages +Source0: gcc-%{gcc_version}-%{DATE}.tar.bz2 +Source2: libstdc++-3.3.4-%{LIBSTDCXXDATE}.tar.bz2 +Source3: dummylib.sh +URL: http://gcc.gnu.org +BuildRoot: /var/tmp/gcc-root +# Need .eh_frame ld optimizations +# Need proper visibility support +# Need -pie support +# Need --as-needed/--no-as-needed support +# Need .weakref support +BuildRequires: binutils >= 2.16.91.0.5-1 +BuildRequires: zlib-devel, gettext, dejagnu, bison, flex, texinfo +# Make sure pthread.h doesn't contain __thread tokens +BuildRequires: glibc-devel >= 2.2.90-12, glibc-static +# Need .eh_frame ld optimizations +# Need proper visibility support +# Need -pie support +# Need .weakref support +Requires: binutils >= 2.16.91.0.5-1 +# Make sure gdb will understand DW_FORM_strp +Conflicts: gdb < 5.1-2 +Requires: glibc-devel >= 2.2.90-12 +Requires: libgcc >= 3.4.0 +%ifarch %{multilib_64_archs} sparc sparcv9 ppc +# Ensure glibc{,-devel} is installed for both multilib arches +BuildRequires: /lib/libc.so.6 /usr/lib/libc.so /lib64/libc.so.6 /usr/lib64/libc.so +%endif +Provides: bundled(libiberty) + +Patch1: gcc32-multi32-hack.patch +Patch2: gcc32-ice-hack.patch +Patch3: gcc32-ppc64-m32-m64-multilib-only.patch +Patch4: gcc32-bison-1.875c.patch +Patch5: gcc32-i386-prefetch-sse.patch +Patch6: gcc32-convert-move.patch +Patch7: gcc32-libjava-jar-timestamps.patch +Patch8: gcc32-c++-friend-templ-member.patch +Patch9: gcc32-c++-scope-nesting.patch +Patch10: gcc32-libstdc++-symver.patch +Patch11: gcc32-java-intlex.patch +Patch12: gcc32-java-nan.patch +Patch13: gcc32-dwarf2-pruning-keep-spec.patch +Patch14: gcc32-java-bytecode.patch +Patch15: gcc32-pr3581.patch +Patch16: gcc32-libstdc++-limits.patch +Patch17: gcc32-ppc64-crtsavres.patch +Patch18: gcc32-s390-reload-dup.patch +Patch19: gcc32-ppc-altivec-ap.patch +Patch20: gcc32-ppc-mpowerpc64.patch +Patch21: gcc32-null-pointer-check-noncc0.patch +Patch22: gcc32-ppc-movdi_internal64.patch +Patch23: gcc32-c++-reregister-specialization.patch +Patch24: gcc32-c++-pr7566.patch +Patch25: gcc32-c++-pass-by-invisible-ref.patch +Patch26: gcc32-c++-unitialized-self-ref.patch +Patch27: gcc32-tablejump-cleanup.patch +Patch28: gcc32-libstdc++-fully-dynamic-strings.patch +Patch29: gcc32-Winline-doc.patch +Patch30: gcc32-ia64-expand_load_address.patch +Patch31: gcc32-demangle-pr16240.patch +Patch32: gcc32-debug-cdtor.patch +Patch33: gcc32-cxa_demangle-ambiguity.patch +Patch34: gcc32-c++-pr10558.patch +Patch35: gcc32-libstdc++-pr9659.patch +Patch36: gcc32-libstdc++-symver2.patch +Patch37: gcc32-pr19005.patch +Patch38: gcc32-rh149250.patch +Patch39: gcc32-rh156185.patch +Patch40: gcc32-rh156291.patch +Patch41: gcc32-pr18300.patch +Patch42: gcc32-gnuc-rh-release.patch +Patch43: gcc32-weakref.patch +Patch44: gcc32-pr13106.patch +Patch45: gcc32-ppc64-stack-boundary.patch +Patch46: gcc32-pr12799.patch +Patch47: gcc32-pr13041.patch +Patch48: gcc32-pr26208.patch +Patch49: gcc32-rh173224.patch +Patch50: gcc32-rh180778.patch +Patch51: gcc32-rh181894.patch +Patch52: gcc32-rh186252.patch +Patch53: gcc32-pr26208-workaround.patch +Patch54: gcc32-libgcc_eh-hidden.patch +Patch55: gcc32-java-zoneinfo.patch +Patch56: gcc32-CVE-2006-3619.patch +Patch57: gcc32-rh226706.patch + +Patch60: gcc32-obstack-lvalues.patch +Patch61: gcc32-fc4-compile.patch +Patch62: gcc32-s390x-compile.patch +Patch63: gcc32-bison.patch + +Patch100: compat-libstdc++33-incdir.patch +Patch101: compat-libstdc++33-limits.patch +Patch102: compat-libstdc++33-symver.patch +Patch103: compat-libstdc++33-v3.patch +Patch104: compat-libstdc++33++-fully-dynamic-strings.patch +Patch105: compat-libstdc++33++-symver2.patch +Patch106: compat-libstdc++33-cxa_demangle-ambiguity.patch +Patch107: compat-libstdc++33-ldbl.patch + +%define _gnu %{nil} + +%ifarch sparc sparcv9 +%define gcc_target_platform sparc64-%{_vendor}-linux +%endif +%ifarch ppc +%define gcc_target_platform ppc64-%{_vendor}-linux +%endif +%ifnarch sparc sparcv9 ppc +%define gcc_target_platform %{_target_cpu}-%{_vendor}-linux +%endif + +%description +This package includes a GCC 3.2.3-RH compatibility compiler. + +%package -n compat-libstdc++-33 +Summary: Compatibility standard C++ libraries +Group: System Environment/Libraries +Obsoletes: compat-libstdc++ +Obsoletes: compat-gcc-32, compat-gcc-32-c++, compat-gcc-32-g77 + +%description -n compat-libstdc++-33 +The compat-libstdc++ package contains compatibility standard C++ library +from GCC 3.3.4. + +%prep +%setup -q -n gcc-%{gcc_version}-%{DATE} -a2 +mv gcc-3.3.4-%{LIBSTDCXXDATE}/libstdc++-v3 libstdc++33-v3 +%ifarch sparc ppc +#%patch1 -p0 -b .multi32-hack~ +%endif +%patch2 -p0 -b .ice-hack~ +%patch3 -p0 -b .ppc64-m32-m64-multilib-only~ +%patch4 -p0 -b .bison-1.875c~ +%patch5 -p0 -b .i386-prefetch-sse~ +%patch6 -p0 -b .convert-move~ +%patch7 -p0 -b .libjava-jar-timestamps~ +%patch8 -p0 -b .c++-friend-templ-member~ +#%patch9 -p0 -b .c++-scope-nesting~ +%patch10 -p0 -b .libstdc++-symver~ +%patch11 -p0 -b .java-intlex~ +%patch12 -p0 -b .java-nan~ +%patch13 -p0 -b .dwarf2-pruning-keep-spec~ +%patch14 -p0 -b .java-bytecode~ +%patch15 -p0 -b .pr3581~ +%patch16 -p0 -b .libstdc++-limits~ +%patch17 -p0 -b .ppc64-crtsavres~ +%patch18 -p0 -b .s390-reload-dup~ +%patch19 -p0 -b .ppc-altivec-ap~ +%patch20 -p0 -b .ppc-mpowerpc64~ +%patch21 -p0 -b .null-pointer-check-noncc0~ +%patch22 -p0 -b .ppc-movdi_internal64~ +%patch23 -p0 -b .c++-reregister-specialization~ +%patch24 -p0 -b .c++-pr7566~ +%patch25 -p0 -b .c++-pass-by-invisible-ref~ +%patch26 -p0 -b .c++-unitialized-self-ref~ +%patch27 -p0 -b .tablejump-cleanup~ +%patch28 -p0 -b .libstdc++-fully-dynamic-strings~ +%patch29 -p0 -b .Winline-doc~ +%patch30 -p0 -b .ia64-expand_load_address~ +%patch31 -p0 -b .demangle-pr16240~ +%patch32 -p0 -b .debug-cdtor~ +%patch33 -p0 -b .cxa_demangle-ambiguity~ +%patch34 -p0 -b .c++-pr10558~ +%patch35 -p0 -b .libstdc++-pr9659~ +%patch36 -p0 -b .libstdc++-symver2~ +%patch37 -p0 -b .pr19005~ +%patch38 -p0 -b .rh149250~ +%patch39 -p0 -b .rh156185~ +%patch40 -p0 -b .rh156291~ +%patch41 -p0 -b .pr18300~ +%patch42 -p0 -b .gnuc-rh-release~ +%patch43 -p0 -b .weakref~ +%patch44 -p0 -b .pr13106~ +%patch45 -p0 -b .ppc64-stack-boundary~ +%patch46 -p0 -b .pr12799~ +%patch47 -p0 -b .pr13041~ +%patch48 -p0 -b .pr26208~ +%patch49 -p0 -b .rh173224~ +%patch50 -p0 -b .rh180778~ +%patch51 -p0 -b .rh181894~ +%patch52 -p0 -b .rh186252~ +%patch53 -p0 -b .pr26208-workaround~ +%patch54 -p0 -b .libgcc_eh-hidden~ +%patch55 -p0 -b .java-zoneinfo~ +%patch56 -p0 -b .CVE-2006-3619~ +%patch57 -p0 -b .rh226706~ + +%patch60 -p0 -b .obstack-lvalues~ +%patch61 -p0 -b .fc4-compile~ +%patch62 -p0 -b .s390x-compile~ +%patch63 -p0 -b .bison~ + +%patch100 -p0 -b .compat-libstdc++33-incdir~ +%patch101 -p0 -b .compat-libstdc++33-limits~ +%patch102 -p0 -b .compat-libstdc++33-symver~ +%patch103 -p0 -b .compat-libstdc++33-v3~ +%patch104 -p0 -b .compat-libstdc++33++-fully-dynamic-strings~ +%patch105 -p0 -b .compat-libstdc++33++-symver2~ +%patch106 -p0 -b .compat-libstdc++33-cxa_demangle-ambiguity~ +%patch107 -p0 -b .compat-libstdc++33-ldbl.patch~ + +sed -i -e 's/struct siginfo/siginfo_t/' gcc/config/*/linux*.h + +%ifarch ppc ppc64 s390 s390x +sed -i -e 's/-lm @LIBUNWIND_FLAG@/-lm @LIBUNWIND_FLAG@ -lnldbl_nonshared/' \ + libstdc++33-v3/src/Makefile.{am,in} +%endif +# Don't need to test C, only check-g++ and libstdc++-v33's make check +sed -i -e 's/\$(RUNTEST) --tool gcc/: $(RUNTEST) --tool gcc/' \ + gcc/Makefile.in +sed -i -e 's/\$\$runtest \$(RUNTESTDEFAULTFLAGS)/: $$runtest $(RUNTESTDEFAULTFLAGS)/' \ + libstdc++-v3/testsuite/Makefile.in +perl -pi -e 's/3\.2\.4/3.2.3/' gcc/version.c +perl -pi -e 's/"%{gcc_version}"/"%{gcc_version} \(release\)"/' gcc/version.c +perl -pi -e 's/\((prerelease|experimental|release|Red Hat[^)]*)\)/\(Red Hat Linux %{gcc_version}-%{gcc_release}\)/' gcc/version.c + +cp -a libstdc++33-v3/config/cpu/i{4,3}86/atomicity.h + +./contrib/gcc_update --touch + +%build + +rm -fr obj-%{gcc_target_platform} +mkdir obj-%{gcc_target_platform} +cd obj-%{gcc_target_platform} + +mkdir -p ld_hack +cat > ld_hack/ld <<\EOF +#!/bin/sh +case " $* " in *\ -r\ *) exec /usr/bin/ld "$@";; esac +exec /usr/bin/ld --build-id "$@" +EOF +chmod 755 ld_hack/ld +export PATH=`pwd`/ld_hack/${PATH:+:$PATH} + +if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then + mkdir locale + localedef -f ISO-8859-1 -i de_DE locale/de_DE + export LOCPATH=`pwd`/locale:/usr/lib/locale +fi + +CC=gcc +OPT_FLAGS=`echo $RPM_OPT_FLAGS|sed -e 's/-fno-rtti//g' -e 's/-fno-exceptions//g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-m64//g;s/-m32//g;s/-m31//g'` +%ifarch %{ix86} +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=pentium4/-mcpu=i686/g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=generic/-mcpu=i686/g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=atom/-mcpu=i686/g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=atom/-mcpu=i686/g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=x86-64//g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mfpmath=sse//g'` +%endif +%ifarch x86_64 +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=nocona//g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mtune=generic//g'` +%endif +%ifarch sparc sparcv9 sparc64 +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-mcpu=ultrasparc/-mtune=ultrasparc/g'` +%endif +%ifarch s390 s390x +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=z9-109//g;s/-march=z10//g;s/-march=z196//g;s/-mtune=z10//g;s/-mtune=zEC12//g'` +%endif +%ifarch ppc ppc64 +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-march=power[678]//g;s/-mcpu=power[678]//g;s/-mtune=power[678]//g'` +%endif +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-Wall//g' -e 's/-Wp,-D_FORTIFY_SOURCE=2//g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-fexceptions//g' -e 's/-fasynchronous-unwind-tables//g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-grecord-gcc-switches//g' -e 's/-fstack-protector-strong//g'` +OPT_FLAGS=`echo $OPT_FLAGS|sed -e 's/-fstack-protector//g' -e 's/--param=ssp-buffer-size=[0-9]*//g'` +%ifarch sparc64 +cat > gcc64 <<"EOF" +#!/bin/sh +exec /usr/bin/gcc -m64 "$@" +EOF +chmod +x gcc64 +CC=`pwd`/gcc64 +%endif +%ifarch ppc64 +if gcc -m64 -xc -S /dev/null -o - > /dev/null 2>&1; then + cat > gcc64 <<"EOF" +#!/bin/sh +exec /usr/bin/gcc -m64 "$@" +EOF + chmod +x gcc64 + CC=`pwd`/gcc64 +fi +%endif +CC="$CC" CFLAGS="$OPT_FLAGS" CXXFLAGS="$OPT_FLAGS" XCFLAGS="$OPT_FLAGS" TCFLAGS="$OPT_FLAGS" \ + GCJFLAGS="$OPT_FLAGS" \ + ../configure --prefix=%{_prefix} --mandir=%{_mandir} --infodir=%{_infodir} \ + --enable-shared --enable-threads=posix --disable-checking \ + --with-system-zlib --enable-__cxa_atexit \ + --enable-languages=c,c++ --disable-libgcj \ +%ifarch sparc sparcv9 + --host=%{gcc_target_platform} --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=v7 +%endif +%ifarch ppc + --host=%{gcc_target_platform} --build=%{gcc_target_platform} --target=%{gcc_target_platform} --with-cpu=default32 +%endif +%ifnarch sparc sparcv9 ppc + --host=%{gcc_target_platform} +%endif + +make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" bootstrap-lean +#make %{?_smp_mflags} BOOT_CFLAGS="$OPT_FLAGS" bootstrap + +# Fix up libstdc++.so's +for d in `pwd`/%{gcc_target_platform}/libstdc++-v3 `pwd`/%{gcc_target_platform}/*/libstdc++-v3; do + test -d $d || continue + d33=`dirname $d`/libstdc++33-v3 + pushd $d/src + sh %{SOURCE3} .libs/libstdc++.so .libs/ll.so linker.map + rm .libs/libstdc++.so; mv .libs/ll.so .libs/libstdc++.so + f=`basename .libs/libstdc++.so.5.0.*` + f33=`basename $d33/src/.libs/libstdc++.so.5.0.*` + cp -a $d33/src/.libs/libstdc++.so.5.0.* .libs/ + if [ "$f" != "$f33" ]; then + ln -sf $f33 .libs/libstdc++.so.5 + ln -sf $f33 .libs/$f + fi + popd + pushd $d33/src + sh %{SOURCE3} .libs/libstdc++.so .libs/ll.so libstdc++*.ver + rm .libs/libstdc++.so; mv .libs/ll.so .libs/libstdc++.so + popd +done + +# Make sure we are using system libgcc_s, as system libc might +# use unwinding features that require it. +mv gcc/libgcc_s.so.1{,.bak} +ln -sf /%{_lib}/libgcc_s.so.1 gcc/libgcc_s.so.1 + +# run the tests. +make %{?_smp_mflags} -k check || : +sed -ie s/libstdc++-v3/libstdc++33-v3/g `find $(find %{gcc_target_platform} -type d -a -name libstdc++33-v3) -name \*.sum` +echo ====================TESTING========================= +( ../contrib/test_summary || : ) 2>&1 | sed -n '/^cat.*EOF/,/^EOF/{/^cat.*EOF/d;/^EOF/d;/^LAST_UPDATED:/d;p;}' +echo ====================TESTING END===================== + +%install +rm -fr $RPM_BUILD_ROOT + +export PATH=`pwd`/obj-%{gcc_target_platform}/ld_hack/${PATH:+:$PATH} + +perl -pi -e \ + 's~href="l(ibstdc|atest)~href="http://gcc.gnu.org/onlinedocs/libstdc++/l\1~' \ + libstdc++-v3/docs/html/documentation.html +ln -sf documentation.html libstdc++-v3/docs/html/index.html +find libstdc++-v3/docs/html -name CVS | xargs rm -rf + +cd obj-%{gcc_target_platform} + +if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then + export LOCPATH=`pwd`/locale:/usr/lib/locale +fi + +TARGET_PLATFORM=%{gcc_target_platform} + +# There are some MP bugs in libstdc++ and libjava Makefiles +# make -C %{gcc_target_platform}/libstdc++-v3 + +make prefix=$RPM_BUILD_ROOT%{_prefix} mandir=$RPM_BUILD_ROOT%{_mandir} \ + infodir=$RPM_BUILD_ROOT%{_infodir} install + +FULLPATH=$RPM_BUILD_ROOT%{_prefix}/lib/gcc-lib/%{gcc_target_platform}/%{gcc_version} +FULLPATH33=$RPM_BUILD_ROOT%{_prefix}/lib/gcc-lib/%{gcc_target_platform}/3.3.4 + +rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libstdc++.*a +rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libsupc++.*a +rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libstdc++.so* + +for d in %{gcc_target_platform}/libstdc++-v3 %{gcc_target_platform}/*/libstdc++-v3; do + test -d $d || continue + d33=`dirname $d`/libstdc++33-v3 + b="" + test x"$d" != x%{gcc_target_platform}/libstdc++-v3 && b=/`basename $(dirname $d)` + install -m 644 $d/libsupc++/.libs/libsupc++.a $FULLPATH$b/ + install -m 644 $d/src/.libs/libstdc++.a $FULLPATH$b/ + strip -g $FULLPATH$b/*.a + install -m 644 $d/src/.libs/libstdc++.so $FULLPATH$b/ + + mkdir -p $FULLPATH33$b + install -m 644 $d33/libsupc++/.libs/libsupc++.a $FULLPATH33$b/ + install -m 644 $d33/src/.libs/libstdc++.a $FULLPATH33$b/ + strip -g $FULLPATH33$b/*.a + install -m 644 $d33/src/.libs/libstdc++.so $FULLPATH33$b/ +done + +mkdir -p $RPM_BUILD_ROOT/%{_lib} +install -m755 %{gcc_target_platform}/libstdc++33-v3/src/.libs/libstdc++.so.5.0* \ + $RPM_BUILD_ROOT%{_prefix}/%{_lib}/ +/sbin/ldconfig -n $RPM_BUILD_ROOT%{_prefix}/%{_lib}/ + +rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libgcc_s* + +cd .. + +for i in $RPM_BUILD_ROOT%{_prefix}/bin/{*gcc,*++,gcov}; do + mv -f $i ${i}32 +done + +rm -f $RPM_BUILD_ROOT%{_prefix}/lib*/{libiberty.a,*/libiberty.a} +rm -f $RPM_BUILD_ROOT/lib*/libgcc_s* + +%ifarch %{multilib_64_archs} +# Remove libraries for the other arch on multilib arches +rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.so* +rm -f $RPM_BUILD_ROOT%{_prefix}/lib/lib*.a +%else +%ifarch sparc sparcv9 ppc +rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.so* +rm -f $RPM_BUILD_ROOT%{_prefix}/lib64/lib*.a +%endif +%endif + +rm -rf $RPM_BUILD_ROOT%{_prefix}/{lib/gcc-lib,bin,include} + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -n compat-libstdc++-33 -p /sbin/ldconfig + +%postun -n compat-libstdc++-33 -p /sbin/ldconfig + +%files -n compat-libstdc++-33 +%defattr(-,root,root) +%{_prefix}/%{_lib}/libstdc++.so.5* + +%changelog +* Tue Nov 4 2014 Jakub Jelinek 3.2.3-72 +- rebuilt against fixed glibc to avoid infinite recursion in btowc (#1159772) + +* Fri Jan 24 2014 Daniel Mach - 3.2.3-71 +- Mass rebuild 2014-01-24 + +* Tue Jan 7 2014 Jakub Jelinek 3.2.3-70 +- filter out -fstack-protector-strong, -grecord-gcc-switches and new + i686, ppc and s390 tunings (#1048850) + +* Wed Aug 28 2013 Jakub Jelinek 3.2.3-69 +- add %%{?dist} to release (#874993) + +* Wed Feb 20 2013 Jakub Jelinek 3.2.3-68.7 +- use siginfo_t instead of struct siginfo + +* Wed Feb 13 2013 Fedora Release Engineering - 3.2.3-68.6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Oct 15 2012 Jon Ciesla - 3.2.3-68.5 +- Provides: bundled(libiberty) + +* Wed Jul 18 2012 Fedora Release Engineering - 3.2.3-68.4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Feb 28 2012 Fedora Release Engineering - 3.2.3-68.3 +- Rebuilt for c++ ABI breakage + +* Thu Jan 12 2012 Fedora Release Engineering - 3.2.3-68.2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Feb 08 2011 Fedora Release Engineering - 3.2.3-68.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Thu Sep 17 2009 Jakub Jelinek 3.2.3-68 +- strip -march=z9-109 and -mtune=z10 from OPT_FLAGS on s390, s390x + (#523209) +- make sure to use system libgcc_s.so.1 instead of gcc32 one during + testing + +* Tue Jul 28 2009 Jakub Jelinek 3.2.3-67 +- replace -mtune=generic in $RPM_OPT_FLAGS with something that + GCC 3.2.3 groks + +* Mon Mar 9 2009 Jakub Jelinek 3.2.3-66 +- fix up for latest bison + +* Sat Feb 14 2009 Dennis Gilmore - 3.2.3-65 +- fix to build 32 bit sparc sparcv9 + +* Tue Jul 15 2008 Tom "spot" Callaway - 3.2.3-64 +- fix license tag +- apply patches with fuzz=2 + +* Tue Feb 19 2008 Fedora Release Engineering - 3.2.3-63 +- Autorebuild for GCC 4.3 + +* Tue Oct 9 2007 Jakub Jelinek 3.2.3-62 +- rebuilt + +* Mon Aug 21 2006 Jakub Jelinek 3.2.3-61 +- fix the ppc*/s390* math *l stub changes + +* Fri Aug 18 2006 Jakub Jelinek 3.2.3-60 +- on ppc*/s390* make sure all needed math *l stubs are included + +* Thu Aug 10 2006 Jakub Jelinek 3.2.3-59 +- fix cleaning up the buildroot before debuginfo generation + +* Thu Aug 10 2006 Jakub Jelinek 3.2.3-58 +- include only compat-libstdc++-33 subpackage + +* Thu Aug 3 2006 Jakub Jelinek 3.2.3-57 +- in 64-bit builds remove 32-bit /usr/lib/lib* libraries from the + buildroots (and similarly on 32-bit builds remove 64-bit /usr/lib64/lib*) + before AutoReq generation + +* Wed Jul 12 2006 Jesse Keating - 3.2.3-55.fc5.1 +- rebuild + +* Sat Feb 11 2006 Jakub Jelinek 3.2.3-55.fc5 +- replace -mtune=generic in $RPM_OPT_FLAGS with something that + GCC 3.2.3 groks + +* Fri Feb 10 2006 Jesse Keating - 3.2.3-54.fc5.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 3.2.3-54.fc5.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Jan 4 2006 Jakub Jelinek 3.2.3-54.fc5 +- rebuilt with new gcc, massage $RPM_OPT_FLAGS, as GCC 3.2.3-RH doesn't + grok -fstack-protector etc. +- make sure glibc and glibc-devel for all multilib arches is installed + for building (#170601) +- fix compat-libstdc++-33 %%description (#171684) +- disable os_defines.h changes introduced in 3.2.3-45 also for + IBM xlC compiler (#146196, IT#75174) +- fix pushdecl_class_level for OVERLOADs (Mark Mitchell, + Alexandre Oliva, #156185) +- reword diagnostics about unresolved overloaded type + (Alexandre Oliva, #156291, IT#70101) +- fix x86_64 compiler hang when passing object with 3+ base classes by value + (Zak Kipling, PR target/18300, #164421, #171940, IT#76454) +- predefine __GNUC_RH_RELEASE__ macro to rpm's %%{release} (Alexandre Oliva) +- weakref attribute support, use it in various C++ headers + are using (Alexandre Oliva, #165728, IT#73356) +- don't warn in templates about missing return if return type is dependent + on template parameters (Alexandre Oliva, PR c++/13106, #169044, IT#77857) +- ensure ppc64 keeps stack 16 byte aligned even with dynamic allocation + (alloca, VLAs), but don't rely on it in the generated code + (Alexandre Oliva, #169111, IT#76136) +- fix invalid CC clobberation on i?86/x86_64 (Eric Botcazou, + PR optimization/12799, #169654) +- don't assume hard frame pointer register is STACK_BOUNDARY aligned + if frame pointer isn't used and the register has been reused + for something else (Eric Botcazou, PR optimization/13041, #169845) +- fix libstdc++ seekoff bug (Scott Snyder, #151692, IT#66065, + PR libstdc++/9659) +- don't use .symver directives in libstdc++.a, instead + provide hidden aliases for the obsolete symbols (#151732, IT#64710) +- fix a strength reduction bug (Jan Hubicka, #149250, IT#66328) +- fix xchgb constraints on i386 (#156104, IT#69633, PR target/19005) +- change __cxa_demangle to match cxx-abi change + http://www.codesourcery.com/archives/cxx-abi-dev/msg01877.html + (Jason Merrill, #133406) +- fix ICE on invalid use of template without arguments as primary + expression (Mark Mitchell, #149492, PR c++/10558) +- fix c++filt/__cxa_demangle segfault on invalidly mangled names + generated by G++ 3.4 (Ian Lance Taylor, #145781, PR c++/16240) +- disable os_defines.h changes introduced in 3.2.3-45 for non-GCC + compilers (#144725, #146196) +- fix debugging information in in-charge constructors and + destructors (Mark Mitchell, #146416, PR debug/11098) +- fix delete_null_pointer_checks on non-cc0 targets (Alan Modra, #141694, + IT#54408, PR rtl-optimization/14279) +- fix some reload related issues on ppc64 (David Edelsohn, #139099, + IT#45622, PRs target/16239, target/8480, optimization/8328) +- fix ICE in regenerate_decl_from_template (Mark Mitchell, #142418, + PR c++/7053) +- fix ICE when printing jump to case label... crosses initialization + warning (Gabriel Dos Reis, #140830, PR c++/7566) +- fix corner case in passing by invisible reference (Alexandre Oliva, + IT#54891, #141270) +- fix ICE on code that uses value of reference in reference's initializer + (Alexandre Oliva, #141274, IT#36304) +- avoid moving jumptable away from corresponding jump even if there is an + intervening barrier (Josef Zlomek, #131378) +- with -D_GLIBCXX_FULLY_DYNAMIC_STRING, STL should now avoid + _S_empty_rep_storage (Paolo Carlini, #131030, IT#45103, PR libstdc++/16612) +- document -Winline only works for languages that use RTL inliner (Java, + Ada, #141272, IT#28331) + +* Tue Mar 8 2005 Jakub Jelinek 3.2.3-47.fc4 +- new compatibility package