aboutsummaryrefslogtreecommitdiffstats
path: root/test/regression/aligned.c
blob: bd16d513bff3afc3eed7782320f0ad38d656f605 (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
/* The "aligned" attribute */

#include <stdio.h>

#define ALIGNED __attribute((aligned(16)))
#define ALIGNED1 __attribute((aligned(1)))

typedef ALIGNED char c16;

struct s {
  char y;
  char ALIGNED x;
};

typedef struct { char y; } ALIGNED u;

struct {
  char filler1;

  /* Base type */
  char ALIGNED a;
  /* Array */
  /* Expected: array of 3 naturally-aligned chars -> size = 3 */
  ALIGNED char b[3];
  /* Pointer */
  /* Expected: 16-aligned pointer to naturally-aligned char */
  ALIGNED char * c;

/* Typedef */

  c16 d;
  /* Expected: like char ALIGNED d */
  // c16 e[3] = {2, 3, 4};
  /* Expected: unclear.  This one is rejected by gcc.
     clang says size = 16, alignment = 16, but initializes first 3 bytes only.
     compcert says size = 3, alignment = 16. */
  char filler2;
  c16 * f;
  /* Expected: naturally-aligned pointer to 16-aligned char */

/* Struct */

  struct s g;
  /* Expected: alignment 16, size 17
     (1 byte, padding to mod 16, 1 bytes) */

  char filler3;

  struct t {
    char y;
  } ALIGNED h;
  /* Expected: type struct t and variable h have alignment 16 and size 1 */

  char filler4;

  struct t i;
  /* Expected: alignment 16 and size 1.  This checks that the ALIGNED
     attribute is attached to "struct t". */

  char filler5;

  u j;
  /* Expected: type u and variable j have alignment 16 and size 1. */
} x;

typedef char T1[100];

typedef struct { T1 mess[1]; } ALIGNED T2;
/* Expected: alignment 16, size 112 = 100 aligned to 16 */

typedef T2 T3[];

typedef struct { T3 *area; } T4;
/* Expected: size of a pointer, alignment of a pointer */

struct t1 { double d; };
struct t2 { char c; ALIGNED1 struct t1 d; };
/* Expected: size = 1 + 8, alignment 1 */

void check(const char * msg, void * addr, size_t sz)
{
  printf("%s: size %zu, offset mod 16 = %lu\n",
         msg, sz, (unsigned long) ((char *) addr - (char *) &x) % 16);
}

void checkptr(const char * msg, void * addr, size_t sz, size_t al)
{
  printf("%s: size %s that of a pointer, offset mod 16 %s\n",
         msg,
         sz == sizeof(void *) ? "is" : "IS NOT",
         (((char *) addr - (char *) &x) % 16) == al ?
            "is good" : "IS BAD");
}

int main()
{
  check("a", &(x.a), sizeof(x.a));
  check("b", &(x.b), sizeof(x.b));
  checkptr("c", &(x.c), sizeof(x.c), 0);
  check("d", &(x.d), sizeof(x.d));
  checkptr("f", &(x.f), sizeof(x.f), _Alignof(void *));
  check("g", &(x.g), sizeof(x.g));
  check("h", &(x.h), sizeof(x.h));
  check("i", &(x.i), sizeof(x.i));
  check("j", &(x.j), sizeof(x.j));

  printf("T2: size %zu, alignment %zu\n", sizeof(T2), _Alignof(T2));
  printf("T4: size %s that of a pointer, alignment %s that of a pointer\n",
         sizeof(T4) == sizeof(void *) ? "is" : "IS NOT",
         _Alignof(T4) == _Alignof(void *) ? "is" : "IS NOT");

  printf("t2: size %zu, alignment %zu\n",
         sizeof(struct t2), _Alignof(struct t2));
  return 0;
}