1 /*
2 REQUIRED_ARGS: -dip1000
3 PERMUTE_ARGS:
4 TEST_OUTPUT:
5 ---
6 fail_compilation/retscope.d(23): Error: scope variable `p` may not be returned
7 fail_compilation/retscope.d(33): Error: returning `b ? nested1(& i) : nested2(& j)` escapes a reference to local variable `j`
8 fail_compilation/retscope.d(46): Error: scope variable `p` assigned to non-scope `q`
9 fail_compilation/retscope.d(48): Error: address of variable `i` assigned to `q` with longer lifetime
10 fail_compilation/retscope.d(49): Error: variadic variable `a` assigned to non-scope `b`
11 fail_compilation/retscope.d(50): Error: reference to stack allocated value returned by `(*fp2)()` assigned to non-scope `q`
12 ---
13 */
14
15
16
17
foo1(return scope int * p)18 int* foo1(return scope int* p) { return p; } // ok
19
foo2()20 int* foo2()(scope int* p) { return p; } // ok, 'return' is inferred
21 alias foo2a = foo2!();
22
foo3(scope int * p)23 int* foo3(scope int* p) { return p; } // error
24
foo4(bool b)25 int* foo4(bool b)
26 {
27 int i;
28 int j;
29
30 int* nested1(scope int* p) { return null; }
31 int* nested2(return scope int* p) { return p; }
32
33 return b ? nested1(&i) : nested2(&j);
34 }
35
36 /************************************************/
37
38 struct S2 { int a,b,c,d; }
39
40 @safe S2 function() fp2;
41
test2(scope int * p,int[]a...)42 void test2(scope int* p, int[] a ...) @safe
43 {
44 static int* q;
45 static int[] b;
46 q = p;
47 int i;
48 q = &i;
49 b = a;
50 q = &fp2().d;
51 }
52
53 /**************************************************/
54
55 /*
56 TEST_OUTPUT:
57 ---
58 fail_compilation/retscope.d(76): Error: function retscope.HTTP.Impl.onReceive is @nogc yet allocates closures with the GC
59 fail_compilation/retscope.d(78): retscope.HTTP.Impl.onReceive.__lambda1 closes over variable this at fail_compilation/retscope.d(76)
60 ---
61 */
62
63
64 struct Curl
65 {
66 int delegate() dg;
67 }
68
69 struct HTTP
70 {
71 struct Impl
72 {
73 Curl curl;
74 int x;
75
onReceiveImpl76 @nogc void onReceive()
77 {
78 auto dg = ( ) { return x; };
79 curl.dg = dg;
80 }
81 }
82 }
83
84 /***********************************************/
85
86 /*
87 TEST_OUTPUT:
88 ---
89 fail_compilation/retscope.d(97): Error: reference to local variable `sa` assigned to non-scope parameter `a` calling retscope.bar8
90 ---
91 */
92 // https://issues.dlang.org/show_bug.cgi?id=8838
93
94 int[] foo8() @safe
95 {
96 int[5] sa;
97 return bar8(sa);
98 }
99
100 int[] bar8(int[] a) @safe
101 {
102 return a;
103 }
104
105
106 /*************************************************/
107
108 /*
109 TEST_OUTPUT:
110 ---
111 fail_compilation/retscope.d(124): Error: returning `foo9(cast(char[])tmp)` escapes a reference to local variable `tmp`
112 ---
113 */
114
115 char[] foo9(return char[] a) @safe pure nothrow @nogc
116 {
117 return a;
118 }
119
120 char[] bar9() @safe
121 {
122 char[20] tmp;
123 foo9(tmp); // ok
124 return foo9(tmp); // error
125 }
126
127 /*************************************************/
128
129 /*
130 //
131 //
132 //fail_compilation/retscope.d(143): To enforce @safe compiler allocates a closure unless the opApply() uses 'scope'
133 //
134 */
135
136 struct S10
137 {
138 static int opApply(int delegate(S10*) dg);
139 }
140
141 S10* test10()
142 {
143 foreach (S10* m; S10)
144 return m;
145 return null;
146 }
147
148 /************************************************/
149
150 /*
151 TEST_OUTPUT:
152 ---
153 fail_compilation/retscope.d(159): Error: scope variable `this` may not be returned
154 ---
155 */
156
157 class C11
158 {
159 @safe C11 foo() scope { return this; }
160 }
161
162
163 /****************************************************/
164
165 /*
166 TEST_OUTPUT:
167 ---
168 fail_compilation/retscope.d(178): Error: address of variable `i` assigned to `p` with longer lifetime
169 ---
170 */
171
172
173
174 void foo11() @safe
175 {
176 int[] p;
177 int[3] i;
178 p = i[];
179 }
180
181 /************************************************/
182 /*
183 TEST_OUTPUT:
184 ---
185 fail_compilation/retscope.d(198): Error: scope variable `e` may not be returned
186 ---
187 */
188
189 struct Escaper
190 {
191 void* DG;
192 }
193
194 void* escapeDg1(scope void* d) @safe
195 {
196 Escaper e;
197 e.DG = d;
198 return e.DG;
199 }
200
201 /*************************************************/
202 /*
203 TEST_OUTPUT:
204 ---
205 fail_compilation/retscope.d(213): Error: scope variable `p` assigned to non-scope `e`
206 ---
207 */
208 struct Escaper3 { void* e; }
209
210 void* escape3 (scope void* p) @safe {
211 Escaper3 e;
212 scope dg = () { return e.e; };
213 e.e = p;
214 return dg();
215 }
216
217 /**************************************************/
218
219 /*
220 TEST_OUTPUT:
221 ---
222 fail_compilation/retscope.d(230): Error: scope variable `ptr` may not be returned
223 ---
224 */
225
226 alias dg_t = void* delegate () return scope @safe;
227
228 void* funretscope(scope dg_t ptr) @safe
229 {
230 return ptr();
231 }
232
233 /*****************************************************/
234
235 /*
236 TEST_OUTPUT:
237 ---
238 fail_compilation/retscope.d(249): Error: cannot implicitly convert expression `__lambda1` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`
239 fail_compilation/retscope.d(249): Error: cannot implicitly convert expression `__lambda1` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`
240 fail_compilation/retscope.d(250): Error: cannot implicitly convert expression `__lambda2` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`
241 fail_compilation/retscope.d(250): Error: cannot implicitly convert expression `__lambda2` of type `void* delegate() pure nothrow @nogc return @safe` to `void* delegate() @safe`
242 ---
243 */
244
245 void escape4() @safe
246 {
247 alias FunDG = void* delegate () @safe;
248 int x = 42;
249 scope FunDG f = () return { return &x; };
250 scope FunDG g = () { return &x; };
251 }
252
253 /**************************************************/
254
255 /*
256 TEST_OUTPUT:
257 ---
258 fail_compilation/retscope.d(267): Error: cannot take address of scope local p in @safe function escape5
259 ---
260 */
261
262 void escape5() @safe
263 {
264 int* q;
265 scope int* p;
266 scope int** pp = &q; // ok
267 pp = &p; // error
268 }
269
270 /***********************************************/
271
272 /*
273 TEST_OUTPUT:
274 ---
275 fail_compilation/retscope.d(287): Error: returning `foo6(& b)` escapes a reference to local variable `b`
276 ---
277 */
278
279 @safe int* foo6()(int* arg)
280 {
281 return arg;
282 }
283
284 int* escape6() @safe
285 {
286 int b;
287 return foo6(&b);
288 }
289
290 /***************************************************/
291
292 struct S7
293 {
294 int[10] a;
295 int[3] abc(int i) @safe
296 {
297 return a[0 .. 3]; // should not error
298 }
299 }
300
301 /***************************************************/
302
303 int[3] escape8(scope int[] p) @safe { return p[0 .. 3]; } // should not error
304 char*[3] escape9(scope char*[] p) @safe { return p[0 .. 3]; }
305
306 /***************************************************/
307
308 /*
309 TEST_OUTPUT:
310 ---
311 fail_compilation/retscope.d(320): Error: reference to local variable `i` assigned to non-scope `f`
312 ---
313 */
314
315 int* escape10() @safe
316 {
317 int i;
318 int* f;
319 scope int** x = &f;
320 f = &i;
321
322 return bar10(x);
323 }
324
325 int* bar10( scope int** ptr ) @safe
326 {
327 return *ptr;
328 }
329
330 /******************************************/
331
332 /*
333 TEST_OUTPUT:
334 ---
335 fail_compilation/retscope.d(343): Error: cannot take address of scope local aa in @safe function escape11
336 ---
337 */
338
339 int* escape11() @safe
340 {
341 int i;
342 int*[3] aa = [ &i, null, null ];
343 return bar11(&aa[0]);
344 }
345
346 int* bar11(scope int** x) @safe
347 {
348 return foo11(*x);
349 }
350
351 int* foo11(int* x) @safe { return x; }
352
353 /******************************************/
354
355 void escape15() @safe
356 {
357 int arg;
358 const(void)*[1] argsAddresses;
359 argsAddresses[0] = // MUST be an array assignment
360 (ref arg)@trusted{ return cast(const void*) &arg; }(arg);
361 }
362
363 /******************************************/
364 /*
365 TEST_OUTPUT:
366 ---
367 fail_compilation/retscope.d(1003): Error: returning `f.foo()` escapes a reference to local variable `f`
368 ---
369 */
370
371 #line 1000
372 int* escape12() @safe
373 {
374 Foo12 f;
375 return f.foo;
376 }
377
378 struct Foo12
379 {
380 int* foo() return @safe;
381 }
382
383 /******************************************/
384 /*
385 TEST_OUTPUT:
386 ---
387 fail_compilation/retscope.d(1103): Error: scope variable `f` may not be returned
388 ---
389 */
390
391 #line 1100
392 int* escape13() @safe
393 {
394 scope Foo13 f;
395 return f.foo;
396 }
397
398 class Foo13
399 {
400 int* foo() return @safe;
401 }
402
403 /******************************************/
404 /*
405 TEST_OUTPUT:
406 ---
407 fail_compilation/retscope.d(1205): Error: scope variable `f14` assigned to non-scope parameter `this` calling retscope.Foo14.foo
408 ---
409 */
410
411 #line 1200
412 int* escape14() @safe
413 {
414 int i;
415 Foo14 f14;
416 f14.v = &i;
417 return f14.foo;
418 }
419
420 struct Foo14
421 {
422 int* v;
423 int* foo () @safe { return this.v; }
424 }
425
426 /******************************************/
427 /*
428 TEST_OUTPUT:
429 ---
430 fail_compilation/retscope.d(1311): Error: scope variable `u2` assigned to `ek` with longer lifetime
431 ---
432 */
433
434 #line 1300
435 @safe struct U13 {
436 int* k;
437 int* get() return scope { return k; }
438 static int* sget(return scope ref U13 u) { return u.k; }
439 }
440
441 @safe void foo13() {
442 int* ek;
443
444 int i;
445 auto u2 = U13(&i);
446 ek = U13.sget(u2); // Error: scope variable u2 assigned to ek with longer lifetime
447
448 auto u1 = U13(new int);
449 ek = u1.get(); // ok
450 ek = U13.sget(u1); // ok
451 }
452
453 /************************************************/
454
455 /*
456 TEST_OUTPUT:
457 ---
458 fail_compilation/retscope.d(1405): Error: reference to local variable `buf` assigned to non-scope parameter `unnamed` calling retscope.myprintf
459 ---
460 */
461
462 #line 1400
463 @trusted extern(C) int myprintf(const(char)*, ...);
464
465 @safe void foo14()
466 {
467 char[4] buf = [ 'h', 'i', '\n', 0 ];
468 myprintf(&buf[0]);
469 }
470
471 /************************************************/
472
473 /*
474 TEST_OUTPUT:
475 ---
476 fail_compilation/retscope.d(1509): Error: reference to stack allocated value returned by `(*fp15)()` assigned to non-scope parameter `unnamed`
477 ---
478 */
479
480 #line 1500
481
482 @safe void bar15(int*);
483
484 struct S15 { int a,b,c,d; }
485
486 @safe S15 function() fp15;
487
488 void test15() @safe
489 {
490 bar15(&fp15().d);
491 }
492
493
494 /*************************************************/
495
496 void foo16() @nogc nothrow
497 {
498 alias dg_t = string delegate(string) @nogc nothrow;
499
500 dg_t dg = (string s) => s;
501 }
502
503 /*************************************************/
504
505 /*
506 TEST_OUTPUT:
507 ---
508 fail_compilation/retscope.d(1701): Error: cannot implicitly convert expression `& func` of type `int* function(int* p)` to `int* function(scope int* p)`
509 fail_compilation/retscope.d(1702): Error: cannot implicitly convert expression `& func` of type `int* function(int* p)` to `int* function(return scope int* p)`
510 fail_compilation/retscope.d(1703): Error: cannot implicitly convert expression `& func` of type `int* function(int* p)` to `int* function(return scope int* p)`
511 fail_compilation/retscope.d(1711): Error: cannot implicitly convert expression `& funcr` of type `int* function(return scope int* p)` to `int* function(scope int* p)`
512 fail_compilation/retscope.d(1716): Error: cannot implicitly convert expression `& funcrs` of type `int* function(return scope int* p)` to `int* function(scope int* p)`
513 ---
514 */
515
516 int* func(int* p);
517 int* funcs(scope int* p);
518 int* funcr(return int* p);
519 int* funcrs(return scope int* p);
520
521 void foo17()
522 {
523 #line 1700
524 typeof(func) *fp1 = &func;
525 typeof(funcs) *fp2 = &func; // error
526 typeof(funcr) *fp3 = &func; // error
527 typeof(funcrs) *fp4 = &func; // error
528
529 typeof(func) *fq1 = &funcs;
530 typeof(funcs) *fq2 = &funcs;
531 typeof(funcr) *fq3 = &funcs;
532 typeof(funcrs) *fq4 = &funcs;
533
534 typeof(func) *fr1 = &funcr;
535 typeof(funcs) *fr2 = &funcr; // error
536 typeof(funcr) *fr3 = &funcr;
537 typeof(funcrs) *fr4 = &funcr;
538
539 typeof(func) *fs1 = &funcrs;
540 typeof(funcs) *fs2 = &funcrs; // error
541 typeof(funcr) *fs3 = &funcrs;
542 typeof(funcrs) *fs4 = &funcrs;
543 }
544
545 /*************************************************/
546
547 /*
548 TEST_OUTPUT:
549 ---
550 fail_compilation/retscope.d(1801): Error: cannot implicitly convert expression `&c.func` of type `int* delegate()` to `int* delegate() scope`
551 fail_compilation/retscope.d(1802): Error: cannot implicitly convert expression `&c.func` of type `int* delegate()` to `int* delegate() return scope`
552 fail_compilation/retscope.d(1803): Error: cannot implicitly convert expression `&c.func` of type `int* delegate()` to `int* delegate() return scope`
553 fail_compilation/retscope.d(1811): Error: cannot implicitly convert expression `&c.funcr` of type `int* delegate() return scope` to `int* delegate() scope`
554 fail_compilation/retscope.d(1816): Error: cannot implicitly convert expression `&c.funcrs` of type `int* delegate() return scope` to `int* delegate() scope`
555 ---
556 */
557
558 class C18
559 {
560 int* func();
561 int* funcs() scope;
562 int* funcr() return;
563 int* funcrs() return scope;
564 }
565
566 void foo18()
567 {
568 C18 c;
569
570 #line 1800
571 typeof(&c.func) fp1 = &c.func;
572 typeof(&c.funcs) fp2 = &c.func; // error
573 typeof(&c.funcr) fp3 = &c.func; // error
574 typeof(&c.funcrs) fp4 = &c.func; // error
575
576 typeof(&c.func) fq1 = &c.funcs;
577 typeof(&c.funcs) fq2 = &c.funcs;
578 typeof(&c.funcr) fq3 = &c.funcs;
579 typeof(&c.funcrs) fq4 = &c.funcs;
580
581 typeof(&c.func) fr1 = &c.funcr;
582 typeof(&c.funcs) fr2 = &c.funcr; // error
583 typeof(&c.funcr) fr3 = &c.funcr;
584 typeof(&c.funcrs) fr4 = &c.funcr;
585
586 typeof(&c.func) fs1 = &c.funcrs;
587 typeof(&c.funcs) fs2 = &c.funcrs; // error
588 typeof(&c.funcr) fs3 = &c.funcrs;
589 typeof(&c.funcrs) fs4 = &c.funcrs;
590 }
591
592 /*********************************************/
593
594 @safe void foo19(C)(ref C[] str) // infer 'scope' for 'str'
595 {
596 str = str;
597 str = str[1 .. str.length];
598 }
599
600 @safe void test19()
601 {
602 char[10] s;
603 char[] t = s[];
604 foo19(t);
605 }
606
607 /********************************************/
608
609
610 bool foo20(const string a) @safe pure nothrow @nogc
611 {
612 return !a.length;
613 }
614
615 struct Result(R)
616 {
617 R source;
618
619 bool empty() // infer 'scope' for 'this'
620 { return foo20(source); }
621 }
622
623 @safe void test20()
624 {
625 scope n = Result!string("abc");
626 n.empty();
627 }
628
629 /************************************************/
630
631 // https://issues.dlang.org/show_bug.cgi?id=17117
632
633 ref int foo21(return ref int s)
634 {
635 return s;
636 }
637
638 int fail21()
639 {
640 int s;
641 return foo21(s); // Error: escaping reference to local variable s
642 }
643
644 int test21()
645 {
646 int s;
647 s = foo21(s);
648 return s;
649 }
650
651 /**********************************************/
652
653 @safe void foo22()(ref char[] s)
654 {
655 char[] a = s;
656 }
657
658 @safe void test22(scope char[] s)
659 {
660 foo22(s);
661 }
662
663