brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.4 KiB · d5bb466 Raw
266 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -fsyntax-only -triple x86_64-linux-gnu -fdump-record-layouts %s | FileCheck %s2 3namespace Empty {4  struct A {};5  struct B { [[no_unique_address]] A a; char b; };6  static_assert(sizeof(B) == 1);7 8  // CHECK:*** Dumping AST Record Layout9  // CHECK:          0 | struct Empty::B10  // CHECK-NEXT:     0 |   struct Empty::A a (empty)11  // CHECK-NEXT:     0 |   char b12  // CHECK-NEXT:       | [sizeof=1, dsize=1, align=1,13  // CHECK-NEXT:       |  nvsize=1, nvalign=1]14 15  struct C {};16  struct D {17    [[no_unique_address]] A a;18    [[no_unique_address]] C c;19    char d;20  };21  static_assert(sizeof(D) == 1);22 23  // CHECK:*** Dumping AST Record Layout24  // CHECK:          0 | struct Empty::D25  // CHECK-NEXT:     0 |   struct Empty::A a (empty)26  // CHECK-NEXT:     0 |   struct Empty::C c (empty)27  // CHECK-NEXT:     0 |   char d28  // CHECK-NEXT:       | [sizeof=1, dsize=1, align=1,29  // CHECK-NEXT:       |  nvsize=1, nvalign=1]30 31  struct E {32    [[no_unique_address]] A a1;33    [[no_unique_address]] A a2;34    char e;35  };36  static_assert(sizeof(E) == 2);37 38  // CHECK:*** Dumping AST Record Layout39  // CHECK:          0 | struct Empty::E40  // CHECK-NEXT:     0 |   struct Empty::A a1 (empty)41  // CHECK-NEXT:     1 |   struct Empty::A a2 (empty)42  // CHECK-NEXT:     0 |   char e43  // CHECK-NEXT:       | [sizeof=2, dsize=2, align=1,44  // CHECK-NEXT:       |  nvsize=2, nvalign=1]45 46  struct F {47    ~F();48    [[no_unique_address]] A a1;49    [[no_unique_address]] A a2;50    char f;51  };52  static_assert(sizeof(F) == 2);53 54  // CHECK:*** Dumping AST Record Layout55  // CHECK:          0 | struct Empty::F56  // CHECK-NEXT:     0 |   struct Empty::A a1 (empty)57  // CHECK-NEXT:     1 |   struct Empty::A a2 (empty)58  // CHECK-NEXT:     0 |   char f59  // CHECK-NEXT:       | [sizeof=2, dsize=1, align=1,60  // CHECK-NEXT:       |  nvsize=2, nvalign=1]61 62  struct G { [[no_unique_address]] A a; ~G(); };63  static_assert(sizeof(G) == 1);64 65  // CHECK:*** Dumping AST Record Layout66  // CHECK:          0 | struct Empty::G67  // CHECK-NEXT:     0 |   struct Empty::A a (empty)68  // CHECK-NEXT:       | [sizeof=1, dsize=0, align=1,69  // CHECK-NEXT:       |  nvsize=1, nvalign=1]70 71  struct H { [[no_unique_address]] A a, b; ~H(); };72  static_assert(sizeof(H) == 2);73 74  // CHECK:*** Dumping AST Record Layout75  // CHECK:          0 | struct Empty::H76  // CHECK-NEXT:     0 |   struct Empty::A a (empty)77  // CHECK-NEXT:     1 |   struct Empty::A b (empty)78  // CHECK-NEXT:       | [sizeof=2, dsize=0, align=1,79  // CHECK-NEXT:       |  nvsize=2, nvalign=1]80 81  struct OversizedEmpty : A {82    ~OversizedEmpty();83    [[no_unique_address]] A a;84  };85  static_assert(sizeof(OversizedEmpty) == 2);86 87  // CHECK:*** Dumping AST Record Layout88  // CHECK:          0 | struct Empty::OversizedEmpty89  // CHECK-NEXT:     0 |   struct Empty::A (base) (empty)90  // CHECK-NEXT:     1 |   struct Empty::A a (empty)91  // CHECK-NEXT:       | [sizeof=2, dsize=0, align=1,92  // CHECK-NEXT:       |  nvsize=2, nvalign=1]93 94  struct HasOversizedEmpty {95    [[no_unique_address]] OversizedEmpty m;96  };97  static_assert(sizeof(HasOversizedEmpty) == 2);98 99  // CHECK:*** Dumping AST Record Layout100  // CHECK:          0 | struct Empty::HasOversizedEmpty101  // CHECK-NEXT:     0 |   struct Empty::OversizedEmpty m (empty)102  // CHECK-NEXT:     0 |     struct Empty::A (base) (empty)103  // CHECK-NEXT:     1 |     struct Empty::A a (empty)104  // CHECK-NEXT:       | [sizeof=2, dsize=0, align=1,105  // CHECK-NEXT:       |  nvsize=2, nvalign=1]106 107  struct EmptyWithNonzeroDSize {108    [[no_unique_address]] A a;109    int x;110    [[no_unique_address]] A b;111    int y;112    [[no_unique_address]] A c;113  };114  static_assert(sizeof(EmptyWithNonzeroDSize) == 12);115 116  // CHECK:*** Dumping AST Record Layout117  // CHECK:          0 | struct Empty::EmptyWithNonzeroDSize118  // CHECK-NEXT:     0 |   struct Empty::A a (empty)119  // CHECK-NEXT:     0 |   int x120  // CHECK-NEXT:     4 |   struct Empty::A b (empty)121  // CHECK-NEXT:     4 |   int y122  // CHECK-NEXT:     8 |   struct Empty::A c (empty)123  // CHECK-NEXT:       | [sizeof=12, dsize=12, align=4,124  // CHECK-NEXT:       |  nvsize=12, nvalign=4]125 126  struct EmptyWithNonzeroDSizeNonPOD {127    ~EmptyWithNonzeroDSizeNonPOD();128    [[no_unique_address]] A a;129    int x;130    [[no_unique_address]] A b;131    int y;132    [[no_unique_address]] A c;133  };134  static_assert(sizeof(EmptyWithNonzeroDSizeNonPOD) == 12);135 136  // CHECK:*** Dumping AST Record Layout137  // CHECK:          0 | struct Empty::EmptyWithNonzeroDSizeNonPOD138  // CHECK-NEXT:     0 |   struct Empty::A a (empty)139  // CHECK-NEXT:     0 |   int x140  // CHECK-NEXT:     4 |   struct Empty::A b (empty)141  // CHECK-NEXT:     4 |   int y142  // CHECK-NEXT:     8 |   struct Empty::A c (empty)143  // CHECK-NEXT:       | [sizeof=12, dsize=8, align=4,144  // CHECK-NEXT:       |  nvsize=9, nvalign=4]145}146 147namespace POD {148  // Cannot reuse tail padding of a PDO type.149  struct A { int n; char c[3]; };150  struct B { [[no_unique_address]] A a; char d; };151  static_assert(sizeof(B) == 12);152 153  // CHECK:*** Dumping AST Record Layout154  // CHECK:          0 | struct POD::B155  // CHECK-NEXT:     0 |   struct POD::A a156  // CHECK-NEXT:     0 |     int n157  // CHECK-NEXT:     4 |     char[3] c158  // CHECK-NEXT:     8 |   char d159  // CHECK-NEXT:       | [sizeof=12, dsize=12, align=4,160  // CHECK-NEXT:       |  nvsize=12, nvalign=4]161}162 163namespace NonPOD {164  struct A { int n; char c[3]; ~A(); };165  struct B { [[no_unique_address]] A a; char d; };166  static_assert(sizeof(B) == 8);167 168  // CHECK:*** Dumping AST Record Layout169  // CHECK:          0 | struct NonPOD::B170  // CHECK-NEXT:     0 |   struct NonPOD::A a171  // CHECK-NEXT:     0 |     int n172  // CHECK-NEXT:     4 |     char[3] c173  // CHECK-NEXT:     7 |   char d174  // CHECK-NEXT:       | [sizeof=8, dsize=8, align=4,175  // CHECK-NEXT:       |  nvsize=8, nvalign=4]176}177 178namespace NVSizeGreaterThanDSize {179  // The nvsize of an object includes the complete size of its empty subobjects180  // (although it's unclear why). Ensure this corner case is handled properly.181  struct alignas(8) A { ~A(); }; // dsize 0, nvsize 0, size 8182  struct B : A { char c; }; // dsize 1, nvsize 8, size 8183  static_assert(sizeof(B) == 8);184 185  // CHECK:*** Dumping AST Record Layout186  // CHECK:          0 | struct NVSizeGreaterThanDSize::B187  // CHECK-NEXT:     0 |   struct NVSizeGreaterThanDSize::A (base) (empty)188  // CHECK-NEXT:     0 |   char c189  // CHECK-NEXT:       | [sizeof=8, dsize=1, align=8,190  // CHECK-NEXT:       |  nvsize=8, nvalign=8]191 192  struct V { int n; };193 194  // V is at offset 16, not offset 12, because B's tail padding is strangely not195  // usable for virtual bases.196  struct C : B, virtual V {};197  static_assert(sizeof(C) == 24);198 199  // CHECK:*** Dumping AST Record Layout200  // CHECK:          0 | struct NVSizeGreaterThanDSize::C201  // CHECK-NEXT:     0 |   (C vtable pointer)202  // CHECK-NEXT:     8 |   struct NVSizeGreaterThanDSize::B (base)203  // CHECK-NEXT:     8 |     struct NVSizeGreaterThanDSize::A (base) (empty)204  // CHECK-NEXT:     8 |     char c205  // CHECK-NEXT:    16 |   struct NVSizeGreaterThanDSize::V (virtual base)206  // CHECK-NEXT:    16 |     int n207  // CHECK-NEXT:       | [sizeof=24, dsize=20, align=8,208  // CHECK-NEXT:       |  nvsize=16, nvalign=8]209 210  struct D : virtual V {211    [[no_unique_address]] B b;212  };213  static_assert(sizeof(D) == 24);214 215  // CHECK:*** Dumping AST Record Layout216  // CHECK:          0 | struct NVSizeGreaterThanDSize::D217  // CHECK-NEXT:     0 |   (D vtable pointer)218  // CHECK-NEXT:     8 |   struct NVSizeGreaterThanDSize::B b219  // CHECK-NEXT:     8 |     struct NVSizeGreaterThanDSize::A (base) (empty)220  // CHECK-NEXT:     8 |     char c221  // CHECK-NEXT:    16 |   struct NVSizeGreaterThanDSize::V (virtual base)222  // CHECK-NEXT:    16 |     int n223  // CHECK-NEXT:       | [sizeof=24, dsize=20, align=8,224  // CHECK-NEXT:       |  nvsize=16, nvalign=8]225 226  struct X : virtual A { [[no_unique_address]] A a; };227  struct E : virtual A {228    [[no_unique_address]] A a;229    // Here, we arrange for X to hang over the end of the nvsize of E. This230    // should force the A vbase to be laid out at offset 24, not 16.231    [[no_unique_address]] X x;232  };233  static_assert(sizeof(E) == 32);234 235  // CHECK:*** Dumping AST Record Layout236  // CHECK:          0 | struct NVSizeGreaterThanDSize::E237  // CHECK-NEXT:     0 |   (E vtable pointer)238  // CHECK-NEXT:     0 |   struct NVSizeGreaterThanDSize::A a (empty)239  // CHECK-NEXT:     8 |   struct NVSizeGreaterThanDSize::X x240  // CHECK-NEXT:     8 |     (X vtable pointer)241  // CHECK-NEXT:     8 |     struct NVSizeGreaterThanDSize::A a (empty)242  // CHECK-NEXT:    16 |     struct NVSizeGreaterThanDSize::A (virtual base) (empty)243  // CHECK-NEXT:    24 |   struct NVSizeGreaterThanDSize::A (virtual base) (empty)244  // CHECK-NEXT:       | [sizeof=32, dsize=16, align=8,245  // CHECK-NEXT:       |  nvsize=16, nvalign=8]246}247 248namespace RepeatedVBase {249  struct alignas(16) A { ~A(); };250  struct B : A {};251  struct X : virtual A, virtual B {};252  struct Y { [[no_unique_address]] X x; char c; };253  static_assert(sizeof(Y) == 32);254 255  // CHECK:*** Dumping AST Record Layout256  // CHECK:          0 | struct RepeatedVBase::Y257  // CHECK-NEXT:     0 |   struct RepeatedVBase::X x258  // CHECK-NEXT:     0 |     (X vtable pointer)259  // CHECK-NEXT:     0 |     struct RepeatedVBase::A (virtual base) (empty)260  // CHECK-NEXT:    16 |     struct RepeatedVBase::B (virtual base) (empty)261  // CHECK-NEXT:    16 |       struct RepeatedVBase::A (base) (empty)262  // CHECK-NEXT:     8 |     char c263  // CHECK-NEXT:       | [sizeof=32, dsize=9, align=16,264  // CHECK-NEXT:       |  nvsize=9, nvalign=16]265}266