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