// REQUIRED_ARGS: -o- // PERMUTE_ARGS: // Disallow skipping variable decl static assert(!__traits(compiles, (bool b) { if (b) goto label; int x; label: {} assert(!x); })); // Disallow skipping variable in block backwards static assert(!__traits(compiles, (bool b) { { int x; label: {} assert(!x); } if (b) goto label; })); // Disallow skipping backwards int block static assert(!__traits(compiles, (bool b) { { int x; label: {} assert(!x); } if (b) goto label; })); // Variable inside try block static assert(!__traits(compiles, (bool b) { if (b) goto label; try { int x; label: {} assert(!x); } catch(Throwable) { } })); // Variable inside catch block static assert(!__traits(compiles, (bool b) { if (b) goto label; try { } catch(Throwable) { int x; label: {} assert(!x); } })); // Goto into catch block with unnamed exception static assert(__traits(compiles, (bool b) { if (b) goto label; try { } catch(Exception) { label: {} } })); // Goto into catch block with named exception static assert(!__traits(compiles, (bool b) { if (b) goto label; try { } catch(Exception e) { label: {} assert(e); } })); // Goto into finally block static assert(!__traits(compiles, (bool b) { if (b) goto label; try { } finally { label: {} } })); // Goto into variable with block static assert(!__traits(compiles, (bool b) { if (b) goto label; struct S { int x; } with (S()) { label: {} assert(!x); } })); // Goto backwards into variable with block static assert(!__traits(compiles, (bool b) { struct S { int x; } with (S()) { label: {} assert(!x); } if (b) goto label; })); // Goto into symbolic with block static assert(__traits(compiles, (bool b) { if (b) goto label; struct S { int x; } with (S) { label: {} } })); // Goto backwards into symbolic with block static assert(__traits(compiles, (bool b) { struct S { int x; } with (S) { label: {} } if (b) goto label; })); // Goto into for loop static assert(!__traits(compiles, (bool b) { if (b) goto label; for (int i = 0; i < 8; ++i) { label: {} assert(i); } })); // Goto into for loop backwards static assert(!__traits(compiles, (bool b) { for (int i = 0; i < 8; ++i) { label: {} assert(i); } if (b) goto label; })); // Goto into foreach loop static assert(!__traits(compiles, (bool b) { if (b) goto label; foreach(i; 0..8) { label: {} assert(i); } })); // Goto into foreach loop backwards static assert(!__traits(compiles, (bool b) { foreach(i; 0..8) { label: {} assert(i); } if (b) goto label; })); // Goto into if block with variable static assert(!__traits(compiles, (bool b) { if (b) goto label; if (auto x = b) { label: {} assert(x); } })); // Goto backwards into if block with variable static assert(!__traits(compiles, (bool b) { if (auto x = b) { label: {} assert(x); } if (b) goto label; })); // Goto into if block without variable static assert(__traits(compiles, (bool b) { if (b) goto label; if (b) { label: {} } })); // Goto into else block static assert(__traits(compiles, (bool b) { if (b) goto label; if (auto x = b) { } else { label: {} } })); // Goto backwards into else with variable static assert(!__traits(compiles, (bool b) { if (auto x = b) { } else { int y; label: {} } if (b) goto label; })); // Goto into while block static assert(__traits(compiles, (bool b) { if (b) goto label; while (b) { label: {} } })); // Goto into while block with internal variable static assert(!__traits(compiles, (bool b) { if (b) goto label; while (b) { int x; label: {} assert(!x); } })); // Goto into do block static assert(__traits(compiles, (bool b) { if (b) goto label; do { label: {} } while (b); })); // Goto over switch variable static assert(!__traits(compiles, (bool b) { if (b) goto label; switch(0) { default: break; int x; label: {} } })); // Goto over switch variable static assert(!__traits(compiles, (bool b) { if (b) goto label; switch(0) { default: break; case 0: int x; label: {} } })); // Goto into synchronized statement static assert(!__traits(compiles, (bool b) { if (b) goto label; synchronized { label: {} } })); // Goto into scope(success) with variable static assert(!__traits(compiles, (bool b) { scope(success) { int x; label: {} assert(!x); } if (b) goto label; })); // Goto into scope(failure) static assert(!__traits(compiles, (bool b) { if (b) goto label; scope(failure) { label: {} } })); // Goto into scope(failure) with variable static assert(!__traits(compiles, (bool b) { scope(failure) { int x; label: {} assert(!x); } if (b) goto label; })); // Goto into scope(exit) static assert(!__traits(compiles, (bool b) { if (b) goto label; scope(exit) { label: {} } })); // Goto into scope(exit) static assert(!__traits(compiles, (bool b) { scope(exit) { label: {} } if (b) goto label; })); // Goto into scope(exit) with variable static assert(!__traits(compiles, (bool b) { scope(exit) { int x; label: {} assert(!x); } if (b) goto label; })); /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=11659 int test11659() { goto LABEL; enum expr = "0"; LABEL: return mixin(expr); } /***************************************************/ // https://issues.dlang.org/show_bug.cgi?id=13321 void test13321(bool b) { static struct Foo { this(int) {} } Foo x; if (b) goto EXIT; x = Foo(1); EXIT: }