util: Add macro to overflow check integer assignments

Add a macro that will allow to simplify overflow checks and make them
more universal in case data types change.
This commit is contained in:
Peter Krempa 2015-05-27 10:54:38 +02:00
parent f35b9b7898
commit 65c61e5030
2 changed files with 41 additions and 0 deletions

View File

@ -247,4 +247,15 @@ unsigned long long virMemoryLimitTruncate(unsigned long long value);
bool virMemoryLimitIsSet(unsigned long long value);
unsigned long long virMemoryMaxValue(bool ulong);
/**
* VIR_ASSIGN_IS_OVERFLOW:
* @rvalue: value that is checked (evaluated twice)
* @lvalue: value that the check is against (used in typeof())
*
* This macro assigns @lvalue to @rvalue and evaluates as true if the value of
* @rvalue did not fit into the @lvalue.
*/
# define VIR_ASSIGN_IS_OVERFLOW(lvalue, rvalue) \
(((lvalue) = (rvalue)) != (rvalue))
#endif /* __VIR_UTIL_H__ */

View File

@ -172,6 +172,35 @@ testRoundValueToPowerOfTwo(const void *data ATTRIBUTE_UNUSED)
}
#define TEST_OVERFLOW(var, val, expect) \
tmp = val; \
if (VIR_ASSIGN_IS_OVERFLOW(var, tmp) != expect) { \
fprintf(stderr, "\noverflow check failed: " \
"var: " #var " val: " #val "\n"); \
return -1; \
}
static int
testOverflowCheckMacro(const void *data ATTRIBUTE_UNUSED)
{
long long tmp;
unsigned char luchar;
char lchar;
TEST_OVERFLOW(luchar, 254, false);
TEST_OVERFLOW(luchar, 255, false);
TEST_OVERFLOW(luchar, 256, true);
TEST_OVERFLOW(luchar, 767, true);
TEST_OVERFLOW(lchar, 127, false);
TEST_OVERFLOW(lchar, -128, false);
TEST_OVERFLOW(lchar, -129, true);
TEST_OVERFLOW(lchar, 128, true);
return 0;
}
static int
@ -193,6 +222,7 @@ mymain(void)
DO_TEST(DiskNameToIndex);
DO_TEST(ParseVersionString);
DO_TEST(RoundValueToPowerOfTwo);
DO_TEST(OverflowCheckMacro);
return result == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}