Hello, Using GCC10 on Fedora 31, I built coreutils from a git clone of the latest sources. After running $./bootstrap && ./configure && make I got a few deprecation warnings for sys/sysctl.h which I skipped over, and found an interesting error while building src/yes.o: CC src/yes.o src/yes.c: In function 'main': src/yes.c:110:20: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=] 110 | buf[bufused - 1] = '\n'; | ~~~~~~~~~~~~~~~~~^~~~~~ src/yes.c:100:51: note: at offset -1 to an object with size 8192 allocated by 'xmalloc' here 100 | char *buf = reuse_operand_strings ? *operands : xmalloc (bufalloc); | ^~~~~~~~~~~~~~~~~~
The compiler didn't deduce that the for loop will always iterate at least once, therefore my first thought was to assert(operands < operand_lim) before the start of the for loop on line 102. I 'heard' :) about assure and decided to use that instead, before realizing that I could make it obvious that the loop would run at least once by converting the for loop into a do-while loop. This avoided the warning. I also made sure the tests still pass on F31. Chris Meyering
From 94b603963b93c2d5669d3053c8682b4d442c1a8d Mon Sep 17 00:00:00 2001 From: Chris Meyering <christophe.meyer...@gmail.com> Date: Wed, 29 Jan 2020 22:34:48 -0800 Subject: [PATCH] yes: rearrange code to prevent gcc10 warning * src/yes.c (main): Convert for loop to do-while in order to tell GCC10 that the loop will be run at least once. This avoids the following: src/yes.c:110:20: error: writing 1 byte into a region of size 0 --- src/yes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/yes.c b/src/yes.c index e01213065..335a23b8f 100644 --- a/src/yes.c +++ b/src/yes.c @@ -99,7 +99,8 @@ main (int argc, char **argv) the operands strings; this wins when the buffer would be large. */ char *buf = reuse_operand_strings ? *operands : xmalloc (bufalloc); size_t bufused = 0; - for (char **operandp = operands; operandp < operand_lim; operandp++) + char **operandp = operands; + do { size_t operand_len = strlen (*operandp); if (! reuse_operand_strings) @@ -107,6 +108,7 @@ main (int argc, char **argv) bufused += operand_len; buf[bufused++] = ' '; } + while (++operandp < operand_lim); buf[bufused - 1] = '\n'; /* If a larger buffer was allocated, fill it by repeating the buffer -- 2.24.1