diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-30 02:22:08 +0900 |
---|---|---|
committer | Qijiang Fan <fqj@google.com> | 2020-06-04 16:47:31 +0900 |
commit | 432750437990d7ca96621125de046ee6870b2d19 (patch) | |
tree | 51f623a8f1341dfd90a148edcb26a65aebd7baa6 /mojo/public/c/system | |
parent | c11e2f761a635e987021b350c67adfa7e22b4c83 (diff) | |
download | libchrome-432750437990d7ca96621125de046ee6870b2d19.tar.gz |
Mojo: Require our public options structs to be aligned like int64_t's.
The structs are meant to be extensible and part of the ABI, and not
requiring such alignment of them would mean that it'd be difficult to
add (u)int64_t's (or anything aligned like them) to them in the future.
R=darin@chromium.org
Review URL: https://codereview.chromium.org/295383012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273508 0039d316-1c4b-4281-b951-d872f2087c98
CrOS-Libchrome-Original-Commit: 54743a5071e673a394501c3da0f3de7409cf3891
Diffstat (limited to 'mojo/public/c/system')
-rw-r--r-- | mojo/public/c/system/buffer.h | 3 | ||||
-rw-r--r-- | mojo/public/c/system/data_pipe.h | 3 | ||||
-rw-r--r-- | mojo/public/c/system/macros.h | 33 | ||||
-rw-r--r-- | mojo/public/c/system/tests/macros_unittest.cc | 29 |
4 files changed, 65 insertions, 3 deletions
diff --git a/mojo/public/c/system/buffer.h b/mojo/public/c/system/buffer.h index 360832150f..ab5734d7eb 100644 --- a/mojo/public/c/system/buffer.h +++ b/mojo/public/c/system/buffer.h @@ -38,7 +38,8 @@ const MojoCreateSharedBufferOptionsFlags ((MojoCreateSharedBufferOptionsFlags) 0) #endif -struct MojoCreateSharedBufferOptions { +MOJO_COMPILE_ASSERT(MOJO_ALIGNOF(int64_t) == 8, int64_t_has_weird_alignment); +struct MOJO_ALIGNAS(8) MojoCreateSharedBufferOptions { uint32_t struct_size; MojoCreateSharedBufferOptionsFlags flags; }; diff --git a/mojo/public/c/system/data_pipe.h b/mojo/public/c/system/data_pipe.h index 511858df76..1313448ebd 100644 --- a/mojo/public/c/system/data_pipe.h +++ b/mojo/public/c/system/data_pipe.h @@ -46,7 +46,8 @@ const MojoCreateDataPipeOptionsFlags ((MojoCreateDataPipeOptionsFlags) 1 << 0) #endif -struct MojoCreateDataPipeOptions { +MOJO_COMPILE_ASSERT(MOJO_ALIGNOF(int64_t) == 8, int64_t_has_weird_alignment); +struct MOJO_ALIGNAS(8) MojoCreateDataPipeOptions { uint32_t struct_size; MojoCreateDataPipeOptionsFlags flags; uint32_t element_num_bytes; diff --git a/mojo/public/c/system/macros.h b/mojo/public/c/system/macros.h index 322c3be61f..f1e3c7d683 100644 --- a/mojo/public/c/system/macros.h +++ b/mojo/public/c/system/macros.h @@ -26,8 +26,10 @@ #define MOJO_WARN_UNUSED_RESULT #endif +// Assert things at compile time. (|msg| should be a valid identifier name.) // This macro is currently C++-only, but we want to use it in the C core.h. -// Used to assert things at compile time. +// Use like: +// MOJO_COMPILE_ASSERT(sizeof(Foo) == 12, Foo_has_invalid_size); #if __cplusplus >= 201103L #define MOJO_COMPILE_ASSERT(expr, msg) static_assert(expr, #msg) #elif defined(__cplusplus) @@ -38,4 +40,33 @@ namespace mojo { template <bool> struct CompileAssert {}; } #define MOJO_COMPILE_ASSERT(expr, msg) #endif +// Like the C++11 |alignof| operator. +#if __cplusplus >= 201103L +#define MOJO_ALIGNOF(type) alignof(type) +#elif defined(__GNUC__) +#define MOJO_ALIGNOF(type) __alignof__(type) +#elif defined(_MSC_VER) +// The use of |sizeof| is to work around a bug in MSVC 2010 (see +// http://goo.gl/isH0C; supposedly fixed since then). +#define MOJO_ALIGNOF(type) (sizeof(type) - sizeof(type) + __alignof(type)) +#else +#error "Please define MOJO_ALIGNOF() for your compiler." +#endif + +// Specify the alignment of a |struct|, etc. +// Use like: +// struct MOJO_ALIGNAS(8) Foo { ... }; +// Unlike the C++11 |alignas()|, |alignment| must be an integer. It may not be a +// type, nor can it be an expression like |MOJO_ALIGNOF(type)| (due to the +// non-C++11 MSVS version). +#if __cplusplus >= 201103L +#define MOJO_ALIGNAS(alignment) alignas(alignment) +#elif defined(__GNUC__) +#define MOJO_ALIGNAS(alignment) __attribute__((aligned(alignment))) +#elif defined(_MSC_VER) +#define MOJO_ALIGNAS(alignment) __declspec(align(alignment)) +#else +#error "Please define MOJO_ALIGNAS() for your compiler." +#endif + #endif // MOJO_PUBLIC_C_SYSTEM_MACROS_H_ diff --git a/mojo/public/c/system/tests/macros_unittest.cc b/mojo/public/c/system/tests/macros_unittest.cc index 5225b67cdb..fdc0c87c99 100644 --- a/mojo/public/c/system/tests/macros_unittest.cc +++ b/mojo/public/c/system/tests/macros_unittest.cc @@ -44,5 +44,34 @@ TEST(MacrosTest, CompileAssert) { bad_compile_assert_failure); } +TEST(MacrosTest, Alignof) { + // Strictly speaking, this isn't a portable test, but I think it'll pass on + // all the platforms we currently support. + EXPECT_EQ(1u, MOJO_ALIGNOF(char)); + EXPECT_EQ(4u, MOJO_ALIGNOF(int32_t)); + EXPECT_EQ(8u, MOJO_ALIGNOF(int64_t)); + EXPECT_EQ(8u, MOJO_ALIGNOF(double)); +} + +// These structs are used in the Alignas test. Define them globally to avoid +// MSVS warnings/errors. +#if defined(_MSC_VER) +#pragma warning(push) +// Disable the warning "structure was padded due to __declspec(align())". +#pragma warning(disable:4324) +#endif +struct MOJO_ALIGNAS(1) StructAlignas1 { char x; }; +struct MOJO_ALIGNAS(4) StructAlignas4 { char x; }; +struct MOJO_ALIGNAS(8) StructAlignas8 { char x; }; +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +TEST(MacrosTest, Alignas) { + EXPECT_EQ(1u, MOJO_ALIGNOF(StructAlignas1)); + EXPECT_EQ(4u, MOJO_ALIGNOF(StructAlignas4)); + EXPECT_EQ(8u, MOJO_ALIGNOF(StructAlignas8)); +} + } // namespace } // namespace mojo |