From fd33f259890c119ee0b3a9889e008d928eb32a84 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 27 Jul 2024 00:05:49 -0700 Subject: [PATCH] Pacify gcc 14 -Wanalyzer-infinite-loop MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * gnulib.modules: Add stddef, for ‘unreachable’. * src/compare.c (dumpdir_cmp): Tell GCC that the default case is unreachable. Make just one pass through the string, instead of two passes (one via strcmp, another via strlen). --- gnulib.modules | 1 + src/compare.c | 31 +++++++++++++++++-------------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/gnulib.modules b/gnulib.modules index 0e6cec61..8cbc8dba 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -92,6 +92,7 @@ setenv snprintf stat-time stdbool +stddef stdint stpcpy stdopen diff --git a/src/compare.c b/src/compare.c index d08220a2..348554e3 100644 --- a/src/compare.c +++ b/src/compare.c @@ -334,34 +334,37 @@ diff_special (void) static int dumpdir_cmp (const char *a, const char *b) { - size_t len; - while (*a) switch (*a) { case 'Y': case 'N': - if (!strchr ("YN", *b)) - return 1; - if (strcmp(a + 1, b + 1)) + /* If the null-terminated strings A and B are equal, other + than possibly A's first byte being 'Y' where B's is 'N' or + vice versa, advance A and B past the strings. + Otherwise, return 1. */ + if (! (*b == 'Y' || *b == 'N')) return 1; - len = strlen (a) + 1; - a += len; - b += len; - break; - + a++, b++; + FALLTHROUGH; case 'D': - if (strcmp(a, b)) + /* If the null-terminated strings A and B are equal, advance A + and B past them. Otherwise, return 1. */ + while (*a) + if (*a++ != *b++) + return 1; + if (*b) return 1; - len = strlen (a) + 1; - a += len; - b += len; + a++, b++; break; case 'R': case 'T': case 'X': return *b; + + default: + unreachable (); } return *b; } -- 2.47.2