Bug 13850 – mixin template accepts delegates as function parameters

Status
RESOLVED
Resolution
DUPLICATE
Severity
major
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-12-10T10:39:24Z
Last change time
2023-03-30T14:49:13Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
Marc Schütz

Comments

Comment #0 by schuetzm — 2014-12-10T10:39:24Z
Reported by Vlasov Roman: http://forum.dlang.org/thread/[email protected] import std.stdio; mixin template Template(void function() func1, void function() func2) { void to() { func1(); func2(); } }; class SomeClass { mixin Template!(&func, &func23); void func() { writeln("First function!"); } void func23() { writeln("First function!"); } void toTemplate() { to(); } } void main() { SomeClass a = new SomeClass(); a.toTemplate(); } This compiles, but segfaults at runtime, because the delegates &func and &func23 are evidently passed to Template as function pointers.
Comment #1 by razvan.nitu1305 — 2023-03-29T14:03:05Z
I cannot reproduce this. The code compiles, runs and exits gracefully.
Comment #2 by maxsamukha — 2023-03-29T15:35:00Z
(In reply to RazvanN from comment #1) > I cannot reproduce this. The code compiles, runs and exits gracefully. How does this even work? Implicitly binding the function pointers to `this` is an extremely confusing semantics. Rather than stacking yet another hack on top of the pile, we'd better fix the underlying issue, which is member functions having invalid types.
Comment #3 by salihdb — 2023-03-29T22:13:04Z
No problem: alias T = string; alias fun = T function(); template Fun(fun funA, fun funB) {  void print() {    import std.stdio : writeln;    funA().writeln;    funB().writeln; } } template Hun() { void print() {    import std.stdio : writeln;    foo().writeln;    bar().writeln; } } struct S {  //mixin Fun!(&foo, &bar);/*/  mixin Hun;//*/   T foo() => "First"; T bar() => "Second"; } void main() {  S s; s.print(); }
Comment #4 by salihdb — 2023-03-29T22:40:12Z
(In reply to Max Samukha from comment #2) > ... stacking yet another hack > on top of the pile, we'd better fix the underlying issue, which is member > functions having invalid types. You are right, because there is alias!
Comment #5 by maxsamukha — 2023-03-30T06:33:38Z
(In reply to Salih Dincer from comment #4) > You are right, because there is alias! I am not sure what you mean exactly, but functions passed by alias are correctly rejected if they are used in a wrong context. Consider: mixin template Template(void function() func1, alias func2) { static void foo() { func1(); // UB // func2(); // This fails to compile } }; class SomeClass { int x; mixin Template!(&func23); void func23() { x = 1; } } void main() { SomeClass a = new SomeClass; a.foo(); assert(a.x == 1); // Fails } I am reopening this. Local function types have been an embarrassment for decades and should be fixed.
Comment #6 by maxsamukha — 2023-03-30T06:40:04Z
(In reply to Max Samukha from comment #5) > mixin Template!(&func23); Should be `mixin Template!(&func23, func23);`
Comment #7 by razvan.nitu1305 — 2023-03-30T08:39:14Z
Well, what we are seeing here is just another manifestation of 3720: https://issues.dlang.org/show_bug.cgi?id=3720 . The underlying issue is that when you take the address of a member function that is not attached to an instance, the pointer of the function (in the .txt) section is returned. The type is not a delegate because it was intended to be used in conjunction with the .funcptr and .ptr properties of delegates (you can take the address of some delegate as a function pointer and set it as the funcptr of another delegate). I'm saying this is a good design, I am just stating what the situation is. In this context, the code compiles because the function are not using any instance members therefore the context pointer, even though it is garbage it is not used at all. If you add a member to the class and try to access it in those functions you will probably get a segfault. I am inclined to close this as a dupe of 3720, as fixing that will most likely fix this case also.
Comment #8 by maxsamukha — 2023-03-30T09:43:22Z
(In reply to RazvanN from comment #7) > Well, what we are seeing here is just another manifestation of 3720: > https://issues.dlang.org/show_bug.cgi?id=3720 . > > I am inclined to close this as a dupe of 3720, as fixing that will most > likely fix this case also. Yes, I agree.
Comment #9 by razvan.nitu1305 — 2023-03-30T14:49:13Z
*** This issue has been marked as a duplicate of issue 3720 ***