diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 4d0d91730ed22458c714cc6815ed9a00e0d2d94e..6222c1ec77da7e2f31dda27bd16aae77b692c80b 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,11 @@
+2002-03-08  Benjamin Kosnik  <bkoz@redhat.com>
+
+	* include/std/std_limits.h: Move static const data members out of
+	generic template, into base class __numeric_limits_base.
+	* src/limits.cc: Add definitions.
+	* config/linker-map.gnu: Add __numeric_limits_base.
+	* testsuite/18_support/numeric_limits.cc: Declare test in scope.
+	
 2002-03-07  Benjamin Kosnik  <bkoz@redhat.com>
 
 	* include/bits/stl_alloc.h: Add extern implicit allocator
diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu
index 71395527c42a0c6d2dccdeb5d701d2191b1a2406..240ca0138eff14514315984e806547140ecaca46 100644
--- a/libstdc++-v3/config/linker-map.gnu
+++ b/libstdc++-v3/config/linker-map.gnu
@@ -33,7 +33,8 @@ GLIBCPP_3.1 {
       std::__throw_*;
       std::__basic_file*;
       std::__num_base*;
-      std::__timepunct*
+      std::__timepunct*;
+      std::__numeric_limits_base*
     };
 
     # Names not in an 'extern' block are mangled names.
diff --git a/libstdc++-v3/include/std/std_limits.h b/libstdc++-v3/include/std/std_limits.h
index 91125ef949547e85a4014eab1938eb032bc7809b..d2b57e39cc756069c94beaa1dea2fae9a18e8c43 100644
--- a/libstdc++-v3/include/std/std_limits.h
+++ b/libstdc++-v3/include/std/std_limits.h
@@ -908,140 +908,52 @@ namespace std
   //
   // 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<typename _Tp> 
-    struct numeric_limits 
+    struct numeric_limits : public __numeric_limits_base 
     {
-      static const bool is_specialized = false;
-
       static _Tp min() throw() { return static_cast<_Tp>(0); }
       static _Tp max() throw() { return static_cast<_Tp>(0); }
-
-      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 _Tp epsilon() throw() { return static_cast<_Tp>(0); }
       static _Tp round_error() throw() { return static_cast<_Tp>(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 _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); }
-
-      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<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_specialized;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::digits;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::digits10;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_signed;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_integer;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_exact;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::radix;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::min_exponent;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::min_exponent10;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::max_exponent;
-
-  template<typename _Tp> 
-    const int
-    numeric_limits<_Tp>::max_exponent10;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::has_infinity;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::has_quiet_NaN;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::has_signaling_NaN;
-
-  template<typename _Tp> 
-    const float_denorm_style
-    numeric_limits<_Tp>::has_denorm;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::has_denorm_loss;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_iec559;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_bounded;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::is_modulo;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::traps;
-
-  template<typename _Tp> 
-    const bool
-    numeric_limits<_Tp>::tinyness_before;
-
-  template<typename _Tp> 
-    const float_round_style
-    numeric_limits<_Tp>::round_style;
-
   // Now there follow 15 explicit specializations.  Yes, 15.  Make sure
-  // you get the count right.
-  
+  // you get the count right.  
   template<>
     struct numeric_limits<bool>
     {
diff --git a/libstdc++-v3/src/limits.cc b/libstdc++-v3/src/limits.cc
index 3fc3dcb8fb30352cb9f21036bd3dc31f65a094f8..294673ea186999dd92e9268693e1121f944bbab5 100644
--- a/libstdc++-v3/src/limits.cc
+++ b/libstdc++-v3/src/limits.cc
@@ -1,6 +1,6 @@
 // Static data members of -*- C++ -*- numeric_limits classes
 
-// Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2001, 2002 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
@@ -38,6 +38,29 @@
 
 namespace std 
 {
+  const bool __numeric_limits_base::is_specialized;
+  const int  __numeric_limits_base::digits;
+  const int  __numeric_limits_base::digits10;
+  const bool __numeric_limits_base::is_signed;
+  const bool __numeric_limits_base::is_integer;
+  const bool __numeric_limits_base::is_exact;
+  const int  __numeric_limits_base::radix;
+  const int  __numeric_limits_base::min_exponent;
+  const int  __numeric_limits_base::min_exponent10;
+  const int  __numeric_limits_base::max_exponent;
+  const int  __numeric_limits_base::max_exponent10;
+  const bool __numeric_limits_base::has_infinity;
+  const bool __numeric_limits_base::has_quiet_NaN;
+  const bool __numeric_limits_base::has_signaling_NaN;
+  const float_denorm_style __numeric_limits_base::has_denorm;
+  const bool __numeric_limits_base::has_denorm_loss;
+  const bool __numeric_limits_base::is_iec559;
+  const bool __numeric_limits_base::is_bounded;
+  const bool __numeric_limits_base::is_modulo;
+  const bool __numeric_limits_base::traps;
+  const bool __numeric_limits_base::tinyness_before;
+  const float_round_style __numeric_limits_base::round_style;
+
   // bool
   const bool numeric_limits<bool>::is_specialized;
   const int  numeric_limits<bool>::digits;
diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits.cc b/libstdc++-v3/testsuite/18_support/numeric_limits.cc
index 6cbeacb4d03b4727a15368c2057f487258e3b1e3..bf9d9e0c35d57fab0ac0c5fa5d57084e45b217de 100644
--- a/libstdc++-v3/testsuite/18_support/numeric_limits.cc
+++ b/libstdc++-v3/testsuite/18_support/numeric_limits.cc
@@ -55,6 +55,7 @@ DEFINE_EXTREMA(long double, LDBL_MIN, LDBL_MAX);
 template<typename T>
 void test_extrema()
 {
+  bool test = true;
   VERIFY( extrema<T>::min == std::numeric_limits<T>::min() );
   VERIFY( extrema<T>::max == std::numeric_limits<T>::max() );
 }
@@ -73,6 +74,7 @@ template<>
 void test_extrema<long double>()
 {
   typedef long double T;
+  bool test = true;
   VERIFY( (extrema<T>::min - std::numeric_limits<T>::min())
             < std::numeric_limits<T>::epsilon() );
   VERIFY( (std::numeric_limits<T>::min() - extrema<T>::min)
@@ -92,6 +94,7 @@ void test_extrema<long double>()
 
 void test_sign()
 {
+  bool test = true;
   VERIFY( std::numeric_limits<char>::is_signed == char_is_signed );
   VERIFY( std::numeric_limits<signed char>::is_signed == true );
   VERIFY( std::numeric_limits<unsigned char>::is_signed == false );
@@ -230,9 +233,3 @@ int main()
 
     return 0;
 }
-
-
-
-
-
-