mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
321 lines
7 KiB
D
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
|
|
}
|