shared/extract-word: replace enum with unsigned int to avoid undefined behaviour
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 22 Apr 2017 23:04:02 +0000 (19:04 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 26 Apr 2017 01:12:52 +0000 (21:12 -0400)
commite4d85dbb3d5a2217167f419794e37c181bc9fe81
tree5570b296a855cb3d794962b06ce162a6777f8015
parent1f0f4f3bfd05fd416e3e2dea10ad225b276a6ef7
shared/extract-word: replace enum with unsigned int to avoid undefined behaviour

../src/basic/extract-word.c:255:22: warning: passing an object that undergoes default argument promotion to 'va_start' has undefined behavior [-Wvarargs]
        va_start(ap, flags);
                     ^
../src/basic/extract-word.c:244:77: note: parameter of type 'ExtractFlags' (aka 'enum ExtractFlags') is declared here
int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
                                                                            ^
../src/basic/extract-word.c:286:22: warning: passing an object that undergoes default argument promotion to 'va_start' has undefined behavior [-Wvarargs]
        va_start(ap, flags);
                     ^
../src/basic/extract-word.c:244:77: note: parameter of type 'ExtractFlags' (aka 'enum ExtractFlags') is declared here
int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
                                                                            ^
2 warnings generated.

I think the relevant part of C99 is 6.7.2.2 Enumeration specifiers:

Each enumerated type shall be compatible with char, a signed integer type, or
an unsigned integer type. The choice of type is implementation-defined, but
shall be capable of representing the values of all the members of the
enumeration.

and 7.16.1.4:

The parameter parmN is the identifier of the rightmost parameter in the
variable parameter list in the function definition (the one just before the
...). If the parameter parmN is declared with the register storage class, with
a function or array type, or with a type that is not compatible with the type
that results after application of the default argument promotions, the behavior
is undefined.

This might cause a real issue if the compiler chooses something that is not an
integer for ExtractFlags. Rework the code to avoid the warning, but add an
assert_cc in a large-valued ExtractFlags element is ever defined and the type
is bumped to something wider than an int.
src/basic/extract-word.c
src/basic/extract-word.h