blob: a71a66ff99dfaa38ebad697ca5262d2e7df68399 [file] [log] [blame]
// C++26 P3533R2 - constexpr virtual inheritance
// { dg-do compile { target c++26 } }
struct A {
int a;
constexpr virtual int foo () { return a; };
constexpr A () : a (42) {}
constexpr A (int x) : a (x) {}
constexpr virtual ~A () { if (a < 42 || a > 62) asm (""); }
};
struct B : public A {
int b;
constexpr virtual int foo () { return a + b; }
constexpr B () : A (43), b (42) {}
constexpr B (int x, int y) : A (x), b (y) {}
constexpr virtual ~B () { if (b < 42 || b > 62) asm (""); }
};
struct C : virtual public B {
int c;
constexpr C () : B (44, 43), c (45) {}
constexpr C (int x) : B (44, 43), c (x) {}
constexpr virtual int bar () { return a + b + c; }
constexpr virtual ~C () { if (c < 42 || c > 62) asm (""); }
};
struct D : virtual public B {
int d;
constexpr D () : B (44, 43), d (45) {}
constexpr D (int x) : B (44, 43), d (x) {}
constexpr virtual int baz () { return a + b + d; }
constexpr virtual ~D () { if (d < 42 || d > 62) asm (""); }
};
struct E : public C, D {
int e;
constexpr E () : B (), C (), D (), e (58) {}
constexpr E (int x, int y, int z, int w, int v) : B (x, y), C (z), D (w), e (v) {}
constexpr virtual ~E () { if (e < 42 || e > 62) asm (""); }
};
constexpr bool
qux ()
{
E f (45, 46, 47, 48, 49);
f.a++;
f.b++;
f.c++;
f.d++;
f.e++;
C *c = static_cast <C *> (&f);
D *d = static_cast <D *> (&f);
B *b = static_cast <B *> (&f);
A *a = static_cast <A *> (&f);
if (f.foo () != 46 + 47)
return false;
if (f.bar () != 46 + 47 + 48)
return false;
if (f.baz () != 46 + 47 + 49)
return false;
a->a += 2;
b->b += 3;
c->c += 4;
c->a += 5;
d->d += 6;
d->a += 7;
if (c->foo () != 60 + 50)
return false;
c->b -= 3;
if (d->foo () != 60 + 47)
return false;
if (f.a != 60 || f.b != 47 || f.c != 52 || f.d != 55 || f.e != 50)
return false;
C g (48);
c = static_cast <C *> (&g);
b = static_cast <B *> (&g);
a = static_cast <A *> (&g);
g.a++;
g.b++;
g.c++;
if (g.foo () != 45 + 44)
return false;
if (g.bar () != 45 + 44 + 49)
return false;
a->a += 2;
b->b += 3;
c->c += 4;
if (c->foo () != 47 + 47)
return false;
if (g.a != 47 || g.b != 47 || g.c != 53)
return false;
D h (49);
d = static_cast <D *> (&h);
b = static_cast <B *> (&h);
a = static_cast <A *> (&h);
h.a++;
h.b++;
h.d++;
if (h.foo () != 45 + 44)
return false;
if (h.baz () != 45 + 44 + 50)
return false;
a->a += 2;
b->b += 3;
d->d += 4;
if (d->foo () != 47 + 47)
return false;
if (h.a != 47 || h.b != 47 || h.d != 54)
return false;
return true;
}
constexpr bool
corge ()
{
E *f = new E (45, 46, 47, 48, 49);
f->a++;
f->b++;
f->c++;
f->d++;
f->e++;
C *c = static_cast <C *> (f);
D *d = static_cast <D *> (f);
B *b = static_cast <B *> (f);
A *a = static_cast <A *> (f);
if (f->foo () != 46 + 47)
return false;
if (f->bar () != 46 + 47 + 48)
return false;
if (f->baz () != 46 + 47 + 49)
return false;
a->a += 2;
b->b += 3;
c->c += 4;
c->a += 5;
d->d += 6;
d->a += 7;
if (c->foo () != 60 + 50)
return false;
c->b -= 3;
if (d->foo () != 60 + 47)
return false;
if (f->a != 60 || f->b != 47 || f->c != 52 || f->d != 55 || f->e != 50)
return false;
C *g = new C (48);
c = static_cast <C *> (g);
b = static_cast <B *> (g);
a = static_cast <A *> (g);
g->a++;
g->b++;
g->c++;
if (g->foo () != 45 + 44)
return false;
if (g->bar () != 45 + 44 + 49)
return false;
a->a += 2;
b->b += 3;
c->c += 4;
if (c->foo () != 47 + 47)
return false;
if (g->a != 47 || g->b != 47 || g->c != 53)
return false;
D *h = new D (49);
d = static_cast <D *> (h);
b = static_cast <B *> (h);
a = static_cast <A *> (h);
h->a++;
h->b++;
h->d++;
if (h->foo () != 45 + 44)
return false;
if (h->baz () != 45 + 44 + 50)
return false;
a->a += 2;
b->b += 3;
d->d += 4;
if (d->foo () != 47 + 47)
return false;
if (h->a != 47 || h->b != 47 || h->d != 54)
return false;
delete h;
delete g;
delete f;
return true;
}
static_assert (qux ());
static_assert (corge ());
constexpr E a;
constexpr E b (45, 46, 47, 48, 49);
constexpr C c;
constexpr C d (50);