]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - string/strcoll_l.c
Make mktime etc. compatible with __time64_t
[thirdparty/glibc.git] / string / strcoll_l.c
index 8f1225fc7aefcf304e69c348657d23cbfba8ad13..1b5ec5d97917760003e397428215cfe6d51b3fce 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2015 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2019 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Ulrich Drepper <drepper@gnu.org>, 1995.
 
 #include <stdint.h>
 #include <string.h>
 #include <sys/param.h>
+#include <libc-diag.h>
 
 #ifndef STRING_TYPE
 # define STRING_TYPE char
 # define USTRING_TYPE unsigned char
 # define STRCOLL __strcoll_l
-# define STRDIFF __strdiff
 # define STRCMP strcmp
 # define WEIGHT_H "../locale/weight.h"
 # define SUFFIX        MB
 #include "../locale/localeinfo.h"
 #include WEIGHT_H
 
-#define MASK_UTF8_7BIT  (1 << 7)
-#define MASK_UTF8_START (3 << 6)
-
-size_t
-STRDIFF (const STRING_TYPE *s, const STRING_TYPE *t)
-{
-  size_t n;
-
-  for (n = 0; *s != '\0' && *s++ == *t++; ++n)
-    continue;
-
-  return n;
-}
-
 /* Track status while looking for sequences in a string.  */
 typedef struct
 {
@@ -185,7 +171,19 @@ get_next_seq (coll_seq *seq, int nrules, const unsigned char *rulesets,
            }
        }
 
+      /* With GCC 5.3 when compiling with -Os the compiler complains
+        that idx, taken from seq->idx (seq1 or seq2 from STRCOLL) may
+        be used uninitialized.  In general this can't possibly be true
+        since seq1.idx and seq2.idx are initialized to zero in the
+        outer function.  Only one case where seq->idx is restored from
+        seq->save_idx might result in an uninitialized idx value, but
+        it is guarded by a sequence of checks against backw_stop which
+        ensures that seq->save_idx was saved to first and contains a
+        valid value.  */
+      DIAG_PUSH_NEEDS_COMMENT;
+      DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
       len = weights[idx++];
+      DIAG_POP_NEEDS_COMMENT;
       /* Skip over indices of previous levels.  */
       for (int i = 0; i < pass; i++)
        {
@@ -257,7 +255,7 @@ out:
 }
 
 int
-STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
+STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, locale_t l)
 {
   struct __locale_data *current = l->__locales[LC_COLLATE];
   uint_fast32_t nrules = current->values[_NL_ITEM_INDEX (_NL_COLLATE_NRULES)].word;
@@ -269,29 +267,9 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
   const USTRING_TYPE *extra;
   const int32_t *indirect;
 
-  /* In case there is no locale specific sort order (C / POSIX).  */
   if (nrules == 0)
     return STRCMP (s1, s2);
 
-  /* Fast forward to the position of the first difference.  Needs to be
-     encoding aware as the byte-by-byte comparison can stop in the middle
-     of a char sequence for multibyte encodings like UTF-8.  */
-  uint_fast32_t encoding =
-    current->values[_NL_ITEM_INDEX (_NL_COLLATE_ENCODING_TYPE)].word;
-  if (encoding != __cet_other)
-    {
-      size_t diff = STRDIFF (s1, s2);
-      if (diff > 0)
-       {
-         if (encoding == __cet_utf8 && (*(s1 + diff) & MASK_UTF8_7BIT) != 0)
-           do
-             diff--;
-           while (diff > 0 && (*(s1 + diff) & MASK_UTF8_START) != MASK_UTF8_START);
-         s1 += diff;
-         s2 += diff;
-       }
-    }
-
   /* Catch empty strings.  */
   if (__glibc_unlikely (*s1 == '\0') || __glibc_unlikely (*s2 == '\0'))
     return (*s1 != '\0') - (*s2 != '\0');
@@ -314,7 +292,17 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
 
   int result = 0, rule = 0;
 
+  /* With GCC 7 when compiling with -Os the compiler warns that
+     seq1.back_us and seq2.back_us might be used uninitialized.
+     Sometimes this warning appears at locations in locale/weightwc.h
+     where the actual use is, but on architectures other than x86_64,
+     x86 and s390x, a warning appears at the definitions of seq1 and
+     seq2.  This uninitialized use is impossible for the same reason
+     as described in comments in locale/weightwc.h.  */
+  DIAG_PUSH_NEEDS_COMMENT;
+  DIAG_IGNORE_Os_NEEDS_COMMENT (7, "-Wmaybe-uninitialized");
   coll_seq seq1, seq2;
+  DIAG_POP_NEEDS_COMMENT;
   seq1.len = 0;
   seq1.idxmax = 0;
   seq1.rule = 0;
@@ -358,8 +346,7 @@ STRCOLL (const STRING_TYPE *s1, const STRING_TYPE *s2, __locale_t l)
                     byte-level comparison to ensure that we don't waste time
                     going through multiple passes for totally equal strings
                     before proceeding to subsequent passes.  */
-                 if (pass == 0 && encoding == __cet_other &&
-                     STRCMP (s1, s2) == 0)
+                 if (pass == 0 && STRCMP (s1, s2) == 0)
                    return result;
                  else
                    break;