digitalmars.D.bugs - [Issue 17764] New: [scope][DIP1000] Escape checker defeated by
- via Digitalmars-d-bugs (125/125) Aug 19 2017 https://issues.dlang.org/show_bug.cgi?id=17764
https://issues.dlang.org/show_bug.cgi?id=17764 Issue ID: 17764 Summary: [scope][DIP1000] Escape checker defeated by composition transformations Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: major Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: petar.p.kirov gmail.com At first I was about to name this issue "The compiler treats 'scope ref T' and 'scope ref T[1]' differently" (see `use0x3()` and `use0x4()`), but then I decided to dig a little more, so here's what I've found so far: $ cat > scope_bug.d << DBUG safe: struct Context0x0 { char[] str; } struct Parent0x1 { Context0x0 c; } struct Parent0x2 { Context0x0[1] csa; } struct Parent0x3 { Context0x0[] csl; } struct Parent0x4 { Context0x0* cp; } struct Parent0x5 { Parent0x1 p1; } struct Parent0x6 { Parent0x5 p5; } struct Parent0x7 { Parent0x6 p6; } struct Parent0x8 { Parent0x2[1]* p2; } struct Parent0x9 { Parent0x8[1] p8; } struct Parent0xA { Parent0x9[1] p9; } struct Parent0xB { Parent0x4* p4; } struct Parent0xC { Parent0xB* pb; } struct Parent0xD { Parent0xC* pc; } void main() { char[16] buf; use0x0(buf); char[] charSlice = buf; use0x1(charSlice); // use0x2(&charSlice); // NG - rejects valid Context0x0[1] c = Context0x0(charSlice); use0x3(c[0]); use0x4(c); use0x5(c); auto p1 = Parent0x1(c[0]); use0x6(p1); auto p2 = Parent0x2(c); use0x7(p2); Context0x0[] contextSlice = c[]; auto p3 = Parent0x3(contextSlice); use0x8(p3); auto p4 = Parent0x4(&c[0]); use0x9(p4); auto p5 = Parent0x7(Parent0x6(Parent0x5(p1))); use0xA(p5); Parent0x2[1] p2sa = Parent0x2(c); Parent0xA p6 = Parent0xA(Parent0x9(Parent0x8(&p2sa))); use0xB(p6); // auto pbAttemp1 = Parent0xB(&p4); // NG - rejects valid Parent0x4[1] p4WorkAround = Parent0x4(&c[0]); Parent0xB[1] pb = Parent0xB(&p4WorkAround[0]); Parent0xC[1] pc = Parent0xC(&pb[0]); Parent0xD[1] pd = Parent0xD(&pc[0]); use0xC(pd[0]); } char[] global; void use0x0(scope char[] arr) { // global = arr; // OK - this does not compile } void use0x1(scope ref char[] arr) { // global = arr; // OK - this does not compile } void use0x2(scope char[]* arr) { global = *arr; // NG - accepts invalid } void use0x3(scope ref Context0x0 c) { // global = c.str; // OK - this does not compile } void use0x4(scope ref Context0x0[1] c) { global = c[0].str; // NG - accepts invalid } void use0x5(scope Context0x0[] c) { global = c[0].str; // NG - accepts invalid } void use0x6(scope ref Parent0x1 p) { // global = p.c.str; // OK - this does not compile } void use0x7(scope ref Parent0x2 p) { global = p.csa[0].str; // NG - accepts invalid } void use0x8(scope ref Parent0x3 p) { global = p.csl[0].str; // NG - accepts invalid } void use0x9(scope ref Parent0x4 p) { global = p.cp.str; // NG - accepts invalid } void use0xA(scope ref Parent0x7 p) { // global = p.p6.p5.p1.c.str; // OK - this does not compile } void use0xB(scope ref Parent0xA p) { global = (*p.p9[0].p8[0].p2)[0].csa[0].str; // NG - accepts invalid } void use0xC(scope ref Parent0xD p) { global = p.pc.pb.p4.cp.str; // NG - accepts invalid } DBUG $ dmd -dip1000 scope_bug.d scope_bug.d(11): Error: cannot take address of scope local c in safe function main $ dmd --version DMD64 D Compiler v2.076.0-b1-master-32bb4ed --
Aug 19 2017