about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/rt/rust_shape.cpp6
-rw-r--r--src/rt/rust_shape.h36
2 files changed, 30 insertions, 12 deletions
diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp
index c08663bface..e80512b92a0 100644
--- a/src/rt/rust_shape.cpp
+++ b/src/rt/rust_shape.cpp
@@ -199,7 +199,7 @@ size_of::compute_tag_size(tag_info &tinfo) {
             tinfo.tag_sa.set(1, 1);
     } else {
         // Add in space for the tag.
-        tinfo.tag_sa.add(sizeof(uint32_t), ALIGNOF(uint32_t));
+        tinfo.tag_sa.add(sizeof(uint32_t), alignof<uint32_t>());
     }
 }
 
@@ -259,7 +259,7 @@ private:
     }
 
     inline void cmp_two_pointers(bool align) {
-        if (align) dp = align_to(dp, ALIGNOF(uint8_t *) * 2);
+        if (align) dp = align_to(dp, alignof<uint8_t *>() * 2);
         data_pair<uint8_t *> fst = bump_dp<uint8_t *>(dp);
         data_pair<uint8_t *> snd = bump_dp<uint8_t *>(dp);
         cmp_number(fst);
@@ -268,7 +268,7 @@ private:
     }
 
     inline void cmp_pointer(bool align) {
-        if (align) dp = align_to(dp, ALIGNOF(uint8_t *));
+        if (align) dp = align_to(dp, alignof<uint8_t *>());
         cmp_number(bump_dp<uint8_t *>(dp));
     }
 
diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h
index e568d480164..789d54c71fa 100644
--- a/src/rt/rust_shape.h
+++ b/src/rt/rust_shape.h
@@ -6,12 +6,6 @@
 
 #include "rust_internal.h"
 
-#ifdef _MSC_VER
-#define ALIGNOF     __alignof
-#else
-#define ALIGNOF     __alignof__
-#endif
-
 #define ARENA_SIZE          256
 
 #define DPRINT(fmt,...)     fprintf(stderr, fmt, ##__VA_ARGS__)
@@ -86,6 +80,30 @@ public:
 };
 
 
+// Alignment inquiries
+//
+// We can't directly use __alignof__ everywhere because that returns the
+// preferred alignment of the type, which is different from the ABI-mandated
+// alignment of the type in some cases (e.g. doubles on x86). The latter is
+// what actually gets used for struct elements.
+
+template<typename T>
+inline size_t
+alignof() {
+#ifdef _MSC_VER
+    return __alignof(T);
+#else
+    return __alignof__(T);
+#endif
+}
+
+template<>
+inline size_t
+alignof<double>() {
+    return 4;
+}
+
+
 // Utility classes
 
 struct size_align {
@@ -546,7 +564,7 @@ public:
     }
 
     template<typename T>
-    void walk_number(bool align) { sa.set(sizeof(T), ALIGNOF(T)); }
+    void walk_number(bool align) { sa.set(sizeof(T), alignof<T>()); }
 
     void compute_tag_size(tag_info &tinfo);
 
@@ -709,7 +727,7 @@ namespace shape {
 // for methods that actually manipulate the data involved.
 
 #define DATA_SIMPLE(ty, call) \
-    if (align) dp = align_to(dp, sizeof(ty)); \
+    if (align) dp = align_to(dp, alignof<ty>()); \
     U end_dp = dp + sizeof(ty); \
     static_cast<T *>(this)->call; \
     dp = end_dp;
@@ -847,7 +865,7 @@ data<T,U>::walk_tag(bool align, tag_info &tinfo) {
     size_of::compute_tag_size(*this, tinfo);
 
     if (tinfo.variant_count > 1 && align)
-        dp = align_to(dp, ALIGNOF(uint32_t));
+        dp = align_to(dp, alignof<uint32_t>());
 
     U end_dp = dp + tinfo.tag_sa.size;