Skip to content

Commit

Permalink
build: Fix struct align/pack for MSVC (#1754)
Browse files Browse the repository at this point in the history
Signed-off-by: Rasmus Bonnedal <[email protected]>
  • Loading branch information
rasmusbonnedal authored Nov 20, 2023
1 parent bc86477 commit da8f2be
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/include/OSL/fmt_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,29 @@ namespace pvt {
// PackedArgs is similar to tuple but packs its data back to back
// in memory layout, which is what we need to build up payload
// to the fmt reporting system
template<int IndexT, typename TypeT> struct PackedArg {
OSL_PACK_STRUCTS_BEGIN
template<int IndexT, typename TypeT> struct alignas(1) PackedArg {
explicit PackedArg(const TypeT& a_value) : m_value(a_value) {}
TypeT m_value;
} __attribute__((packed, aligned(1)));
};
OSL_PACK_STRUCTS_END

template<typename IntSequenceT, typename... TypeListT> struct PackedArgsBase;
// Specialize to extract a parameter pack of the IntegerSquence
// so it can be expanded alongside the TypeListT parameter pack
OSL_PACK_STRUCTS_BEGIN
template<int... IntegerListT, typename... TypeListT>
struct PackedArgsBase<std::integer_sequence<int, IntegerListT...>, TypeListT...>
struct alignas(1)
PackedArgsBase<std::integer_sequence<int, IntegerListT...>, TypeListT...>
: public PackedArg<IntegerListT, TypeListT>... {
explicit PackedArgsBase(const TypeListT&... a_values)
// multiple inheritance of individual components
// uniquely identified by the <Integer,Type> combo
: PackedArg<IntegerListT, TypeListT>(a_values)...
{
}
} __attribute__((packed, aligned(1)));
};
OSL_PACK_STRUCTS_END

template<typename... TypeListT> struct PackedArgs {
typedef std::make_integer_sequence<int, sizeof...(TypeListT)>
Expand All @@ -50,6 +55,13 @@ template<typename... TypeListT> struct PackedArgs {
{
}
};

static_assert(sizeof(PackedArgs<int, char, int>)
== sizeof(int) + sizeof(char) + sizeof(int),
"PackedArgs<> type is not packed");
static_assert(alignof(PackedArgs<int, char, int>) == 1,
"PackedArgs<> type is not aligned to 1");

} // namespace pvt


Expand Down
12 changes: 12 additions & 0 deletions src/include/OSL/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,18 @@ template<> OSL_FORCEINLINE double bitcast<double, int64_t>(const int64_t& val) n
#endif


/// OSL_PACK_STRUCTS_* is used to pack a struct or class tightly. Use it like
/// the following example. To set the alignment of the struct use the
/// alignas(x) directive.
///
/// OSL_PACK_STRUCTS_BEGIN
/// struct alignas(1) Foo {
/// char x, y, z;
/// };
/// OSL_PACK_STRUCTS_END
#define OSL_PACK_STRUCTS_BEGIN OSL_PRAGMA(pack(push, 1))
#define OSL_PACK_STRUCTS_END OSL_PRAGMA(pack(pop))


#if OSL_CPLUSPLUS_VERSION >= 20
using std::assume_aligned;
Expand Down

0 comments on commit da8f2be

Please sign in to comment.