File: builtin-object-size-pr101832.c

package info (click to toggle)
gcc-arm-none-eabi 15%3A14.2.rel1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,099,328 kB
  • sloc: cpp: 3,627,108; ansic: 2,571,498; ada: 834,230; f90: 235,082; makefile: 79,231; asm: 74,984; xml: 51,692; exp: 39,736; sh: 33,298; objc: 15,629; python: 15,069; fortran: 14,429; pascal: 7,003; awk: 5,070; perl: 3,106; ml: 285; lisp: 253; lex: 204; haskell: 135
file content (134 lines) | stat: -rw-r--r-- 2,784 bytes parent folder | download
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
125
126
127
128
129
130
131
132
133
134
/* PR 101832: 
   GCC extension accepts the case when a struct with a C99 flexible array
   member is embedded into another struct (possibly recursively).
   __builtin_object_size will treat such struct as flexible size.
   However, when a structure with non-C99 flexible array member, i.e, trailing
   [0], [1], or [4], is embedded into anther struct, the stucture will not
   be treated as flexible size.  */ 
/* { dg-do run } */
/* { dg-options "-O2" } */

#include "builtin-object-size-common.h"

#define expect(p, _v) do { \
  size_t v = _v; \
  if (p == v) \
    __builtin_printf ("ok:  %s == %zd\n", #p, p); \
  else {\
    __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \
    FAIL (); \
  } \
} while (0);


struct A {
  int n;
  char data[];
};

struct B {
  int m;
  struct A a;
};

struct C {
  int q;
  struct B b;
};

struct A0 {
  int n;
  char data[0];
};

struct B0 {
  int m;
  struct A0 a;
};

struct C0 {
  int q;
  struct B0 b;
};

struct A1 {
  int n;
  char data[1];
};

struct B1 {
  int m;
  struct A1 a;
};

struct C1 {
  int q;
  struct B1 b;
};

struct An {
  int n;
  char data[8];
};

struct Bn {
  int m;
  struct An a;
};

struct Cn {
  int q;
  struct Bn b;
};

volatile void *magic1, *magic2;

int main (int argc, char *argv[])
{
  struct B *outer;
  struct C *outest;

  /* Make sure optimization can't find some other object size. */
  outer = (void *)magic1;
  outest = (void *)magic2;

  expect (__builtin_object_size (&outer->a, 1), -1);
  expect (__builtin_object_size (&outest->b, 1), -1);
  expect (__builtin_object_size (&outest->b.a, 1), -1);

  struct B0 *outer0;
  struct C0 *outest0;

  /* Make sure optimization can't find some other object size. */
  outer0 = (void *)magic1;
  outest0 = (void *)magic2;

  expect (__builtin_object_size (&outer0->a, 1), sizeof (outer0->a));
  expect (__builtin_object_size (&outest0->b, 1), sizeof (outest0->b));
  expect (__builtin_object_size (&outest0->b.a, 1), sizeof (outest0->b.a));

  struct B1 *outer1;
  struct C1 *outest1;

  /* Make sure optimization can't find some other object size. */
  outer1 = (void *)magic1;
  outest1 = (void *)magic2;

  expect (__builtin_object_size (&outer1->a, 1), sizeof (outer1->a));
  expect (__builtin_object_size (&outest1->b, 1), sizeof (outest1->b));
  expect (__builtin_object_size (&outest1->b.a, 1), sizeof (outest1->b.a));

  struct Bn *outern;
  struct Cn *outestn;

  /* Make sure optimization can't find some other object size. */
  outern = (void *)magic1;
  outestn = (void *)magic2;

  expect (__builtin_object_size (&outern->a, 1), sizeof (outern->a));
  expect (__builtin_object_size (&outestn->b, 1), sizeof (outestn->b));
  expect (__builtin_object_size (&outestn->b.a, 1), sizeof (outestn->b.a));

  DONE ();
  return 0;
}