www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 21496] New: Implicitly nested templated functions can be


          Issue ID: 21496
           Summary: Implicitly nested templated functions can be assigned
                    to function variables instead of delegates
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: bradley.chatha gmail.com

Relevant forum post:
https://forum.dlang.org/thread/hhgozkijvliyehnsbsay forum.dlang.org

Marked as Major as I believe this is a large error in D's safety and

The following code:

// https://godbolt.org/z/j8f3x5
struct C
    int a;

alias Func = void function(ref string);
void doShizz(alias _)(ref string a)
    a = "Hello!";

static void staticShizz(alias _)(ref string a)
    a = "Hello!";

void main()
    import std;
    string s;

    // Alias to member field causes the compiler to insert a context pointer.
    // doShizz!(C.a)(s); Error: need this for doShizz of type pure nothrow
 nogc  safe void(ref string a)

    // However, it's still treated like a normal function, so this works...
    Func f = &doShizz!(C.a);
    f(s); // Uh Oh: Compiles.

    writefln("ptr: %X | length: %s", s.ptr, s.length); // ptr: 0 | length: 0

    // But if we mark it static...
    writefln("ptr: %X | length: %s", s.ptr, s.length); // ptr: [omitted] |
length: 6

Shows that even though `doShizz` becomes implicitly nested inside of `struct
C`, meaning that it has a context pointer inserted into its parameters, the
compiler is allowing this "function" to be assignable to a `function` variable.

And as you can see, it produces unexpected behaviour when called.

Unless I'm missing something even more obscure about this behavior, the
compiler should not be allowing the `Func f = &doShizz` assignment.

Dec 20 2020