On 3/21/23 15:19, Daniel P. Berrangé wrote: > On Tue, Mar 21, 2023 at 03:13:02PM +0100, Michal Prívozník wrote: >> On 3/21/23 11:46, Daniel P. Berrangé wrote: >>> On Mon, Mar 20, 2023 at 03:17:24PM +0100, Michal Prívozník wrote: >>>> On 3/16/23 15:51, Andrea Bolognani wrote: >>>>> On Wed, Mar 15, 2023 at 08:10:26PM +0100, Michal Privoznik wrote: >>>>>> We ran into so many clang bugs recently, that I'm strongly in favor of >>>>>> making it optional and aim on gcc only. Debugging these issues burns our >>>>>> time needlessly. >>>>>> >>>>> [...] >>>>>> >>>>>> After these patches, there is still one qemuxml2argvtest case failing, >>>>>> and it's simply because no matter how hard I try, I can't stop clang >>>>>> from optimizing the function. >>>>>> >>>>> [...] >>>>>> >>>>>> At this point, I think we can call clang broken and focus our time on >>>>>> developing libvirt. Not coming up with hacks around broken compilers. >>>>> >>>>> clang is the default compiler for FreeBSD and macOS, both of which >>>>> are officially supported platforms. Unless we are willing to change >>>>> that, ignoring clang is simply out of the question. >>>> >>>> I'm fine with doing that change. FreeBSD offers option to install gcc. >>>> And for macOS - the fact we compile there says absolutely nothing. >>>> Anybody willing to make libvirt work on macOS is more than welcome to >>>> post patches. >>> >>> clang is the system compiler for those platforms, and IMHO we should >>> be compatible with it. Just as Fedora was long unhappy with certain >>> apps trying to force use of clang, when Fedora's system compiler was >>> GCC, the opposite is reasonable for other platforms. >>> >>>>> A thought about VIR_OPTNONE. It seems to me that we'd want to apply >>>>> this to all the functions that currently are marked with G_NO_INLINE >>>>> for mocking purposes. So, wouldn't it make sense to instead have a >>>>> single VIR_MOCKABLE annotation that combines the two, and use that >>>>> everywhere? >>>>> >>>> >>>> The problem is, __attribute__((optnone)) works only when passed at >>>> function definition, while noinline can be passed at function >>>> definition. >>> >>> Is that a problem in fact ? We only need to suppress inlining when >>> the calling function is in the same compilation unit as the called >>> function. Likewise for this return value optimization. So if 'noinline' >>> annotation was in the definition, rather than the declaration, it >>> would be fine for our purposes. >>> >>> I think it would make sense to have a VIR_MOCKABLE annotation that >>> covered 'noline', 'optnone' and 'noipa' attributes (the precise set >>> varying according to what compiler we target). >>> >>> If anything this is more appealing that having it in the .h file, >>> since this annotations are not intended to influence callers from >>> external compilation units. >>> >>> We would need to update our test program that validates the >>> existance of noinline for mocked functions to look in the .c >>> instead of .h >> >> The problem we're facing is not that functions we mock are optimized, >> but their callers are optimized in such way that our mocking is >> ineffective. IOW: >> >> int mockThisFunction() { >> ... >> } >> >> int someRegularNotMockedFunction() { >> ... >> mockThisFunction(); >> ... >> } >> >> we would need to annotate someRegularNotMockedFunction() and leave >> mockThisFunction() be. This will get hairy pretty soon. >> >> And just for the record: the correct set of attributes that work for me >> are: optnone and used. > > Hmm, i tried adding optnone to both, and it didn't work for me. D'oh. Spoke too early. What I did also was rewrite virNumaGetNodeOfCPU() as follows: int VIR_MOCKABLE virNumaGetNodeOfCPU(int cpu) { errno = ENOSYS; if (cpu < 0) return -1; return -1; } (just don't make that a ternary operator, as it stops working) Where VIR_MOCKABLE is: #if defined(__clang__) # define VIR_OPTNONE __attribute__((optnone)) #else # define VIR_OPTNONE #endif #if defined(__clang__) # define VIR_NOIPA #else # define VIR_NOIPA __attribute__((noipa)) #endif #define VIR_MOCKABLE VIR_OPTNONE VIR_NOIPA __attribute__((noinline)) __attribute__((used)) BUT, I also had to annotate virNumaCPUSetToNodeset() which is NOT mocked. And this is the most annoying thing about whole approach. Since we already have a fix and now are fighting two failed CI builds, I wonder whether it makes sense to just forcibly disable all optimizations IF the compiler is clang and it doesn't have -fsemantic-interposition option. Michal