Coverage for /Syzygy/refinery/types/test_vtables.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
0.0%0076.C++source

Line-by-line coverage:

   1    :  // Copyright 2015 Google Inc. All Rights Reserved.
   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    :  //     http://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    :  // A set of classes to experiment with object layout wrt vftables. To obtain
  16    :  // Visual Studio's object layout use /d1reportAllClassLayout or
  17    :  // /d1reportSingleClassLayout, eg:
  18    :  //   cl /c /d1reportSingleClassLayoutNoVirtualMethodUDT test_vtables.cc
  19    :  
  20    :  #include <cstdint>
  21    :  
  22    :  #include "syzygy/refinery/types/alias.h"
  23    :  
  24  m :  namespace testing {
  25    :  
  26    :  // Note: we declare different functions (return different integers) to avoid
  27    :  // the possibility of vtables overlapping.
  28    :  
  29    :  // Visual Studio expectation
  30    :  // class NoVirtualMethodUDT        size(4):
  31    :  //         +---
  32    :  //  0      | a
  33    :  //         +---
  34  m :  struct NoVirtualMethodUDT {
  35  m :    int a;
  36  m :    int f();
  37  m :  };
  38    :  
  39    :  // class NoVirtualMethodChildUDT   size(12):
  40    :  //         +---
  41    :  //  0      | {vfptr}
  42    :  //         | +--- (base class NoVirtualMethodUDT)
  43    :  //  4      | | a
  44    :  //         | +---
  45    :  //  8      | a
  46    :  //         +---
  47  m :  struct NoVirtualMethodChildUDT : public NoVirtualMethodUDT {
  48  m :    int a;
  49  m :    int f();
  50  m :    virtual int g() { return 0; }
  51  m :  };
  52    :  
  53    :  // Visual Studio expectation: a vftable pointer at offset 0.
  54    :  // class VirtualMethodUDT  size(8):
  55    :  //         +---
  56    :  //  0      | {vfptr}
  57    :  //  4      | a
  58    :  //         +---
  59  m :  struct VirtualMethodUDT {
  60  m :    int a;
  61  m :    virtual int f() { return 1; }
  62  m :  };
  63    :  
  64    :  // Visual Studio expectation: a vftable pointer at offset 0.
  65    :  // class ChildUDT  size(12):
  66    :  //         +---
  67    :  //         | +--- (base class VirtualMethodUDT)
  68    :  //  0      | | {vfptr}
  69    :  //  4      | | a
  70    :  //         | +---
  71    :  //  8      | b
  72    :  //         +---
  73  m :  struct ChildUDT : public VirtualMethodUDT {
  74  m :    int b;
  75  m :    int f() override { return 2; }
  76  m :  };
  77    :  
  78    :  // Visual Studio expectation: a class that has virtual functions (possibly
  79    :  // through inheritance) always has a vftable pointer at offset 0 unless it only
  80    :  // has these due to virtual bases.
  81    :  
  82    :  // class VirtualChildUDT   size(16):
  83    :  //         +---
  84    :  //  0      | {vbptr}
  85    :  //  4      | b
  86    :  //         +---
  87    :  //         +--- (virtual base VirtualMethodUDT)
  88    :  //  8      | {vfptr}
  89    :  // 12      | a
  90    :  //         +---
  91  m :  struct VirtualChildUDT : virtual VirtualMethodUDT {
  92  m :    int b;
  93  m :    int f() override { return 3; }
  94  m :  };
  95    :  
  96    :  // class VirtualChildWithVirtualMethodUDT  size(20):
  97    :  //         +---
  98    :  //  0      | {vfptr}
  99    :  //  4      | {vbptr}
 100    :  //  8      | b
 101    :  //         +---
 102    :  //         +--- (virtual base VirtualMethodUDT)
 103    :  // 12      | {vfptr}
 104    :  // 16      | a
 105    :  //         +---
 106  m :  struct VirtualChildWithVirtualMethodUDT : virtual VirtualMethodUDT {
 107  m :    int b;
 108  m :    int f() override { return 4; }
 109  m :    virtual int g() { return 5; }
 110  m :  };
 111    :  
 112    :  // class ComposedUDT       size(16):
 113    :  //         +---
 114    :  //  0      | {vfptr}
 115    :  //  4      | a
 116    :  //  8      | VirtualMethodUDT udt
 117    :  //         +---
 118  m :  struct ComposedUDT {
 119  m :    int a;
 120  m :    VirtualMethodUDT udt;
 121  m :    virtual int f() { return 6; }
 122  m :  };
 123    :  
 124    :  // Interface implementation case.
 125    :  // class InterfaceImplUDT  size(16):
 126    :  //         +---
 127    :  //         | +--- (base class IA)
 128    :  //  0      | | {vfptr}
 129    :  //         | +---
 130    :  //         | +--- (base class IB)
 131    :  //  4      | | {vfptr}
 132    :  //         | +---
 133    :  //         | +--- (base class SimpleBase)
 134    :  //  8      | | member
 135    :  //         | +---
 136    :  // 12      | bar
 137    :  //         +---
 138  m :  struct IA { virtual int one() = 0; };
 139  m :  struct IB { virtual int two() = 0; };
 140  m :  struct SimpleBase { int member; };
 141  m :  struct InterfaceImplUDT : public SimpleBase, public IA, public IB {
 142  m :    int bar;
 143  m :    int one() override { return 7; }
 144  m :    int two() override { return 8; }
 145  m :  };
 146    :  
 147  m :  void AliasTypes() {
 148  m :    NoVirtualMethodUDT no_virtual_method_udt = {};
 149  m :    Alias(&no_virtual_method_udt);
 150  m :  }
 151    :  
 152    :  // Gets the expected vftable virtual addresses.
 153    :  // @param buffer_size size of @p vftable_vas
 154    :  // @param vftable_vas on success, contains the expected vftable virtual
 155    :  //     addresses.
 156    :  // @param count on success, the count of returned vftable virtual addresses.
 157    :  // @returns true on success, false otherwise.
 158  m :  extern "C" bool GetExpectedVftableVAs(unsigned buffer_size,
 159  m :                                        uint64_t* vftable_vas,
 160  m :                                        unsigned* count) {
 161  m :    if (!vftable_vas || !count)
 162  m :      return false;
 163    :    // Validate pointer size.
 164  m :    if (sizeof(unsigned) != sizeof(unsigned*))
 165  m :      return false;
 166  m :    if (buffer_size < 3U)
 167  m :      return false;
 168    :  
 169  m :    unsigned cnt = 0U;
 170    :  
 171  m :    {
 172  m :      VirtualMethodUDT udt;
 173  m :      vftable_vas[cnt] =
 174  m :          static_cast<uint64_t>(*reinterpret_cast<uintptr_t*>(&udt));
 175  m :      cnt++;
 176  m :    }
 177    :  
 178  m :    {
 179  m :      ComposedUDT udt;
 180  m :      vftable_vas[cnt] =
 181  m :          static_cast<uint64_t>(*reinterpret_cast<uintptr_t*>(&udt));
 182  m :      cnt++;
 183  m :    }
 184    :  
 185  m :    {
 186  m :      VirtualChildWithVirtualMethodUDT udt;
 187  m :      vftable_vas[cnt] =
 188  m :          static_cast<uint64_t>(*reinterpret_cast<uintptr_t*>(&udt));
 189  m :      cnt++;
 190  m :    }
 191    :  
 192    :    // TODO(manzagop): handle the other cases.
 193    :  
 194  m :    *count = cnt;
 195  m :    return true;
 196  m :  }
 197    :  
 198  m :  }  // namespace testing

Coverage information generated Fri Jul 29 11:00:21 2016.