#758911 libc6-dev: spurious sign-conversion warning for setrlimit, clang 3.5, _GNU_SOURCE

Package:
libc6-dev
Source:
glibc
Description:
GNU C Library: Development Libraries and Header Files
Submitter:
Zack Weinberg
Date:
2014-08-25 15:09:08 UTC
Severity:
minor
Tags:
#758911#5
Date:
2014-08-22 19:23:15 UTC
From:
To:
glibc changes the signature of setrlimit() when _GNU_SOURCE is defined, "to
provide better error checking":

extern int setrlimit (int, const struct rlimit *); // as specified by POSIX
extern int setrlimit (__rlimit_resource_t, const struct rlimit *); //
_GNU_SOURCE

where __rlimit_resource_t is an enum with no negative values.  This causes some
compilers (e.g. clang-3.5) to give spurious warnings for programs that pass
non-constant values to setrlimit(), e.g.

$ cat test.c
#define _GNU_SOURCE
#include <sys/resource.h>
int foo(int rsrc, struct rlimit *rl)
{
  return setrlimit(rsrc, rl);
}
$ clang-3.5 -Wsign-conversion -c test.c
test.c:5:20: warning: implicit conversion changes signedness: 'int' to
'__rlimit_resource_t' (aka 'enum __rlimit_resource')
      [-Wsign-conversion]
  return setrlimit(rsrc, rl);
         ~~~~~~~~~ ^~~~

I don't think it's reasonable for me to have to work around this in my code,
and indeed I don't see that there _is_ any workaround available to me in C.
(Maybe in C++ some template black magic to extract "the type of the first
argument to setrlimit"? Yech.)

I'm labeling this a libc bug rather than a clang bug because, if libc is going
to deviate from the standard "to provide better error checking", it needs to
ensure that standard-compliant code still works with no complaints, even at
quite aggressive warning levels.

#758911#10
Date:
2014-08-23 11:53:34 UTC
From:
To:
I agree.

It isn't reasonable for users to have to work around this. Please file
a bug with clang and ask them to come work with with upstream glibc to
help provide better error checking and remove the spurious warning for
this case.

My opinion is that this is not a libc bug and I would suggest
debian-glibc close this bug. You deviated from the standard the second
you defined _GNU_SOURCE. If you want POSIX, but define _GNU_SOURCE,
and then complain it's not *exactly* POSIX then I don't see what we
did wrong. At best this is an enhancement: "Be more POSIX-like if I
define _GNU_SOURCE and happen to be using clang."

Cheers,
Carlos.

#758911#15
Date:
2014-08-25 14:50:26 UTC
From:
To:
forwarded 758911 https://sourceware.org/bugzilla/show_bug.cgi?id=17307
affects 758911 +clang-3.5
stop

On Sat, Aug 23, 2014 at 7:53 AM, Carlos O'Donell <carlos@systemhalted.org> wrote:

Done.

clang bug: http://llvm.org/bugs/show_bug.cgi?id=20742
upstream libc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=17307

Both are annotated with the other.

When I define _GNU_SOURCE, I want POSIX conformance for everything
that POSIX specifies; I just *also* want some GNU extensions -- in the
case of the program that originally provoked this bug report,
`vasprintf`, `initgroups`, and `execvpe`.

Therefore, it is my considered opinion that defining _GNU_SOURCE
should not change the signature of any standard-specified function in
any way that is observable by correct code, even when arbitrarily
aggressive compiler warnings are activated.  "Correct" means "written
as if the functions had the signatures declared in the standard, and
provoking no undefined behavior."

(I'm willing to make an exception for when the standard itself has a
bug in it -- the obvious case that comes to mind is `struct timespec`,
whose `tv_nsec` field never should have been specified as bare `long`
in the first place.  But that sort of thing is going to wind up
affecting code that defines _POSIX_C_SOURCE or _XOPEN_SOURCE as well.)

zw