diff options
author | Abseil Team <absl-team@google.com> | 2022-11-16 11:05:21 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2022-11-16 11:06:21 -0800 |
commit | 4b48854949f8bf9afb871c293a9022331a0b77c7 (patch) | |
tree | 768ae9ca20e921fbce962adce0cad17bf409eea6 /absl/synchronization/mutex_method_pointer_test.cc | |
parent | 76fa844139fb04958a9682f34e3b3d0e4943ae5f (diff) | |
download | abseil-4b48854949f8bf9afb871c293a9022331a0b77c7.tar.gz abseil-4b48854949f8bf9afb871c293a9022331a0b77c7.tar.bz2 abseil-4b48854949f8bf9afb871c293a9022331a0b77c7.zip |
Update Condition to allocate 24 bytes for MSVC platform pointers to methods.
PiperOrigin-RevId: 488986942
Change-Id: I2babb7ea30d60c544f55ca9ed02d9aed23051a12
Diffstat (limited to 'absl/synchronization/mutex_method_pointer_test.cc')
-rw-r--r-- | absl/synchronization/mutex_method_pointer_test.cc | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/absl/synchronization/mutex_method_pointer_test.cc b/absl/synchronization/mutex_method_pointer_test.cc new file mode 100644 index 00000000..1ec801a0 --- /dev/null +++ b/absl/synchronization/mutex_method_pointer_test.cc @@ -0,0 +1,138 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "absl/synchronization/mutex.h" + +#include <cstdlib> +#include <string> + +#include "gtest/gtest.h" +#include "absl/base/config.h" + +namespace { + +class IncompleteClass; + +#ifdef _MSC_VER +// These tests verify expectations about sizes of MSVC pointers to methods. +// Pointers to methods are distinguished by whether their class hierachies +// contain single inheritance, multiple inheritance, or virtual inheritence. + +// Declare classes of the various MSVC inheritance types. +class __single_inheritance SingleInheritance{}; +class __multiple_inheritance MultipleInheritance; +class __virtual_inheritance VirtualInheritance; + +TEST(MutexMethodPointerTest, MicrosoftMethodPointerSize) { + void (SingleInheritance::*single_inheritance_method_pointer)(); + void (MultipleInheritance::*multiple_inheritance_method_pointer)(); + void (VirtualInheritance::*virtual_inheritance_method_pointer)(); + +#if defined(_M_IX86) || defined(_M_ARM) + static_assert(sizeof(single_inheritance_method_pointer) == 4, + "Unexpected sizeof(single_inheritance_method_pointer)."); + static_assert(sizeof(multiple_inheritance_method_pointer) == 8, + "Unexpected sizeof(multiple_inheritance_method_pointer)."); + static_assert(sizeof(virtual_inheritance_method_pointer) == 12, + "Unexpected sizeof(virtual_inheritance_method_pointer)."); +#elif defined(_M_X64) || defined(__aarch64__) + static_assert(sizeof(single_inheritance_method_pointer) == 8, + "Unexpected sizeof(single_inheritance_method_pointer)."); + static_assert(sizeof(multiple_inheritance_method_pointer) == 16, + "Unexpected sizeof(multiple_inheritance_method_pointer)."); + static_assert(sizeof(virtual_inheritance_method_pointer) == 16, + "Unexpected sizeof(virtual_inheritance_method_pointer)."); +#endif + void (IncompleteClass::*incomplete_class_method_pointer)(); + static_assert(sizeof(incomplete_class_method_pointer) >= + sizeof(virtual_inheritance_method_pointer), + "Failed invariant: sizeof(incomplete_class_method_pointer) >= " + "sizeof(virtual_inheritance_method_pointer)!"); +} + +class Callback { + bool x = true; + + public: + Callback() {} + bool method() { + x = !x; + return x; + } +}; + +class M2 { + bool x = true; + + public: + M2() {} + bool method2() { + x = !x; + return x; + } +}; + +class MultipleInheritance : public Callback, public M2 {}; + +TEST(MutexMethodPointerTest, ConditionWithMultipleInheritanceMethod) { + // This test ensures that Condition can deal with method pointers from classes + // with multiple inheritance. + MultipleInheritance object = MultipleInheritance(); + absl::Condition condition(&object, &MultipleInheritance::method); + EXPECT_FALSE(condition.Eval()); + EXPECT_TRUE(condition.Eval()); +} + +class __virtual_inheritance VirtualInheritance : virtual public Callback { + bool x = false; + + public: + VirtualInheritance() {} + bool method() { + x = !x; + return x; + } +}; + +TEST(MutexMethodPointerTest, ConditionWithVirtualInheritanceMethod) { + // This test ensures that Condition can deal with method pointers from classes + // with virtual inheritance. + VirtualInheritance object = VirtualInheritance(); + absl::Condition condition(&object, &VirtualInheritance::method); + EXPECT_TRUE(condition.Eval()); + EXPECT_FALSE(condition.Eval()); +} +#endif // #ifdef _MSC_VER + +TEST(MutexMethodPointerTest, ConditionWithIncompleteClassMethod) { + using IncompleteClassMethodPointer = void (IncompleteClass::*)(); + + union CallbackSlot { + void (*anonymous_function_pointer)(); + IncompleteClassMethodPointer incomplete_class_method_pointer; + }; + + static_assert(sizeof(CallbackSlot) >= sizeof(IncompleteClassMethodPointer), + "The callback slot is not big enough for method pointers."); + static_assert( + sizeof(CallbackSlot) == sizeof(IncompleteClassMethodPointer), + "The callback slot is not big enough for anonymous function pointers."); + +#if defined(_MSC_VER) + static_assert(sizeof(IncompleteClassMethodPointer) <= 24, + "The pointer to a method of an incomplete class is too big."); +#endif +} + +} // namespace |