]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - locale/weight.h
Fix -Os strcoll, wcscoll, build (bug 21313).
[thirdparty/glibc.git] / locale / weight.h
index 6151faacea8a701d32655c403665bac484d670c5..6028d3595e41cd9cc53fb4e6b7d766714e51a451 100644 (file)
@@ -1,25 +1,32 @@
-/* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper, <drepper@cygnus.com>.
 
    The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
 
    The GNU C 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
-   Library General Public License for more details.
+   Lesser General Public License for more details.
 
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _WEIGHT_H_
+#define _WEIGHT_H_     1
+
+#include <libc-diag.h>
 
 /* Find index of weight.  */
-static inline int32_t
-findidx (const unsigned char **cpp)
+static inline int32_t __attribute__ ((always_inline))
+findidx (const int32_t *table,
+        const int32_t *indirect,
+        const unsigned char *extra,
+        const unsigned char **cpp, size_t len)
 {
   int_fast32_t i = table[*(*cpp)++];
   const unsigned char *cp;
@@ -33,12 +40,13 @@ findidx (const unsigned char **cpp)
      Search for the correct one.  */
   cp = &extra[-i];
   usrc = *cpp;
+  --len;
   while (1)
     {
       size_t nhere;
 
       /* The first thing is the index.  */
-      i = *((int32_t *) cp);
+      i = *((const int32_t *) cp);
       cp += sizeof (int32_t);
 
       /* Next is the length of the byte sequence.  These are always
@@ -55,9 +63,17 @@ findidx (const unsigned char **cpp)
             already.  */
          size_t cnt;
 
-         for (cnt = 0; cnt < nhere; ++cnt)
+         /* With GCC 5.3 when compiling with -Os the compiler warns
+            that seq2.back_us, which becomes usrc, might be used
+            uninitialized.  This can't be true because we pass a length
+            of -1 for len at the same time which means that this loop
+            never executes.  */
+         DIAG_PUSH_NEEDS_COMMENT;
+         DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+         for (cnt = 0; cnt < nhere && cnt < len; ++cnt)
            if (cp[cnt] != usrc[cnt])
              break;
+         DIAG_POP_NEEDS_COMMENT;
 
          if (cnt == nhere)
            {
@@ -68,8 +84,8 @@ findidx (const unsigned char **cpp)
 
          /* Up to the next entry.  */
          cp += nhere;
-         if ((1 + nhere) % __alignof__ (int32_t) != 0)
-           cp += __alignof__ (int32_t) - (1 + nhere) % __alignof__ (int32_t);
+         if (!LOCFILE_ALIGNED_P (1 + nhere))
+           cp += LOCFILE_ALIGN - (1 + nhere) % LOCFILE_ALIGN;
        }
       else
        {
@@ -78,19 +94,19 @@ findidx (const unsigned char **cpp)
          size_t cnt;
          size_t offset = 0;
 
-         for (cnt = 0; cnt < nhere; ++cnt)
+         for (cnt = 0; cnt < nhere && cnt < len; ++cnt)
            if (cp[cnt] != usrc[cnt])
              break;
 
          if (cnt != nhere)
            {
-             if (cp[cnt] > usrc[cnt])
+             if (cnt == len || cp[cnt] > usrc[cnt])
                {
                  /* Cannot be in this range.  */
                  cp += 2 * nhere;
-                 if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0)
-                   cp += (__alignof__ (int32_t)
-                          - (1 + 2 * nhere) % __alignof__ (int32_t));
+                 if (!LOCFILE_ALIGNED_P (1 + 2 * nhere))
+                   cp += (LOCFILE_ALIGN
+                          - (1 + 2 * nhere) % LOCFILE_ALIGN);
                  continue;
                }
 
@@ -103,9 +119,9 @@ findidx (const unsigned char **cpp)
                {
                  /* Cannot be in this range.  */
                  cp += 2 * nhere;
-                 if ((1 + 2 * nhere) % __alignof__ (int32_t) != 0)
-                   cp += (__alignof__ (int32_t)
-                          - (1 + 2 * nhere) % __alignof__ (int32_t));
+                 if (!LOCFILE_ALIGNED_P (1 + 2 * nhere))
+                   cp += (LOCFILE_ALIGN
+                          - (1 + 2 * nhere) % LOCFILE_ALIGN);
                  continue;
                }
 
@@ -116,7 +132,15 @@ findidx (const unsigned char **cpp)
              do
                {
                  offset <<= 8;
+                 /* With GCC 7 when compiling with -Os the compiler
+                    warns that seq1.back_us and seq2.back_us, which
+                    become usrc, might be used uninitialized.  This
+                    is impossible for the same reason as described
+                    above.  */
+                 DIAG_PUSH_NEEDS_COMMENT;
+                 DIAG_IGNORE_Os_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
                  offset += usrc[cnt] - cp[cnt];
+                 DIAG_POP_NEEDS_COMMENT;
                }
              while (++cnt < nhere);
            }
@@ -129,3 +153,5 @@ findidx (const unsigned char **cpp)
   /* NOTREACHED */
   return 0x43219876;
 }
+
+#endif /* weight.h */