1/* Check if ObjC class layout follows the ABI (informally) 2 set in the past. ObjC structs must be laid out as if 3 all ivars, including those inherited from superclasses, 4 were defined at once (i.e., any padding introduced for 5 superclasses should be removed). */ 6/* Contributed by Ziemowit Laski <zlaski@apple.com>. */ 7/* { dg-do run } */ 8/* { dg-options "-Wpadded -Wabi=8" } */ 9 10/* Leave blank lines here to keep warnings on the same lines. */ 11 12#include "../objc-obj-c++-shared/TestsuiteObject.m" 13#include <objc/objc.h> 14#include <stdlib.h> 15 16#define CHECK_IF(expr) if(!(expr)) abort() 17 18enum Enum { zero, one, two, three, four }; 19 20@interface Base: TestsuiteObject { 21@public 22 unsigned a: 2; 23 int b: 3; 24 enum Enum c: 4; 25 unsigned d: 5; 26} /* { dg-warning "padding struct size to alignment boundary" } */ 27@end 28 29struct Base_0 { /* { dg-warning "padding struct size to alignment boundary" } */ 30 Class isa; 31 unsigned a: 2; 32 int b: 3; 33 enum Enum c: 4; 34 unsigned d: 5; 35}; 36 37@interface Derived: Base { 38@public 39 signed e: 5; 40 unsigned f: 4; 41 enum Enum g: 3; 42} /* { dg-line interface_Derived } */ 43@end 44 45struct Derived_0 { /* { dg-line struct_Derived_0 } */ 46 Class isa; 47 unsigned a: 2; 48 int b: 3; 49 enum Enum c: 4; 50 unsigned d: 5; 51 signed e: 5; 52 int f: 4; 53 enum Enum g: 3; 54}; 55 56@interface Leaf: Derived { 57@public 58 signed h: 2; 59} /* { dg-line interface_Leaf } */ 60@end 61 62struct Leaf_0 { /* { dg-line struct_Leaf_0 } */ 63 Class isa; 64 unsigned a: 2; 65 int b: 3; 66 enum Enum c: 4; 67 unsigned d: 5; 68 signed e: 5; 69 unsigned f: 4; 70 enum Enum g: 3; 71 signed h: 2; 72}; 73 74/* Note that the semicolon after @defs(...) is optional. */ 75 76typedef struct { @defs(Base) } Base_t; /* { dg-warning "padding struct size to alignment boundary" } */ 77typedef struct { @defs(Derived); } Derived_t; /* { dg-line Derived_t_def } */ 78typedef struct { @defs(Leaf); } Leaf_t; /* { dg-line Leaf_t_def } */ 79 80int main(void) 81{ 82 struct Leaf_0 l_0; 83 Leaf *l = (Leaf *)&l_0; 84 Leaf_t *l_t = (Leaf_t *)&l_0; 85 86 CHECK_IF(sizeof(Base_t) == sizeof(Base)); 87 CHECK_IF(sizeof(Derived_t) == sizeof(Derived)); 88 CHECK_IF(sizeof(Leaf_t) == sizeof(Leaf)); 89 90 CHECK_IF(sizeof(struct Base_0) == sizeof(Base)); 91 CHECK_IF(sizeof(struct Derived_0) == sizeof(Derived)); 92 CHECK_IF(sizeof(struct Leaf_0) == sizeof(Leaf)); 93 94 l_0.isa = (Class)0; 95 l_0.a = 3; 96 l_0.b = 0; 97 l_0.c = three; 98 l_0.d = 31; 99 l_0.e = 0; 100 l_0.f = 15; 101 l_0.g = zero; 102 l_0.h = -2; 103 104 CHECK_IF(!l_t->isa); 105 CHECK_IF(l->a == 3 && l_t->a == 3); 106 CHECK_IF(!l->b && !l_t->b); 107 CHECK_IF(l->c == three && l_t->c == three); 108 CHECK_IF(l->d == 31 && l_t->d == 31); 109 CHECK_IF(!l->e && !l_t->e); 110 CHECK_IF(l->f == 15 && l_t->f == 15); 111 CHECK_IF(l->g == zero && l_t->g == zero); 112 CHECK_IF(l->h == -2 && l_t->h == -2); 113 114 return 0; 115} 116 117/* { dg-prune-output "In file included from" } Ignore this message. */ 118/* { dg-bogus "padding struct to align" "PR23610" { target *-*-* } 0 } */ 119/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } interface_Derived } */ 120/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } struct_Derived_0 } */ 121/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } interface_Leaf } */ 122/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } struct_Leaf_0 } */ 123/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } Derived_t_def } */ 124/* { dg-bogus "padding struct size" "PR23610" { xfail lp64 } Leaf_t_def } */ 125