locale_facets.tcc (num_get<>::_M_extract_float): Evaluate *__beg the exact strict...
authorPaolo Carlini <pcarlini@suse.de>
Mon, 1 Nov 2004 11:31:44 +0000 (11:31 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 1 Nov 2004 11:31:44 +0000 (11:31 +0000)
2004-11-01  Paolo Carlini  <pcarlini@suse.de>

* include/bits/locale_facets.tcc (num_get<>::_M_extract_float):
Evaluate *__beg the exact strict minimum number of times; likewise
for __beg != __end; in the main parsing loop, call ++__beg in two
places only. The former is also a correctness issue, because,
according to the standard (22.2.2.1.2, Stage 2), 'in' shall be
dereferenced only one time for each increment.

From-SVN: r89940

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/locale_facets.tcc

index 43745a49542e00453f36ad935a168245b3c094c1..ec19144b9650a5020f8c0f5463a98cf559533bd9 100644 (file)
@@ -1,3 +1,12 @@
+2004-11-01  Paolo Carlini  <pcarlini@suse.de>
+
+       * include/bits/locale_facets.tcc (num_get<>::_M_extract_float):
+       Evaluate *__beg the exact strict minimum number of times; likewise
+       for __beg != __end; in the main parsing loop, call ++__beg in two
+       places only. The former is also a correctness issue, because,
+       according to the standard (22.2.2.1.2, Stage 2), 'in' shall be
+       dereferenced only one time for each increment.
+
 2004-10-31  Benjamin Kosnik  <bkoz@redhat.com>
 
        PR c++/16728
index a95882488407c4d41bbb553ec676ead6d8ab47df..0f92db205a116a34a9f8f1c8f5d9f04ab4aebf88 100644 (file)
@@ -279,28 +279,34 @@ namespace std
       const locale& __loc = __io._M_getloc();
       const __cache_type* __lc = __uc(__loc);
       const _CharT* __lit = __lc->_M_atoms_in;
+      char_type __c = char_type();
 
-      // True if a mantissa is found.
-      bool __found_mantissa = false;
+      // True if __beg becomes equal to __end.
+      bool __testeof = __beg == __end;
 
       // First check for sign.
-      if (__beg != __end)
+      if (!__testeof)
        {
-         const char_type __c = *__beg;
+         __c = *__beg;
          const bool __plus = __c == __lit[__num_base::_S_iplus];
          if ((__plus || __c == __lit[__num_base::_S_iminus])
              && !(__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
              && !(__c == __lc->_M_decimal_point))
            {
              __xtrc += __plus ? '+' : '-';
-             ++__beg;
+             if (++__beg != __end)
+               __c = *__beg;
+             else
+               __testeof = true;
            }
        }
 
+      // True if a mantissa is found.
+      bool __found_mantissa = false;
+
       // Next, look for leading zeros.
-      while (__beg != __end)
+      while (!__testeof)
        {
-         const char_type __c = *__beg;
          if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep
              || __c == __lc->_M_decimal_point)
            break;
@@ -311,7 +317,10 @@ namespace std
                  __xtrc += '0';
                  __found_mantissa = true;
                }
-             ++__beg;
+             if (++__beg != __end)
+               __c = *__beg;
+             else
+               __testeof = true;
            }
          else
            break;
@@ -324,12 +333,12 @@ namespace std
       if (__lc->_M_use_grouping)
        __found_grouping.reserve(32);
       int __sep_pos = 0;
+      const char_type* __q;
       const char_type* __lit_zero = __lit + __num_base::_S_izero;
-      while (__beg != __end)
+      while (!__testeof)
         {
          // According to 22.2.2.1.2, p8-9, first look for thousands_sep
          // and decimal_point.
-         char_type __c = *__beg;
           if (__lc->_M_use_grouping && __c == __lc->_M_thousands_sep)
            {
              if (!__found_dec && !__found_sci)
@@ -340,7 +349,6 @@ namespace std
                    {
                      __found_grouping += static_cast<char>(__sep_pos);
                      __sep_pos = 0;
-                     ++__beg;
                    }
                  else
                    {
@@ -362,50 +370,53 @@ namespace std
                    __found_grouping += static_cast<char>(__sep_pos);
                  __xtrc += '.';
                  __found_dec = true;
-                 ++__beg;
                }
              else
                break;
            }
-          else
+          else if ((__q = __traits_type::find(__lit_zero, 10, __c)))
            {
-             const char_type* __q = __traits_type::find(__lit_zero, 10, __c);
-             if (__q)
+             __xtrc += __num_base::_S_atoms_in[__q - __lit];
+             __found_mantissa = true;
+             ++__sep_pos;
+           }
+         else if ((__c == __lit[__num_base::_S_ie] 
+                   || __c == __lit[__num_base::_S_iE])
+                  && __found_mantissa && !__found_sci)
+           {
+             // Scientific notation.
+             if (__found_grouping.size() && !__found_dec)
+               __found_grouping += static_cast<char>(__sep_pos);
+             __xtrc += 'e';
+             __found_sci = true;
+
+             // Remove optional plus or minus sign, if they exist.
+             if (++__beg != __end)
                {
-                 __xtrc += __num_base::_S_atoms_in[__q - __lit];
-                 __found_mantissa = true;
-                 ++__sep_pos;
-                 ++__beg;
+                 __c = *__beg;
+                 const bool __plus = __c == __lit[__num_base::_S_iplus];
+                 if ((__plus || __c == __lit[__num_base::_S_iminus])
+                     && !(__lc->_M_use_grouping
+                          && __c == __lc->_M_thousands_sep)
+                     && !(__c == __lc->_M_decimal_point))
+                   __xtrc += __plus ? '+' : '-';
+                 else
+                   continue;
                }
-             else if ((__c == __lit[__num_base::_S_ie] 
-                       || __c == __lit[__num_base::_S_iE])
-                      && __found_mantissa && !__found_sci)
+             else
                {
-                 // Scientific notation.
-                 if (__found_grouping.size() && !__found_dec)
-                   __found_grouping += static_cast<char>(__sep_pos);
-                 __xtrc += 'e';
-                 __found_sci = true;
-
-                 // Remove optional plus or minus sign, if they exist.
-                 if (++__beg != __end)
-                   {
-                     __c = *__beg;
-                     const bool __plus = __c == __lit[__num_base::_S_iplus];
-                     if ((__plus || __c == __lit[__num_base::_S_iminus])
-                         && !(__lc->_M_use_grouping
-                              && __c == __lc->_M_thousands_sep)
-                         && !(__c == __lc->_M_decimal_point))
-                       {
-                         __xtrc += __plus ? '+' : '-';
-                         ++__beg;
-                       }
-                   }
+                 __testeof = true;
+                 break;
                }
-             else
-               // Not a valid input item.
-               break;
            }
+         else
+           // Not a valid input item.
+           break;
+
+         if (++__beg != __end)
+           __c = *__beg;
+         else
+           __testeof = true;
         }
 
       // Digit grouping is checked. If grouping and found_grouping don't
@@ -423,7 +434,7 @@ namespace std
         }
 
       // Finish up.
-      if (__beg == __end)
+      if (__testeof)
         __err |= ios_base::eofbit;
       return __beg;
     }