This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/17365] New: degenerate string.h operations not optimised to no-ops, and can cause compiler warnings
- From: "pc+sourceware at asdf dot org" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Tue, 09 Sep 2014 17:54:47 +0000
- Subject: [Bug libc/17365] New: degenerate string.h operations not optimised to no-ops, and can cause compiler warnings
- Auto-submitted: auto-generated
https://sourceware.org/bugzilla/show_bug.cgi?id=17365
Bug ID: 17365
Summary: degenerate string.h operations not optimised to
no-ops, and can cause compiler warnings
Product: glibc
Version: 2.19
Status: NEW
Severity: minor
Priority: P2
Component: libc
Assignee: unassigned at sourceware dot org
Reporter: pc+sourceware at asdf dot org
CC: drepper.fsp at gmail dot com
For example, in <bits/string2.h> there are macros like this:
# define strncat(dest, src, n) \
(__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n) \
? (strlen (src) < ((size_t) (n)) \
? strcat (dest, src) \
: strncat (dest, src, n)) \
: strncat (dest, src, n)))
With gcc -Wtype-limits, src being a string string literal, and - most
importantly - n being 0, the above can cause compiler diagnostics like:
warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
? strlen (src) < ((size_t) (n))))
Of course, with n==0, the operation is a no-op. Therefore the macros could make
that explicit, to take the responsibility off the compiler for noticing such
shortcuts.
That particular case may sound contrived, but other examples that have the same
issue can easily crop up in real world code, such as strncmp(var,
LITERAL_STRING, sizeof(LITERAL_STRING)-1) where LITERAL_STRING is "".
Alas, even optimising the macro to make it do nothing in the n==0 case doesn't
fix the warnings, as gcc pedantically checks all subexpressions for silliness
even if they can not be evaluated. (To be honest it's the warnings that are
more annoying than the lack of optimisation, as the compiler will almost
certainly optimise the expression to nothing.)
The issue is old - here's an example from a 32-bit glibc 2.11 installation:
baz$ cat > strncmp.c
#include <string.h>
static const char magic[] = "";
int foo(const char *s) {
return strncmp(s, magic, sizeof(magic)-1);
}
baz$ gcc -Wtype-limits -O -o strncmp.o -c strncmp.c
strncmp.c: In function 'foo':
strncmp.c:4: warning: comparison of unsigned expression < 0 is always false
baz$ gcc -v
...
gcc version 4.4.5 (Debian 4.4.5-8)
Another, 64-bit x86_64 with glibc 2.13:
bar$ gcc -Wtype-limits -O -o strncmp.o -c strncmp.c
strncmp.c: In function 'foo':
strncmp.c:4:9: warning: comparison of unsigned expression < 0 is always false
[-Wtype-limits]
strncmp.c:4:9: warning: comparison of unsigned expression < 0 is always false
[-Wtype-limits]
bar$ gcc -v
gcc version 4.7.2 (Debian 4.7.2-5)
And others. I.e. it will occur pretty much no matter the glibc version (2.11,
2.13, 2.19 tested), the arch (x86, x86_64, ppc tested), or the gcc version
(4.4, 4.7, and 4.9 tested). (As long as the compiler actually performs the
substitutions in the macros in your header files. With some compiler settings,
it uses a compiler-builtin <string.h> and ignores your header files. Running
gcc through ccache seems to stops gcc from using its own builtin headers.). All
that matters is that it expands an ``strlen(s) < ((size_t) (n))'' construct.
--
You are receiving this mail because:
You are on the CC list for the bug.