[libvirt] [PATCH 11/35] util: Add macro to overflow check integer assignments

Peter Krempa pkrempa at redhat.com
Fri May 29 13:33:32 UTC 2015


Add a macro that will allow to simplify overflow checks and make them
more universal in case data types change.
---
 src/util/virutil.h | 11 +++++++++++
 tests/utiltest.c   | 30 ++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/src/util/virutil.h b/src/util/virutil.h
index c78b357..53025f7 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -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__ */
diff --git a/tests/utiltest.c b/tests/utiltest.c
index dfa4290..3a1f8eb 100644
--- a/tests/utiltest.c
+++ b/tests/utiltest.c
@@ -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;
 }
-- 
2.4.1




More information about the libvir-list mailing list