On 11/23/21 16:37, Eric Blake wrote:
On Tue, Nov 23, 2021 at 03:25:22PM +0000, Richard W.M. Jones wrote:
> On Tue, Nov 23, 2021 at 11:44:06AM +0100, Laszlo Ersek wrote:
>> On 11/22/21 23:31, Richard W.M. Jones wrote:
>>> My only other thought is that a simple set of tests could be good.
>>> However it's not worth having tests that only test if __builtin*
>>> functions are correct (hopefully GCC is already testing that). So
>>> tests would have to check the fallback macros are correct, even if
>>> they are not used on the current platform.
>>
>> So: the fallbacks need to be available (= built) in the source code
>> unconditionally, so they can be directly called by the test suite. The
>> actual "falling back" to them must be separate. Is that what you mean?
>
> I just meant that if we have a test suite which tests the end result
> (macros like "ADD_OVERFLOW"), because we will only do CI on modern
> systems, it will only ever test that __builtin_add_overflow works.
> That's pointless because presumably GCC already tests that, and the
> fallback code would never be tested. So the tests would need to
> somehow check that the fallback path works.
Something along the lines of:
#if (...gcc or clang new enough...) && !defined(NBDKIT_FALLBACK)
# define ADD_OVERFLOW(a, b, r) __builtin_add_overflow((a), (b), (r))
#else
# define ADD_OVERFLOW(a, b, r) ...fallback...
#endif
so that the testsuite can then #define NBDKIT_FALLBACK for testing the
fallback code even on new enough compilers. I'm not sure how best to
namespace the witness macro for forcing a fallback if the code is
copied between nbdkit and libnbd.
What I have in mind now is (also incorporating feedback from Rich):
- add the functions under "common/utils/checked-overflow.c"
unconditionally, add their declarations unconditionally in
"common/include/checked-overflow.h"
- there should be two sets of macros. Both sets should always perform
the typeof / unsigned check, so that the call sites conform to that even
if the actual fallback is not used. This is so that we not litter the
source code with a bunch of signed arguments, which then blow up in the
typeof static asserts once the codebase is compiled on FreeBSD or RHEL7
(even before calling the actual functions). The first set should then
call the builtins, the second set should call the functions.
- the central macros should be thin wrappers around the above sets of
macros (dependent on the builtins' presence)
- normal code can call the central macros
- the test case should call the one set of lower-level macros that uses
the functions.
I really hope to start working on a patch soon...
Thanks
Laszlo