This is a 40-line MCVE (Minimal, Complete, Verifiable Example) — or something close to minimal — cut down from a 1675 line source file that originally included 32 headers (and most of those included multiple other headers — compiling it with gcc -H
lists 464 headers from the project and the system, many of them several times). That file is working code that previously compiled without warnings (GCC 8.3.0), but not with GCC 9.1.0. All structure, function, type, variable names have been changed.
pf31.c
#include <string.h>
enum { SERVERNAME_LEN = 128 };
typedef struct ServerQueue
{
char server_name[SERVERNAME_LEN + 1];
struct ServerQueue *next;
} ServerQueue;
extern int function_under_test(char *servername);
#ifdef SUPPRESS_BUG
extern int function_using_name(char *name);
#endif /* SUPPRESS_BUG */
extern int GetServerQueue(const char *servername, ServerQueue *queue);
int
function_under_test(char *servername)
{
ServerQueue queue;
char name[SERVERNAME_LEN + 1];
if (GetServerQueue(servername, &queue) != 0)
return -1;
char *name_in_queue = queue.server_name;
if (name_in_queue)
strncpy(name, name_in_queue, SERVERNAME_LEN);
else
strncpy(name, servername, SERVERNAME_LEN);
name[SERVERNAME_LEN] = '\0';
#ifdef SUPPRESS_BUG
return function_using_name(name);
#else
return 0;
#endif /* SUPPRESS_BUG */
}
When compiled using GCC 9.1.0 (on a Mac running macOS 10.14.5 Mojave, or on a Linux VM running RedHat 5.x — don't ask!), with the option -DSUPPRESS_BUG
I get no error, but with the option -USUPPRESS_BUG
, I get an error:
$ gcc -std=c11 -O3 -g -Wall -Wextra -Werror -DSUPPRESS_BUG -c pf31.c
$ gcc -std=c11 -O3 -g -Wall -Wextra -Werror -USUPPRESS_BUG -c pf31.c
In file included from /usr/include/string.h:417,
from pf31.c:1:
pf31.c: In function ‘function_under_test’:
pf31.c:30:9: error: ‘__builtin_strncpy’ output may be truncated copying 128 bytes from a string of length 128 [-Werror=stringop-truncation]
30 | strncpy(name, name_in_queue, SERVERNAME_LEN);
| ^~~~~~~
cc1: all warnings being treated as errors
$
When I compile using GCC 8.3.0, I get no errors reported.
Two sides of one question:
strncpy()
when the code is compiled with -USUPPRESS_BUG
?-DSUPPRESS_BUG
?
strncpy()
to limit the amount of data copied, which is what it is designed for".I have another non-erroring variant, changing the signature of the function_under_test()
— here's a set of diffs:
11c11
< extern int function_under_test(char *servername);
---
> extern int function_under_test(char *servername, ServerQueue *queue);
20c20
< function_under_test(char *servername)
---
> function_under_test(char *servername, ServerQueue *queue)
22d21
< ServerQueue queue;
25c24
< if (GetServerQueue(servername, &queue) != 0)
---
> if (GetServerQueue(servername, queue) != 0)
27c26
< char *name_in_queue = queue.server_name;
---
> char *name_in_queue = queue->server_name;
This compiles cleanly regardless of whether SUPPRESS_BUG
is defined or not.
As you can guess from the SUPPRESS_BUG
terminology, I'm tending towards the view that this is bug in GCC, but I'm kinda cautious about claiming it is one just yet.
More about the the original code: the function itself was 540 lines long; the strncpy()
block occurs about 170 lines into the function; the variable corresponding to name
was used further down the function in a number of function call, some of which take name
as an argument and supply a return value for the function. This corresponds more to the -DSUPPRESS_BUG
code, except that in the 'real code', the bug is not suppressed.
This is a GCC bug tracked as PR88780. According to Martin's comment, this warning did not exist prior to GCC 8.
GCC is shipped with this known bug, as it is not deemed release-critical.
To be honest, I am not 100% sure it is the bug. The point is, there are known false-positives. If you feel like helping the GCC project, you can find the most appropriate bug among strncpy
/ Wstringop-truncation
bugs and post your example there. It would be more helpful if you minimized it further (say, with creduce
); minimizing the compile string is also appreciated (that would be rather trivial, I guess).
Several compilation warnings related to strncpy
were found in GCC 9.0 and reported here and here.
One of them is the error mentioned in the question which seems to occur in the file string_fortified.h
:
/usr/include/bits/string_fortified.h:106:10: warning: ‘__builtin_strncpy’ output may be truncated copying 16 bytes from a string of length 16 [-Wstringop-truncation]
106 | return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The response to this was given on April 15, 2019 was:
Thank you for the report, however as GCC 9 still under development. We do not see the above errors in the current stable GCC 7.4 or GCC 8.3. We appreciate the advanced notice, and will accept PRs to fix issues against GCC 9, but for now our target compiler is gcc stable.
So I believe the errors are probably a result of versions 9 and 9.1 being not stable versions. Hopefully they will be eliminated when these versions become stable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With