dmd/compiler/test/fail_compilation/retscope6.d
2025-01-10 17:52:17 +01:00

321 lines
7 KiB
D

/*
REQUIRED_ARGS: -preview=dip1000
*/
/*
TEST_OUTPUT:
---
fail_compilation/retscope6.d(6007): Error: escaping a reference to local variable `i` by copying `& i` into allocated memory is not allowed in a `@safe` function
---
*/
#line 6000
// https://issues.dlang.org/show_bug.cgi?id=17795
int* test() @safe
{
int i;
int*[][] arr = new int*[][](1);
arr[0] ~= &i;
return arr[0][0];
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(7034): Error: assigning address of variable `i` to `s` with longer lifetime is not allowed in a `@safe` function
fail_compilation/retscope6.d(7035): Error: assigning address of variable `i` to `s` with longer lifetime is not allowed in a `@safe` function
fail_compilation/retscope6.d(7025): Error: assigning scope variable `__param_2` to `ref` variable `t` with longer lifetime is not allowed in a `@safe` function
fail_compilation/retscope6.d(7037): Error: template instance `retscope6.S.emplace4!(int*)` error instantiating
fail_compilation/retscope6.d(7037): Error: assigning address of variable `i` to `s` with longer lifetime is not allowed in a `@safe` function
---
*/
#line 7000
alias T = int*;
struct S
{
T payload;
static void emplace(Args...)(ref S s, Args args) @safe
{
s.payload = args[0];
}
void emplace2(Args...)(Args args) @safe
{
payload = args[0];
}
static void emplace3(Args...)(S s, Args args) @safe
{
s.payload = args[0];
}
static void emplace4(Args...)(scope ref S s, scope out S t, scope Args args) @safe
{
s.payload = args[0];
t.payload = args[0];
}
}
void foo() @safe
{
S s;
int i;
s.emplace(s, &i);
s.emplace2(&i);
s.emplace3(s, &i);
s.emplace4(s, s, &i);
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(8016): Error: assigning address of variable `i` to `p` with longer lifetime is not allowed in a `@safe` function
fail_compilation/retscope6.d(8031): Error: assigning reference to local variable `i` to non-scope parameter `p` calling `betty` is not allowed in a `@safe` function
fail_compilation/retscope6.d(8031): Error: assigning reference to local variable `j` to non-scope parameter `q` calling `betty` is not allowed in a `@safe` function
fail_compilation/retscope6.d(8023): which is not `scope` because of `p = q`
fail_compilation/retscope6.d(8048): Error: assigning reference to local variable `i` to non-scope parameter `p` calling `archie` is not allowed in a `@safe` function
fail_compilation/retscope6.d(8039): which is not `scope` because of `r = p`
fail_compilation/retscope6.d(8048): Error: assigning reference to local variable `j` to non-scope parameter `q` calling `archie` is not allowed in a `@safe` function
fail_compilation/retscope6.d(8038): which is not `scope` because of `p = q`
---
*/
// https://issues.dlang.org/show_bug.cgi?id=19035
#line 8000
@safe
{
void escape(int*);
/**********************/
void frank()(ref scope int* p, int* s)
{
p = s; // should error here
}
void testfrankly()
{
int* p;
int i;
frank(p, &i);
}
/**********************/
void betty()(int* p, int* q)
{
p = q;
escape(p);
}
void testbetty()
{
int i;
int j;
betty(&i, &j); // should error on i and j
}
/**********************/
void archie()(int* p, int* q, int* r)
{
p = q;
r = p;
escape(q);
}
void testarchie()
{
int i;
int j;
int k;
archie(&i, &j, &k); // should error on j
}
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(9023): Error: escaping a reference to local variable `i` by returning `fred(& i)` is not allowed in a `@safe` function
---
*/
#line 9000
@safe
{
alias T9 = S9!(); struct S9()
{
this(int* q)
{
this.p = q;
}
int* p;
}
auto fred(int* r)
{
return T9(r);
}
T9 testfred()
{
int i;
auto j = fred(&i); // ok
return fred(&i); // error
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(10003): Error: assigning scope variable `values` to non-scope parameter `values` calling `escape` is not allowed in a `@safe` function
---
*/
#line 10000
void variadicCaller(int[] values...)
{
escape(values);
}
void escape(int[] values) {}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(11004): Error: assigning address of variable `buffer` to `secret` with longer lifetime is not allowed in a `@safe` function
---
*/
#line 11000
void hmac(scope ubyte[] secret)
{
ubyte[10] buffer;
secret = buffer[];
}
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(12011): Error: escaping a reference to local variable `x` by returning `escape_m_20150(& x)` is not allowed in a `@safe` function
fail_compilation/retscope6.d(12022): Error: escaping a reference to local variable `x` by returning `escape_c_20150(& x)` is not allowed in a `@safe` function
---
*/
#line 12000
// https://issues.dlang.org/show_bug.cgi?id=20150
int* escape_m_20150(int* r) @safe pure nothrow
{
return r;
}
int* f_m_20150() @safe nothrow
{
int x = 42;
return escape_m_20150(&x);
}
const(int)* escape_c_20150(const int* r) @safe pure nothrow
{
return r;
}
const(int)* f_c_20150() @safe nothrow
{
int x = 42;
return escape_c_20150(&x);
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(13010): Error: assigning reference to local variable `str` to non-scope parameter `x` calling `f_throw` is not allowed in a `@safe` function
---
*/
#line 13000
// https://issues.dlang.org/show_bug.cgi?id=22221
void f_throw(string x) @safe pure
{
throw new Exception(x);
}
void escape_throw_20150() @safe
{
immutable(char)[4] str;
f_throw(str[]);
}
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(14019): Error: assigning scope variable `scopePtr` to non-scope parameter `x` calling `noInfer23021` is not allowed in a `@safe` function
fail_compilation/retscope6.d(14009): which is not `scope` because of `*escapeHole = cast(const(int)*)x`
fail_compilation/retscope6.d(14022): Error: returning scope variable `scopePtr` is not allowed in a `@safe` function
---
*/
#line 14000
// https://issues.dlang.org/show_bug.cgi?id=23021
ref int infer23021(ref int* x) @safe pure nothrow
{
return *x;
}
ref int noInfer23021(ref int* x, const(int)** escapeHole = null) @safe pure nothrow
{
*escapeHole = x;
return *x;
}
ref int escape23021() @safe
{
scope int* scopePtr;
int* nonScopePtr = null;
// don't infer scope
cast(void) noInfer23021(scopePtr); // error
// ensure we infer return scope
return infer23021(scopePtr); // error
// ensure we do not infer return ref
return infer23021(nonScopePtr); // no error
}
/******************************/
/* TEST_OUTPUT:
---
fail_compilation/retscope6.d(14050): Error: assigning scope variable `z` to non-scope parameter `y` calling `f23294` is not allowed in a `@safe` function
fail_compilation/retscope6.d(14044): which is not `scope` because of `x = y`
---
*/
// https://issues.dlang.org/show_bug.cgi?id=23294
@safe:
int g23294;
auto f23294(int* x, int* y)
{
x = y;
g23294++; // make sure it's not inferring scope from pure
}
void escape23294(scope int* z)
{
f23294(z, z); // passes
}