// 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(); }