Add cast to ((align) - 1) for Alignment macros (mono/mono#18255)
authorFan Yang <52458914+fanyang-mono@users.noreply.github.com>
Mon, 23 Dec 2019 13:34:37 +0000 (08:34 -0500)
committerAleksey Kliger (λgeek) <alklig@microsoft.com>
Mon, 23 Dec 2019 13:34:37 +0000 (08:34 -0500)
* Add cast to ((align) - 1) for Alignment macros

* Add test for Alignment macro change

Commit migrated from https://github.com/mono/mono/commit/7ffcaaf59a9826a68233fa9671548c2ca492806a

src/mono/mono/eglib/glib.h
src/mono/mono/eglib/test/memory.c

index 29bb96b..c8798cc 100644 (file)
@@ -247,11 +247,11 @@ typedef guint32 gunichar;
 #define ABS(a)         ((a) > 0 ? (a) : -(a))
 #endif
 
-#define ALIGN_TO(val,align) ((((gssize)val) + ((align) - 1)) & ~((align) - 1))
+#define ALIGN_TO(val,align) ((((gssize)val) + (gssize)((align) - 1)) & (~((gssize)(align - 1))))
 
-#define ALIGN_DOWN_TO(val,align) (((gssize)val) & ~((align) - 1))
+#define ALIGN_DOWN_TO(val,align) (((gssize)val) & (~((gssize)(align - 1))))
 
-#define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
+#define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (gssize)(align - 1)) & (~((gssize)(align - 1))))
 
 #define G_STRUCT_OFFSET(p_type,field) offsetof(p_type,field)
 
index 3fed8ce..6083d90 100644 (file)
@@ -30,8 +30,112 @@ test_memory_zero_size_allocations (void)
         return OK;
 }
 
+/*
+ * Test the following macros with alignment value as signed int
+ *     <> ALIGN_TO
+ *     <> ALIGN_DOWN_TO
+ *     <> ALIGN_PTR_TO
+ */
+static RESULT
+test_align_signed_int (void)
+{
+       gssize orig_value = 67;
+       gssize result, exp_value;
+       gpointer orig_ptr = (gpointer)orig_value;
+       gpointer result_ptr, exp_ptr;
+
+       // test case #1
+       int align = 1;
+       result = ALIGN_TO (orig_value, align);
+       exp_value = orig_value;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       result = ALIGN_DOWN_TO (orig_value, align);
+       exp_value = orig_value;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       result_ptr = ALIGN_PTR_TO (orig_ptr,align);
+       exp_ptr = orig_ptr;
+       if (result_ptr != exp_ptr)
+                return FAILED ("Expected address after aligned is %p, however, the actual address is %p", exp_ptr, result_ptr);
+
+       // test case #2
+       align = 8;
+       result = ALIGN_TO (orig_value, align);
+       exp_value = 72;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       result_ptr = ALIGN_PTR_TO (orig_ptr,align);
+       exp_ptr= (gpointer)exp_value;
+       if (result_ptr != exp_ptr)
+                return FAILED ("Expected address after aligned is %p, however, the actual address is %p", exp_ptr, result_ptr);
+
+       result = ALIGN_DOWN_TO (orig_value, align);
+       exp_value = 64;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       return OK;
+}
+
+/*                                                                                                                                                                                                                                                         
+ * Test the following macros with alignment value as unsigned int                                                                                                                                                                                          
+ *     <> ALIGN_TO                                                                                                                                                                                                                                         
+ *     <> ALIGN_DOWN_TO                                                                                                                                                                                                                                     
+ *     <> ALIGN_PTR_TO                                                                                                                                                                                                                                      
+ */
+static RESULT
+test_align_unsigned_int (void)
+{
+       gssize orig_value = 67;
+       gssize result, exp_value;
+       gpointer orig_ptr = (gpointer)orig_value;
+       gpointer result_ptr, exp_ptr;
+
+       // test case #1
+       unsigned int align = 1;
+       result = ALIGN_TO (orig_value, align);
+       exp_value = orig_value;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       result = ALIGN_DOWN_TO (orig_value, align);
+       exp_value = orig_value;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+       
+       result_ptr = ALIGN_PTR_TO (orig_ptr,align);
+       exp_ptr = orig_ptr;
+       if (result_ptr != exp_ptr)
+                return FAILED ("Expected address after aligned is %p, however, the actual address is %p", exp_ptr, result_ptr);
+       
+       // test case #2
+       align= 16;
+       result = ALIGN_TO (orig_value, align);
+       exp_value = 80;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       result_ptr = ALIGN_PTR_TO (orig_ptr,align);
+       exp_ptr= (gpointer)exp_value;
+       if (result_ptr != exp_ptr)
+                return FAILED ("Expected address after aligned is %p, however, the actual address is %p", exp_ptr, result_ptr);
+
+       result = ALIGN_DOWN_TO (orig_value, align);
+       exp_value = 64;
+       if (result != exp_value)
+                return FAILED ("Expected value after aligned is %d, however, the actual value is %d", exp_value, result);
+
+       return OK;
+}
+
 static Test memory_tests [] = {
-        {       "zero_size_allocations", test_memory_zero_size_allocations},
+       {"zero_size_allocations", test_memory_zero_size_allocations},
+       {"align_signed_int", test_align_signed_int},
+       {"align_unsigned_int", test_align_unsigned_int},
         {NULL, NULL}
 };