]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
util: Add macro to overflow check integer assignments
authorPeter Krempa <pkrempa@redhat.com>
Wed, 27 May 2015 08:54:38 +0000 (10:54 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 3 Jun 2015 07:42:08 +0000 (09:42 +0200)
Add a macro that will allow to simplify overflow checks and make them
more universal in case data types change.

src/util/virutil.h
tests/utiltest.c

index c78b357b4367d61a5d52e3c6d7188489906d6f00..53025f7086ff21388ffc8962ea9fb7897a115f12 100644 (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__ */
index dfa4290caf385a60409bfbad89c9d503246a04e6..3a1f8ebbe9b259f7a9096740f3f8d7ba41abef1e 100644 (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;
 }