D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 10336 - Inconsistent call strategy and function behavior in member template opDispatch map to function delegate
Summary: Inconsistent call strategy and function behavior in member template opDispatc...
Status: RESOLVED DUPLICATE of issue 11545
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-06-11 10:09 UTC by Gabriel Garcia
Modified: 2013-11-18 17:56 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Gabriel Garcia 2013-06-11 10:09:55 UTC
DMD 2.063

Code:

struct test {
	template opDispatch(string name) {
		enum opDispatch = function(int x) {
			return x;
		};
	}
}

int main() {
	test t;
	
	return t.hello(12);
}

Output is consistently 0.
Comment 1 Gabriel Garcia 2013-06-11 12:20:03 UTC
(In reply to comment #0)
> DMD 2.063
> 
> Code:
> 
> struct test {
>     template opDispatch(string name) {
>         enum opDispatch = function(int x) {
>             return x;
>         };
>     }
> }
> 
> int main() {
>     test t;
> 
>     return t.hello(12);
> }
> 
> Output is consistently 0.

It appears that the caller is treating the method as a regular/static function, while the function itself is behaving as a method. This is perhaps more evident through the following D code and the corresponding (non-optimized) generated code:

struct test {
	int member = 32;
	
	template opDispatch(string name) {
		enum opDispatch = function(int x) {
			return x + member;
		};
	}
}

int main() {
	test t;
	
	return t.hello(12);
}


(OK) Expects EAX to point to an instance of test, with parameters pushed to stack:

pure nothrow @safe int test.test.opDispatch!("hello").__funcliteral1(int):
		push	EBP
		mov	EBP,ESP
		sub	ESP,4
		mov	EAX,[EAX]
		add	EAX,8[EBP]
		leave
		ret	4
		nop


(ERROR) Disregards it is dealing with a method call:

_Dmain:
		push	EBP
		mov	EBP,ESP
		mov	EAX,_D4test4test6__initZ@SYM32 ; what?
		mov	EAX,0Ch
		call	  pure nothrow @safe int test.test.opDispatch!("hello").__funcliteral1(int)@PC32
		pop	EBP
		ret


Expected:

_Dmain:
                push    EBP
                mov     EBP,ESP
; <begin missing>
                sub     ESP,4
                mov     EAX,_D4test4test6__initZ@SYM32
                mov     -4[EBP],EAX
                push    0Ch
                lea     EAX,-4[EBP]
; <end missing>
                call      pure nothrow @safe int test.test.opDispatch!("hello").__funcliteral1(int)@PC32
                leave
                ret
Comment 2 Gabriel Garcia 2013-11-18 17:56:25 UTC

*** This issue has been marked as a duplicate of issue 11545 ***