aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/compilable/shared.d
blob: 695083a5476e90a515e2735cc706a3dcee718a28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* REQUIRED_ARGS: -preview=nosharedaccess
TEST_OUTPUT:
---
pure nothrow @nogc ref @safe shared(C1)(return ref shared(C1) c)
pure nothrow @nogc ref @safe shared(int)(return ref shared(C3) c)
---
*/
ref shared(int) f(return shared ref int y)
{
    return y;
}

// https://issues.dlang.org/show_bug.cgi?id=20908
void test20908()
{
  // shared locals (or struct members) should be able to be initialised:
  shared int x;

  ref shared(int) fun()
  {
    static shared(int) val;

    // return by reference
    return val;
  }

  ref shared(int) fun2()
  {
    static shared(int)* val;

    // transfer pointer to reference
    return *val;
  }

  ref shared(int) fun3()
  {
    static shared(int)*** val;

    // Multiple indirections
    return ***val;
  }
}

// Simple tests for `DotVarExp`
// A `DotVarExp` is `a.b`. If `a` is a `shared ref`,
// it is of type `shared(T)*` (as opposed to `shared(T*)`).
// We should allow arbitrarily nested `DotVarExp` as long
// as no shared memory is read, as in the case above
// (we're just offsetting a pointer).
struct C1
{
    int value;
}

struct C2
{
    C1 c1;
}

struct C3
{
    C2 c1;
    C2 c2;
}

ref shared(int) test_dotvarexp_1(return ref shared C1 c)
{
    return c.value;
}

shared(int)* test_dotvarexp_2(return ref shared C1 c)
{
    return &c.value;
}

shared(C2)* test_dotvarexp_3(return ref shared C3 c)
{
    return &c.c1;
}

shared(C2)* test_dotvarexp_4(return ref shared C3 c)
{
    return &c.c2;
}

ref shared(int) test_dotvarexp_5(return shared ref C3 c)
{
    return c.c1.c1.value;
}

ref shared(int) test_dotvarexp_5(return ref shared(C3)[] c)
{
    return c[0].c1.c1.value;
}

// Test `auto` inference
auto ref test_inference_1(return ref shared C1 c)
{
    return c;
}

pragma(msg, typeof(test_inference_1));

auto ref test_inference_2(return ref shared C3 c)
{
    return c.c2.c1.value;
}

pragma(msg, typeof(test_inference_2));

// https://issues.dlang.org/show_bug.cgi?id=21793

struct Child
{
    this(int) shared {}
}

struct Parent
{
    shared Child ch;
    this(int i) shared
    {
        ch = shared Child(i);
    }
}

// https://issues.dlang.org/show_bug.cgi?id=23732
class Class {}
void main()
{
    auto b = new shared Class();
}