tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mutex_method_pointer_test.cc (4762B)


      1 // Copyright 2017 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #include "absl/synchronization/mutex.h"
     16 
     17 #include <cstdlib>
     18 #include <string>
     19 
     20 #include "gtest/gtest.h"
     21 #include "absl/base/config.h"
     22 
     23 namespace {
     24 
     25 class IncompleteClass;
     26 
     27 #ifdef _MSC_VER
     28 // These tests verify expectations about sizes of MSVC pointers to methods.
     29 // Pointers to methods are distinguished by whether their class hierarchies
     30 // contain single inheritance, multiple inheritance, or virtual inheritance.
     31 
     32 // Declare classes of the various MSVC inheritance types.
     33 class __single_inheritance SingleInheritance{};
     34 class __multiple_inheritance MultipleInheritance;
     35 class __virtual_inheritance VirtualInheritance;
     36 
     37 TEST(MutexMethodPointerTest, MicrosoftMethodPointerSize) {
     38  void (SingleInheritance::*single_inheritance_method_pointer)();
     39  void (MultipleInheritance::*multiple_inheritance_method_pointer)();
     40  void (VirtualInheritance::*virtual_inheritance_method_pointer)();
     41 
     42 #if defined(_M_IX86) || defined(_M_ARM)
     43  static_assert(sizeof(single_inheritance_method_pointer) == 4,
     44                "Unexpected sizeof(single_inheritance_method_pointer).");
     45  static_assert(sizeof(multiple_inheritance_method_pointer) == 8,
     46                "Unexpected sizeof(multiple_inheritance_method_pointer).");
     47  static_assert(sizeof(virtual_inheritance_method_pointer) == 12,
     48                "Unexpected sizeof(virtual_inheritance_method_pointer).");
     49 #elif defined(_M_X64) || defined(__aarch64__)
     50  static_assert(sizeof(single_inheritance_method_pointer) == 8,
     51                "Unexpected sizeof(single_inheritance_method_pointer).");
     52  static_assert(sizeof(multiple_inheritance_method_pointer) == 16,
     53                "Unexpected sizeof(multiple_inheritance_method_pointer).");
     54  static_assert(sizeof(virtual_inheritance_method_pointer) == 16,
     55                "Unexpected sizeof(virtual_inheritance_method_pointer).");
     56 #endif
     57  void (IncompleteClass::*incomplete_class_method_pointer)();
     58  static_assert(sizeof(incomplete_class_method_pointer) >=
     59                    sizeof(virtual_inheritance_method_pointer),
     60                "Failed invariant: sizeof(incomplete_class_method_pointer) >= "
     61                "sizeof(virtual_inheritance_method_pointer)!");
     62 }
     63 
     64 class Callback {
     65  bool x = true;
     66 
     67 public:
     68  Callback() {}
     69  bool method() {
     70    x = !x;
     71    return x;
     72  }
     73 };
     74 
     75 class M2 {
     76  bool x = true;
     77 
     78 public:
     79  M2() {}
     80  bool method2() {
     81    x = !x;
     82    return x;
     83  }
     84 };
     85 
     86 class MultipleInheritance : public Callback, public M2 {};
     87 
     88 TEST(MutexMethodPointerTest, ConditionWithMultipleInheritanceMethod) {
     89  // This test ensures that Condition can deal with method pointers from classes
     90  // with multiple inheritance.
     91  MultipleInheritance object = MultipleInheritance();
     92  absl::Condition condition(&object, &MultipleInheritance::method);
     93  EXPECT_FALSE(condition.Eval());
     94  EXPECT_TRUE(condition.Eval());
     95 }
     96 
     97 class __virtual_inheritance VirtualInheritance : virtual public Callback {
     98  bool x = false;
     99 
    100 public:
    101  VirtualInheritance() {}
    102  bool method() {
    103    x = !x;
    104    return x;
    105  }
    106 };
    107 
    108 TEST(MutexMethodPointerTest, ConditionWithVirtualInheritanceMethod) {
    109  // This test ensures that Condition can deal with method pointers from classes
    110  // with virtual inheritance.
    111  VirtualInheritance object = VirtualInheritance();
    112  absl::Condition condition(&object, &VirtualInheritance::method);
    113  EXPECT_TRUE(condition.Eval());
    114  EXPECT_FALSE(condition.Eval());
    115 }
    116 #endif  // #ifdef _MSC_VER
    117 
    118 TEST(MutexMethodPointerTest, ConditionWithIncompleteClassMethod) {
    119  using IncompleteClassMethodPointer = void (IncompleteClass::*)();
    120 
    121  union CallbackSlot {
    122    void (*anonymous_function_pointer)();
    123    IncompleteClassMethodPointer incomplete_class_method_pointer;
    124  };
    125 
    126  static_assert(sizeof(CallbackSlot) >= sizeof(IncompleteClassMethodPointer),
    127                "The callback slot is not big enough for method pointers.");
    128  static_assert(
    129      sizeof(CallbackSlot) == sizeof(IncompleteClassMethodPointer),
    130      "The callback slot is not big enough for anonymous function pointers.");
    131 
    132 #if defined(_MSC_VER)
    133  static_assert(sizeof(IncompleteClassMethodPointer) <= 24,
    134                "The pointer to a method of an incomplete class is too big.");
    135 #endif
    136 }
    137 
    138 }  // namespace