Comment 56 for bug 1847361

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Simplified the breaking call a bit and got:
gcc -Iblock -I. -I/build/qemu-D0lqny/qemu-2.11+dfsg -I/build/qemu-D0lqny/qemu-2.11+dfsg/include -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -D_GNU_SOURCE -Wall -Wundef -o file-posix.o ../block/file-posix.c

From there I got down to:
test.c:
#define BITS_PER_LONG (sizeof (unsigned long))
#include <linux/cdrom.h>
int main() {
   return BITS_PER_LONG;
}

$ gcc -Wall -Wundef -o test.o test.c
/usr/include/linux/swab.h: In function ‘__swab’:
test.c:1:34: warning: "sizeof" is not defined, evaluates to 0 [-Wundef]
 #define BITS_PER_LONG (sizeof (unsigned long))
                                  ^
test.c:1:41: error: missing binary operator before token "("
 #define BITS_PER_LONG (sizeof (unsigned long))
                                         ^

Root cause is the missing sizeof which makes BITS_PER_LONG and odd define.
With that defined including linux/cdrom.h breaks.
Dropping the cdrom include avoids it, as much as not defining BITS_PER_LONG (defining it to any reasonable number works are well).

A build with -E shows that BITS_PER_LONG becomes the actual text as it replaces the one in the return to this:
   return (sizeof (unsigned long));

That understanding lets me further simplify the test:
#define FOO (sizeof (unsigned long))
int main() {
#if FOO == 8
   return FOO;
#endif
}

$ gcc -Wall -Wundef -o test.o test.c
test.c: In function ‘main’:
test.c:1:24: warning: "sizeof" is not defined, evaluates to 0 [-Wundef]
 #define FOO (sizeof (unsigned long))
                        ^
test.c:4:5: note: in expansion of macro ‘FOO’
 #if FOO == 8
     ^~~
test.c:1:31: error: missing binary operator before token "("
 #define FOO (sizeof (unsigned long))
                               ^
test.c:4:5: note: in expansion of macro ‘FOO’
 #if FOO == 8
     ^~~

But that has no external dependencies anymore other than the compiler.
Why/where is sizeof missing.

To be clear, this works and returns 8
int main() {
   return (sizeof (unsigned long));

It is only the usage in the definition of the preprocessor var that fails.

But this fails since forever from Xenial to Focal, I must still miss some other change that actually makes this happen (or was mitigating it in the past).