@safe: unittest { struct OpApply { int delegate(int) @safe myDlg; int opApply(int delegate(int) @safe dlg) { myDlg = dlg; return 0; } } struct Foo { OpApply o; int i; this(int x) { o = OpApply(); foreach(_; o) { i = 0; } i = x; } int call(int delegate(int) @safe dlg) { dlg(0); return i; } } auto foo1 = Foo(1); auto foo2 = Foo(2); import std.stdio; writeln(foo2.call(foo1.o.myDlg)); } Crashes with a seg-fault. This is apparently due to abuse of opApply, letting the delegate escape its scope, being considered @safe ?
I think foreach on delegates (opApply or delegates) should require the delegate parameter to be marked "scope" since it really must not escape.
Wow, that's pretty evil :) opApply is showing its age here.
When I compile and run it, it prints: 2 and does not crash. What compiler/system are you using?
dmd --version && dmd -unittest -main -run test17423.d DMD64 D Compiler v2.074.0 Copyright (c) 1999-2017 by Digital Mars written by Walter Bright /tmp/dmd_rundz8iAQ(_D4core7runtime18runModuleUnitTestsUZ19unittestSegvHandlerUNbiPS4core3sys5posix6signal9siginfo_tPvZv+0x38)[0x443804] /lib/x86_64-linux-gnu/libpthread.so.0(+0x11390)[0x7f76b6ce1390] Error: program killed by signal 11
DPaste and I can confirm the segfault: https://dpaste.dzfl.pl/c678a3ce7bf2
The opApply is actually working correctly. The bug is that the dlg parameter was incorrectly inferred as `scope`.
https://github.com/dlang/dmd/pull/7999
(In reply to Walter Bright from comment #7) > https://github.com/dlang/dmd/pull/7999 For this to work, -dip1000 must be used.
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/9fbf0611d2ef4174597470834cb6e356f791468a fix Issue 17423 - pointer assignment to in member function is not accounted for https://github.com/dlang/dmd/commit/eee17da2ffd89093a2de2f7310ca01520cd49a64 Merge pull request #7999 from WalterBright/fix17423 fix Issue 17423 - pointer assignment to in member function is not ac… merged-on-behalf-of: Mike Franklin <JinShil@users.noreply.github.com>
This example actually works now, see https://github.com/dlang/dmd/pull/8408