blob: 93d66efd21aedebe8c2ca98ffe622bb6b1d4f5da [file] [log] [blame]
// PERMUTE_ARGS:
extern(C) int printf(const char*, ...);
class Foo : Object
{
void test() { }
invariant()
{
printf("in invariant %p\n", this);
}
}
int testinvariant()
{
printf("hello\n");
Foo f = new Foo();
printf("f = %p\n", f);
printf("f.sizeof = x%x\n", Foo.sizeof);
printf("f.classinfo = %p\n", f.classinfo);
printf("f.classinfo._invariant = %p\n", f.classinfo.base);
f.test();
printf("world\n");
return 0;
}
/***************************************************/
// 6453
void test6453()
{
static class C
{
static uint called;
invariant() { called += 1; }
invariant() { called += 4; }
invariant() { called += 16; }
void publicMember() { assert(called == 21); }
}
static struct S
{
static uint called;
invariant() { called += 1; }
invariant() { called += 4; }
invariant() { called += 16; }
void publicMember() { assert(called == 21); }
}
auto c = new C();
C.called = 0;
c.publicMember();
assert(C.called == 42);
auto s = new S();
S.called = 0;
s.publicMember();
assert(S.called == 42);
// Defined symbols in one invariant cannot be seen from others.
static struct S6453
{
invariant()
{
struct S {}
int x;
static assert(!__traits(compiles, y));
static assert(!__traits(compiles, z));
}
invariant()
{
struct S {}
int y;
static assert(!__traits(compiles, x));
static assert(!__traits(compiles, z));
}
invariant()
{
struct S {}
int z;
static assert(!__traits(compiles, x));
static assert(!__traits(compiles, y));
}
}
static struct S6453a
{
pure invariant() {}
nothrow invariant() {}
@safe invariant() {}
}
static struct S6453b
{
pure shared invariant() {}
nothrow shared invariant() {}
@safe shared invariant() {}
}
static class C6453c
{
pure synchronized invariant() {}
nothrow synchronized invariant() {}
@safe synchronized invariant() {}
}
}
/***************************************************/
// 13113
struct S13113
{
static int count;
invariant() // impure, throwable, system, and gc-able
{
++count; // impure
}
this(int) pure nothrow @safe @nogc {}
// post invaiant is called directly but doesn't interfere with constructor attributes
~this() pure nothrow @safe @nogc {}
// pre invaiant is called directly but doesn't interfere with destructor attributes
void foo() pure nothrow @safe @nogc {}
// pre & post invariant calls don't interfere with method attributes
}
void test13113()
{
assert(S13113.count == 0);
{
auto s = S13113(1);
assert(S13113.count == 1);
s.foo();
assert(S13113.count == 3);
}
assert(S13113.count == 4);
}
/***************************************************/
// 13147
version (D_InlineAsm_X86)
enum x86iasm = true;
else version (D_InlineAsm_X86_64)
enum x86iasm = true;
else
enum x86iasm = false;
class C13147
{
extern (C++) C13147 test()
{
static if (x86iasm)
asm { naked; ret; }
return this;
}
}
struct S13147
{
void test()
{
static if (x86iasm)
asm { naked; ret; }
}
}
void test13147()
{
auto c = new C13147();
c.test();
S13147 s;
s.test();
}
/***************************************************/
void main()
{
testinvariant();
test6453();
test13113();
test13147();
}