aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c
blob: d4899a63af3c47a84ed9727910cc45dc846798cf (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
/* Test the code generation for the new attribute counted_by.
   And also the offsetof operator on such array.  */
/* { dg-do run } */
/* { dg-options "-O2 -fdump-tree-original" } */

#include <stdlib.h>

struct annotated {
  int b;
  char c[] __attribute__ ((counted_by (b)));
} *array_annotated;

static struct annotated static_annotated = { sizeof "hello", "hello" };
static char *y = static_annotated.c;

struct flex {
  int b;
  char c[]; 
}; 

struct nested_annotated {
  struct {
    union {
      int b;
      float f;	
    };
    int n;
  };
  char c[] __attribute__ ((counted_by (b)));
} *array_nested_annotated;

static struct nested_annotated nested_static_annotated
				 = { sizeof "hello1", 0, "hello1" };
static char *nested_y = nested_static_annotated.c;

struct nested_flex {
  struct {
    union {
      int b;
      float f;	
    };
    int n;
  };
  char c[];
};

void __attribute__((__noinline__)) setup (int normal_count, int attr_count)
{
  array_annotated
    = (struct annotated *)malloc (sizeof (struct annotated)
				  + attr_count *  sizeof (char));
  array_annotated->b = attr_count;

  array_nested_annotated
    = (struct nested_annotated *)malloc (sizeof (struct nested_annotated)
					 + attr_count *  sizeof (char));
  array_nested_annotated->b = attr_count;

  return;
}

void __attribute__((__noinline__)) test (char a, char b)
{
  if (__builtin_offsetof (struct annotated, c[0])
      != __builtin_offsetof (struct flex, c[0]))
    abort ();
  if (__builtin_offsetof (struct annotated, c[1])
      != __builtin_offsetof (struct flex, c[1]))
    abort ();
  if (__builtin_offsetof (struct nested_annotated, c[0]) 
      != __builtin_offsetof (struct nested_flex, c[0])) 
    abort ();
  if (__builtin_offsetof (struct nested_annotated, c[1]) 
      != __builtin_offsetof (struct nested_flex, c[1])) 
    abort ();

  if (__builtin_types_compatible_p (typeof (array_annotated->c),
				    typeof (&(array_annotated->c)[0])))
    abort ();
  if (__builtin_types_compatible_p (typeof (array_nested_annotated->c),
				    typeof (&(array_nested_annotated->c)[0])))
    abort ();

  if (__alignof (array_annotated->c) != __alignof (char))
    abort ();
  if (__alignof (array_nested_annotated->c) != __alignof (char))
    abort ();

  if ((unsigned long) array_annotated->c != (unsigned long) &array_annotated->c)
    abort ();
  if ((unsigned long) array_nested_annotated->c
       != (unsigned long) &array_nested_annotated->c)
    abort ();

  array_annotated->c[2] = a;
  array_nested_annotated->c[3] = b;

  if (y[2] != 'l') abort ();
  if (nested_y[4] !='o') abort ();

}

int main(int argc, char *argv[])
{
  setup (10,10);   
  test ('A', 'B');
  if (array_annotated->c[2] != 'A') abort ();
  if (array_nested_annotated->c[3] != 'B') abort ();
  return 0;
}

/* { dg-final { scan-tree-dump-times "ACCESS_WITH_SIZE" 8 "original" } } */