Skip to content

Commit c569c33

Browse files
Bolpat0xEAB
andcommitted
Make toDelegate safe for function pointers
Co-authored-by: Elias Batek <0xEAB@users.noreply.github.com>
1 parent ff25f6d commit c569c33

File tree

1 file changed

+37
-7
lines changed

1 file changed

+37
-7
lines changed

std/functional.d

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,13 +1814,42 @@ if (isCallable!(F))
18141814
{
18151815
return fp;
18161816
}
1817+
else static if (is(F Func == Func*) && is(Func == function) && is(Func Params == __parameters))
1818+
{
1819+
return () @trusted
1820+
{
1821+
return buildDelegate(fp);
1822+
}();
1823+
}
18171824
else static if (is(typeof(&F.opCall) == delegate)
18181825
|| (is(typeof(&F.opCall) V : V*) && is(V == function)))
18191826
{
18201827
return toDelegate(&fp.opCall);
18211828
}
18221829
else
18231830
{
1831+
return buildDelegate(fp);
1832+
}
1833+
}
1834+
1835+
///
1836+
@safe unittest
1837+
{
1838+
static int inc(ref uint num) {
1839+
num++;
1840+
return 8675309;
1841+
}
1842+
1843+
uint myNum = 0;
1844+
auto incMyNumDel = toDelegate(&inc);
1845+
auto returnVal = incMyNumDel(myNum);
1846+
assert(myNum == 1);
1847+
}
1848+
1849+
private template buildDelegate(F)
1850+
if (isCallable!(F))
1851+
{
1852+
auto buildDelegate(auto ref F fp) {
18241853
alias DelType = typeof(&(new DelegateFaker!(F)).doIt);
18251854

18261855
static struct DelegateFields {
@@ -1850,21 +1879,22 @@ if (isCallable!(F))
18501879
}
18511880
}
18521881

1853-
///
1854-
@system unittest
1882+
@safe unittest
18551883
{
18561884
static int inc(ref uint num) {
18571885
num++;
18581886
return 8675309;
18591887
}
18601888

1861-
uint myNum = 0;
1862-
auto incMyNumDel = toDelegate(&inc);
1863-
auto returnVal = incMyNumDel(myNum);
1864-
assert(myNum == 1);
1889+
uint myNum = 0x1337;
1890+
struct S1 { int opCall() { inc(myNum); return myNum; } }
1891+
static assert(!is(typeof(&s1.opCall) == delegate));
1892+
S1 s1;
1893+
auto getvals1 = toDelegate(s1);
1894+
assert(getvals1() == 0x1338);
18651895
}
18661896

1867-
@system unittest // not @safe due to toDelegate
1897+
@system unittest
18681898
{
18691899
static int inc(ref uint num) {
18701900
num++;

0 commit comments

Comments
 (0)