[systemd-devel] compile with clang broken

David Herrmann dh.herrmann at gmail.com
Fri Aug 15 07:30:04 PDT 2014


Hi

On Fri, Aug 15, 2014 at 1:53 PM, Lennart Poettering
<lennart at poettering.net> wrote:
> On Fri, 15.08.14 13:42, David Herrmann (dh.herrmann at gmail.com) wrote:
>
>>
>> Hi
>>
>> On Fri, Aug 15, 2014 at 1:22 PM, Lennart Poettering
>> <lennart at poettering.net> wrote:
>> > On Fri, 15.08.14 13:00, David Herrmann (dh.herrmann at gmail.com) wrote:
>> >
>> >> > src/resolve/resolved-dns-stream.c:67:43: error: non-const static data
>> >> > member must be initialized out of line
>> >> >                 uint8_t buffer[CMSG_SPACE(MAX(sizeof(struct
>> >> > in_pktinfo), sizeof(struct in6_pktinfo)))
>> >> >                                           ^
>> >>
>> >> Ok, this can be fixed by adding "const" to the variables inside the ({
>> >> }) else-clause. But we then end up with:
>> >>   error: statement expression not allowed at file scope
>> >
>> > I wonder if there's *any* way how to implement a double-evalutation-free
>> > all-type MAX() on LLVM... That'd be quite a limitation in LLVM...
>>
>> I looked around and it seems like there's nothing we can do. Weird
>> thing is, LLVM allows const-initialization but not member-definition
>> with that macro. I really don't understand why..
>>
>> I somehow think adding MAX_CONST which uses __builtin_constant_p and
>> assert_cc() is the easiest way here. That is, we use MAX_CONST() for
>> all cases where MAX fails. I think this is the easiest way to
>> guarantee no-one else changes the code to use MAX() again.
>> Furthermore, it guarantees that MAX_CONST is *really* called with
>> constant arguments.
>
> If that is what it takes, go ahead.
>
> Let it be known though for all future: I think LLVM is stupid here.

Ok, took me a while, but I now figured out how to cause compilation to
fail even in expressions that initialize types (_Static_assert is not
allowed there):
  #define assert_const(expr)
((void)(__builtin_types_compatible_p(int[(expr) ? 1 : -1], int[1])))

Btw., I like that more than our current assert_cc() fallback. But I
leave it up to you to decide.

Anyhow, I found a way to make CONST_MAX work:
#define CONST_MAX(_A, _B)
(__builtin_choose_expr(__builtin_constant_p(_A) &&
__builtin_constant_p(_B), ((_A) > (_B)) ? (_A) : (_B), (void)0))

This will return (void) in case _A or _B is not constant. Works fine
on LLVM, I now have to test it on gcc. If it works, I will commit it
and fix resolvd.

Cheers
David


More information about the systemd-devel mailing list