aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gdc.test/runnable/testptrref.d
blob: 7255595cb57d2883fb03ee23856f850da52ea06f (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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

version(CRuntime_Microsoft)
{
    extern(C)
    {
        extern __gshared uint _DP_beg;
        extern __gshared uint _DP_end;
        extern __gshared uint _TP_beg;
        extern __gshared uint _TP_end;
    }
    alias _DPbegin = _DP_beg;
    alias _DPend = _DP_end;
    alias _TPbegin = _TP_beg;
    alias _TPend = _TP_end;

    __gshared void[] dataSection;
    shared static this()
    {
        import core.internal.traits : externDFunc;
        alias findImageSection = externDFunc!("rt.sections_win64.findImageSection",
                                              void[] function(string name) nothrow @nogc);
        dataSection = findImageSection(".data");
    }

    void[] tlsRange;
    static this()
    {
        import core.internal.traits : externDFunc;
        alias initTLSRanges = externDFunc!("rt.sections_win64.initTLSRanges",
                                              void[] function() nothrow @nogc);
        tlsRange = initTLSRanges();
    }

    version = ptrref_supported;
}
else version(Win32)
{
    extern(C)
    {
        extern __gshared void* _DPbegin;
        extern __gshared void* _DPend;
        extern __gshared uint _TPbegin;
        extern __gshared uint _TPend;
        extern int _tlsstart;
        extern int _tlsend;
    }

    void[] tlsRange;
    static this()
    {
		tlsRange = (cast(void*)&_tlsstart)[0.. cast(void*)&_tlsend - cast(void*)&_tlsstart];
	}

    version = ptrref_supported;
}

struct Struct
{
    int x;
    Struct* next;
}

class Class
{
    void* ptr;
}

struct Struc(T)
{
	static T vtls;
	static __gshared T vgshared;
}

__gshared Struct* gsharedStrctPtr2 = new Struct(7, new Struct(8, null));

int tlsInt;
void* tlsVar;

shared int sharedInt;
shared void* sharedVar;
__gshared void* gsharedVar;
__gshared void* gsharedVar2;
immutable int[] arr = [1, 2, 3];
string tlsStr;

__gshared Struct gsharedStrct;
Struct[3] tlsStrcArr;
Class tlsClss;

// expression initializers
string[] strArr = [ "a", "b" ];
__gshared Class gsharedClss = new Class;
__gshared Struct* gsharedStrctPtr = new Struct(7, new Struct(8, null));

debug(PRINT) import core.stdc.stdio;

void main()
{
    version(ptrref_supported)
        testRefPtr();
}

version(ptrref_supported):

bool findTlsPtr(const(void)* ptr)
{
    debug(PRINT) printf("findTlsPtr %p\n", ptr);
    for (uint* p = &_TPbegin; p < &_TPend; p++)
    {
        void* addr = tlsRange.ptr + *p;
        debug(PRINT) printf("  try %p\n", addr);
        assert(*p < tlsRange.length);
        if (addr == ptr)
            return true;
    }
    return false;
}

bool findDataPtr(const(void)* ptr)
{
    debug(PRINT) printf("findDataPtr %p\n", ptr);
    for (auto p = &_DPbegin; p < &_DPend; p++)
    {
        debug(PRINT) printf("  try %p\n", cast(void*) cast(size_t) *p);
        version(CRuntime_Microsoft)
            void* addr = dataSection.ptr + *p;
        else
            void* addr = *p;

        if (addr == ptr)
            return true;
    }
    return false;
}

void testRefPtr()
{
    debug(PRINT) printf("&_DPbegin %p\n", &_DPbegin);
    debug(PRINT) printf("&_DPend   %p\n", &_DPend);

    debug(PRINT) printf("&_TPbegin %p\n", &_TPbegin);
    debug(PRINT) printf("&_TPend   %p\n", &_TPend);

    assert(!findDataPtr(cast(void*)&sharedInt));
    assert(!findTlsPtr(&tlsInt));

    assert(findDataPtr(cast(void*)&sharedVar));
    assert(findDataPtr(&gsharedVar));
    assert(findDataPtr(&gsharedStrct.next));
    assert(findDataPtr(&(gsharedClss)));
    assert(findDataPtr(&(gsharedClss.ptr)));

    assert(findTlsPtr(&tlsVar));
    assert(findTlsPtr(&tlsClss));
    assert(findTlsPtr(&tlsStrcArr[0].next));
    assert(findTlsPtr(&tlsStrcArr[1].next));
    assert(findTlsPtr(&tlsStrcArr[2].next));

    assert(!findTlsPtr(cast(size_t*)&tlsStr)); // length
    assert(findTlsPtr(cast(size_t*)&tlsStr + 1)); // ptr

    // monitor is manually managed
    assert(!findDataPtr(cast(size_t*)cast(void*)Class.classinfo + 1));
    assert(!findDataPtr(cast(size_t*)cast(void*)Class.classinfo + 1));

    assert(!findDataPtr(&arr));
    assert(!findTlsPtr(&arr));
    assert(!findDataPtr(cast(size_t*)&arr + 1));
    assert(!findTlsPtr(cast(size_t*)&arr + 1));

    assert(findDataPtr(cast(size_t*)&strArr[0] + 1)); // ptr in _DATA!
    assert(findDataPtr(cast(size_t*)&strArr[1] + 1)); // ptr in _DATA!
    strArr[1] = "c";

    assert(findDataPtr(&gsharedStrctPtr));
    assert(findDataPtr(&gsharedStrctPtr.next));
    assert(findDataPtr(&gsharedStrctPtr.next.next));

    assert(findDataPtr(&(Struc!(int*).vgshared)));
    assert(!findDataPtr(&(Struc!(int).vgshared)));
    assert(findTlsPtr(&(Struc!(int*).vtls)));
    assert(!findTlsPtr(&(Struc!(int).vtls)));
}