Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build fails with GCC 9 #212

Closed
pspacek opened this issue Feb 6, 2019 · 10 comments · Fixed by #224
Closed

Build fails with GCC 9 #212

pspacek opened this issue Feb 6, 2019 · 10 comments · Fixed by #224

Comments

@pspacek
Copy link

pspacek commented Feb 6, 2019

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
Copy link
Collaborator

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

@daurnimator
Copy link
Collaborator

daurnimator commented Feb 8, 2019

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
Copy link
Contributor

vcunat commented Feb 8, 2019

@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
Copy link
Collaborator

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
Copy link
Contributor

vcunat commented Feb 8, 2019

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
Copy link
Collaborator

@pspacek
Copy link
Author

pspacek commented Feb 12, 2019

@daurnimator
Copy link
Collaborator

@wahern please drop in here :)

@nicki-krizek
Copy link

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

@vcunat
Copy link
Contributor

vcunat commented May 3, 2019

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants