Bug 21496 – Implicitly nested templated functions can be assigned to function variables instead of delegates

Status
NEW
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-12-20T15:11:07Z
Last change time
2024-12-13T19:13:33Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
bradley.chatha
Moved to GitHub: dmd#19842 →

Comments

Comment #0 by bradley.chatha — 2020-12-20T15:11:07Z
Relevant forum post: https://forum.dlang.org/thread/[email protected] Marked as Major as I believe this is a large error in D's safety and correctness. 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... staticShizz!(C.a)(s); 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.
Comment #1 by robert.schadek — 2024-12-13T19:13:33Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19842 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB