On Thu, Nov 09, 2017 at 04:02:53PM -0500, Wei Wei wrote: > Hi all, > > I get a compile time error after setting -Og when compiling for the latest > GitHub version. > I am using `make defconfig’ to get the default x86_64 config. But previously > I did this in v4.4, > it's fine.
; cat >a.c <<'EOF' extern void __attribute((error("1"))) f1(void); extern void __attribute((error("2"))) f2(void); static inline __attribute__((always_inline)) void bar(const void *addr) { int sz = __builtin_object_size(addr, 0); if (__builtin_expect(sz >= 0, 0)) f1(); if (sz >= 0) f2(); } void foo(int *in) { bar(in); } EOF ; gcc -O2 -c a.c ; gcc -Og -c a.c In function ‘bar’, inlined from ‘foo’ at a.c:15:2: a.c:8:3: error: call to ‘f1’ declared with attribute error: 1 f1(); ^ ; Note that the call of f2() _was_ eliminated. Wrap the condition into __builtin_expect() and with -Og it doesn't get eliminated until too late. It's really brittle and dependent not just upon the _result_ of optimizations (get rid of __attribute((error())) in those and you'll see that with -Og it compiles into .file "a.c" .text .globl foo .type foo, @function foo: .LFB1: .cfi_startproc rep ret .cfi_endproc .LFE1: .size foo, .-foo getting rid of both calls, as it ought to); it depends upon the moment when dead code elimination happens. -Og leaves the sucker around for too long. If you replace that __builtin_object_size() with -1 (which is what it evaluates to), you'll get elimination happening early enough even with -Og; ditto for getting rid of inlining...