summaryrefslogtreecommitdiff
path: root/gcc/testsuite/obj-c++.dg/bitfield-1.mm
blob: 92aaae4cfdadf30dbae590395b57e5306bc0d857 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/* Check if ObjC class layout follows the ABI (informally)
   set in the past.  ObjC structs must be laid out as if
   all ivars, including those inherited from superclasses,
   were defined at once (i.e., any padding introduced for
   superclasses should be removed).  */
/* Contributed by Ziemowit Laski <zlaski@apple.com>.  */
/* { dg-do run } */
/* { dg-options "-Wpadded -Wabi" } */

/* Leave blank lines here to keep warnings on the same lines.  */

#include "../objc-obj-c++-shared/TestsuiteObject.m"
#include <objc/objc.h>
#include <stdlib.h>

#define CHECK_IF(expr) if(!(expr)) abort()

enum Enum { zero, one, two, three, four };

@interface Base: TestsuiteObject {
@public
  unsigned a: 2;
  int b: 3;
  enum Enum c: 4;
  unsigned d: 5;
} /* { dg-warning "padding struct size to alignment boundary" } */
@end

struct Base_0 { /* { dg-warning "padding struct size to alignment boundary" } */
  Class isa;
  unsigned a: 2;
  int b: 3;
  enum Enum c: 4;
  unsigned d: 5;
};

@interface Derived: Base {
@public
  signed e: 5;
  unsigned f: 4;
  enum Enum g: 3;
}
@end

struct Derived_0 {
  Class isa;
  unsigned a: 2;
  int b: 3;
  enum Enum c: 4;
  unsigned d: 5;
  signed e: 5;
  int f: 4;
  enum Enum g: 3;
};

@interface Leaf: Derived {
@public
  signed h: 2;
}
@end

struct Leaf_0 {
  Class isa;
  unsigned a: 2;
  int b: 3;
  enum Enum c: 4;
  unsigned d: 5;
  signed e: 5;
  unsigned f: 4;
  enum Enum g: 3;
  signed h: 2;
};
  
/* Note that the semicolon after @defs(...) is optional.  */

typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */
typedef struct { @defs(Derived); } Derived_t;
typedef struct { @defs(Leaf); } Leaf_t;

int main(void)
{
  struct Leaf_0 l_0;
  Leaf *l = (Leaf *)&l_0;
  Leaf_t *l_t = (Leaf_t *)&l_0;

  CHECK_IF(sizeof(Base_t) == sizeof(Base));
  CHECK_IF(sizeof(Derived_t) == sizeof(Derived));
  CHECK_IF(sizeof(Leaf_t) == sizeof(Leaf));

  CHECK_IF(sizeof(struct Base_0) == sizeof(Base));
  CHECK_IF(sizeof(struct Derived_0) == sizeof(Derived));
  CHECK_IF(sizeof(struct Leaf_0) == sizeof(Leaf));

  l_0.isa = (Class)0;
  l_0.a = 3;
  l_0.b = 0;
  l_0.c = three;
  l_0.d = 31;
  l_0.e = 0;
  l_0.f = 15;
  l_0.g = zero;
  l_0.h = -2;

  CHECK_IF(!l_t->isa);
  CHECK_IF(l->a == 3 && l_t->a == 3);
  CHECK_IF(!l->b && !l_t->b);
  CHECK_IF(l->c == three && l_t->c == three);
  CHECK_IF(l->d == 31 && l_t->d == 31);
  CHECK_IF(!l->e && !l_t->e);
  CHECK_IF(l->f == 15 && l_t->f == 15);
  CHECK_IF(l->g == zero && l_t->g == zero);
  CHECK_IF(l->h == -2 && l_t->h == -2);
  
  return 0;
}

/* { dg-prune-output "In file included from" }  Ignore this message.  */
/* { dg-bogus "padding struct to align" "PR23610" { target *-*-* } 0 } */
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 42 } */
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 45 } */
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 59 } */
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 62 } */
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 77 } */
/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } 78 } */