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;
}
|