wahern / cqueues

Continuation Queues: Embeddable asynchronous networking, threading, and notification framework for Lua on Unix.
http://25thandclement.com/~william/projects/cqueues.html
MIT License
248 stars 37 forks source link

Build fails with GCC 9 #212

Closed pspacek closed 5 years ago

pspacek commented 5 years ago

Hello,

it turns out that latest version of cqueues does not build using GCC 9.

Example: https://kojipkgs.fedoraproject.org//work/tasks/3269/32433269/build.log


BUILDSTDERR: In file included from /builddir/build/BUILD/cqueues-20171014/src/dns.c:43:
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/dns.c: In function 'res_new':
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:1059:24: error: lvalue required as unary '&' operand
BUILDSTDERR:  1059 | #define dns_opts(...) (&dns_quietinit((struct dns_options)DNS_OPTS_INIT(__VA_ARGS__)))
BUILDSTDERR:       |                        ^

or similarly

BUILDSTDERR: In file included from /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:80:
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c: In function 'dns_p_merge':
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:527:16: error: lvalue required as unary '&' operand
BUILDSTDERR:   527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))
BUILDSTDERR:       |                ^
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:565:53: note: in expansion of macro 'dns_rr_i_new'
BUILDSTDERR:   565 |  for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); )
BUILDSTDERR:       |                                                     ^~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:567:29: note: in expansion of macro 'dns_rr_foreach_'
BUILDSTDERR:   567 | #define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__)
BUILDSTDERR:       |                             ^~~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:1672:4: note: in expansion of macro 'dns_rr_foreach'
BUILDSTDERR:  1672 |    dns_rr_foreach(&rr, A, .section = section) {
BUILDSTDERR:       |    ^~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:527:16: error: lvalue required as unary '&' operand
BUILDSTDERR:   527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))
BUILDSTDERR:       |                ^
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:565:53: note: in expansion of macro 'dns_rr_i_new'
BUILDSTDERR:   565 |  for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); )
BUILDSTDERR:       |                                                     ^~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:567:29: note: in expansion of macro 'dns_rr_foreach_'
BUILDSTDERR:   567 | #define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__)
BUILDSTDERR:       |                             ^~~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:1679:4: note: in expansion of macro 'dns_rr_foreach'
BUILDSTDERR:  1679 |    dns_rr_foreach(&rr, B, .section = section) {
BUILDSTDERR:       |    ^~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:527:16: error: lvalue required as unary '&' operand
BUILDSTDERR:   527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))
BUILDSTDERR:       |                ^
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:565:53: note: in expansion of macro 'dns_rr_i_new'
BUILDSTDERR:   565 |  for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); )
BUILDSTDERR:       |                                                     ^~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:567:29: note: in expansion of macro 'dns_rr_foreach_'
BUILDSTDERR:   567 | #define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__)
BUILDSTDERR:       |                             ^~~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:1682:5: note: in expansion of macro 'dns_rr_foreach'
BUILDSTDERR:  1682 |     dns_rr_foreach(&mr, M, .type = rr.type, .section = DNS_S_ALL) {
BUILDSTDERR:       |     ^~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c: In function 'dns_p_dump':
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:527:16: error: lvalue required as unary '&' operand
BUILDSTDERR:   527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))
BUILDSTDERR:       |                ^
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:1895:17: note: in expansion of macro 'dns_rr_i_new'
BUILDSTDERR:  1895 |  dns_p_dump3(P, dns_rr_i_new(P, .section = 0), fp);
BUILDSTDERR:       |                 ^~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c: In function 'dns_m_study':
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:527:16: error: lvalue required as unary '&' operand
BUILDSTDERR:   527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))
BUILDSTDERR:       |                ^
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:565:53: note: in expansion of macro 'dns_rr_i_new'
BUILDSTDERR:   565 |  for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); )
BUILDSTDERR:       |                                                     ^~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:567:29: note: in expansion of macro 'dns_rr_foreach_'
BUILDSTDERR:   567 | #define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__)
BUILDSTDERR:       |                             ^~~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:1942:2: note: in expansion of macro 'dns_rr_foreach'
BUILDSTDERR:  1942 |  dns_rr_foreach(&rr, P, .type = DNS_T_OPT, .section = DNS_S_AR) {
BUILDSTDERR:       |  ^~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c: In function 'dns_rr_exists':
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:527:16: error: lvalue required as unary '&' operand
BUILDSTDERR:   527 |  dns_rr_i_init(&dns_quietinit((struct dns_rr_i){ 0, __VA_ARGS__ }), (P))
BUILDSTDERR:       |                ^
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:565:53: note: in expansion of macro 'dns_rr_i_new'
BUILDSTDERR:   565 |  for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); )
BUILDSTDERR:       |                                                     ^~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.h:567:29: note: in expansion of macro 'dns_rr_foreach_'
BUILDSTDERR:   567 | #define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__)
BUILDSTDERR:       |                             ^~~~~~~~~~~~~~~
BUILDSTDERR: /builddir/build/BUILD/cqueues-20171014/src/lib/dns.c:2702:2: note: in expansion of macro 'dns_rr_foreach'
BUILDSTDERR:  2702 |  dns_rr_foreach(&rr1, P1, .section = rr0->section, .type = rr0->type) {
BUILDSTDERR:       |  ^~~~~~~~~~~~~~

This is going to break the package in Fedora 30 which is moving to GCC 9 right now: https://fedoraproject.org/wiki/Changes/GCC9

daurnimator commented 5 years ago

This looks like a bug with GCC. Could you report it there?

daurnimator commented 5 years ago

Minimal reproduction: https://godbolt.org/z/LIfUzV

/*
 * C O M P I L E R  A N N O T A T I O N S
 *
 * GCC with -Wextra, and clang by default, complain about overrides in
 * initializer lists. Overriding previous member initializers is well
 * defined behavior in C. We rely on this behavior to define default,
 * overrideable member values when instantiating configuration objects.
 *
 * quietinit() guards a compound literal expression with pragmas to
 * silence these shrill warnings. This alleviates the burden of requiring
 * third-party projects to adjust their compiler flags.
 *
 * NOTE: If you take the address of the compound literal, take the address
 * of the transformed expression, otherwise the compound literal lifetime is
 * tied to the scope of the GCC statement expression.
 *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#if defined __clang__
#define PRAGMA_PUSH _Pragma("clang diagnostic push")
#define PRAGMA_QUIET _Pragma("clang diagnostic ignored \"-Winitializer-overrides\"")
#define PRAGMA_POP _Pragma("clang diagnostic pop")

#define quietinit(...) \
    PRAGMA_PUSH PRAGMA_QUIET __VA_ARGS__ PRAGMA_POP
#elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4
#define PRAGMA_PUSH _Pragma("GCC diagnostic push")
#define PRAGMA_QUIET _Pragma("GCC diagnostic ignored \"-Woverride-init\"")
#define PRAGMA_POP _Pragma("GCC diagnostic pop")

/* GCC parses the _Pragma operator less elegantly than clang. */
#define quietinit(...) \
    __extension__ ({ PRAGMA_PUSH PRAGMA_QUIET __VA_ARGS__; PRAGMA_POP })
#else
#define PRAGMA_PUSH
#define PRAGMA_QUIET
#define PRAGMA_POP
#define quietinit(...) __VA_ARGS__
#endif

struct bar {
    int a;
};

int main() {
    void *x = &quietinit((struct bar){ 0, .a = 0 });
}
<source>: In function 'main':
<source>:46:15: error: lvalue required as unary '&' operand
   46 |     void *x = &quietinit((struct bar){ 0, .a = 0 });
      |               ^
Compiler returned: 1
vcunat commented 5 years ago

@daurnimator: at a quick look, this seems intentional. It's not about overriding the parameters at all. The quiteinit() macro starts a block scope, and you're trying to take address outside of it. See the the first C language issue for details.

daurnimator commented 5 years ago

If this is an intentional change by GCC, what should the code be instead so that -Woverride-init can be ignored for a specific initializer?

vcunat commented 5 years ago

I can't see such a nice way ATM. Anyway, I think this issue would better be discussed with gcc devs, for a number of reasons.

daurnimator commented 5 years ago

https://gcc.gnu.org/ml/gcc/2019-02/msg00042.html

pspacek commented 5 years ago

https://gcc.gnu.org/ml/gcc/2019-02/msg00043.html :-)

daurnimator commented 5 years ago

@wahern please drop in here :)

nicki-krizek commented 5 years ago

This patch makes it possible to compile with GCC 9 on Fedora, altough it might cause some issues with clang

vcunat commented 5 years ago

Note: GCC 9 was released today, so the problem should soon start affecting more people.