blob: 60078e1163486d0e9cc7f6edb0df7eeae2e352de [file] [log] [blame]
/* 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;
}