diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp index c08663bface2..e80512b92a01 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()); } } @@ -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() * 2); data_pair fst = bump_dp(dp); data_pair snd = bump_dp(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()); cmp_number(bump_dp(dp)); } diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h index e568d4801642..789d54c71fa9 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 +inline size_t +alignof() { +#ifdef _MSC_VER + return __alignof(T); +#else + return __alignof__(T); +#endif +} + +template<> +inline size_t +alignof() { + return 4; +} + + // Utility classes struct size_align { @@ -546,7 +564,7 @@ public: } template - void walk_number(bool align) { sa.set(sizeof(T), ALIGNOF(T)); } + void walk_number(bool align) { sa.set(sizeof(T), alignof()); } 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()); \ U end_dp = dp + sizeof(ty); \ static_cast(this)->call; \ dp = end_dp; @@ -847,7 +865,7 @@ data::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()); U end_dp = dp + tinfo.tag_sa.size;