Bug 31 – Keyword 'function' and pointer test broken for IsExpression

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2006-03-10T00:01:00Z
Last change time
2014-02-14T20:33:28Z
Assigned to
bugzilla
Creator
sean

Comments

Comment #0 by sean — 2006-03-10T00:01:38Z
Given the documentation, I would expect all eight tests to pass, yet tests six and eight both fail. C:\code\d\bugs>type 149_1.d import std.c.stdio; template isPointer( T ) { const bool isPointer = is( T : T* ); } void main() { struct S {} union U {} class C {} interface I {} enum E { e } alias void function() fp; alias void delegate() dp; static if( is( S == struct ) ) printf( "1. struct passes\n" ); static if( is( U == union ) ) printf( "2. union passes\n" ); static if( is( C == class ) ) printf( "3. class passes\n" ); static if( is( I == interface ) ) printf( "4. interface passes\n" ); static if( is( E == enum ) ) printf( "5. enum passes\n" ); static if( is( fp == function ) ) printf( "6. function passes\n" ); static if( is( dp == delegate ) ) printf( "7. delegate passes\n" ); static if( isPointer!(int*) ) printf( "8. pointer passes\n" ); } C:\code\d\bugs>dmd 149_1.d C:\bin\dmd\bin\..\..\dm\bin\link.exe 149_1,,,user32+kernel32/noi; C:\code\d\bugs>149_1 1. struct passes 2. union passes 3. class passes 4. interface passes 5. enum passes 7. delegate passes C:\code\d\bugs>
Comment #1 by thomas-dloop — 2006-03-15T02:50:24Z
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 [email protected] schrieb am 2006-03-10: > Given the documentation, I would expect all eight tests to pass, yet tests six > and eight both fail. > > > C:\code\d\bugs>type 149_1.d > import std.c.stdio; > > template isPointer( T ) > { > const bool isPointer = is( T : T* ); > } > > void main() > { > struct S {} > union U {} > class C {} > interface I {} > enum E { e } > alias void function() fp; > alias void delegate() dp; > > static if( is( S == struct ) ) printf( "1. struct passes\n" ); > static if( is( U == union ) ) printf( "2. union passes\n" ); > static if( is( C == class ) ) printf( "3. class passes\n" ); > static if( is( I == interface ) ) printf( "4. interface passes\n" ); > static if( is( E == enum ) ) printf( "5. enum passes\n" ); > static if( is( fp == function ) ) printf( "6. function passes\n" ); > static if( is( dp == delegate ) ) printf( "7. delegate passes\n" ); > static if( isPointer!(int*) ) printf( "8. pointer passes\n" ); > } > C:\code\d\bugs>dmd 149_1.d > C:\bin\dmd\bin\..\..\dm\bin\link.exe 149_1,,,user32+kernel32/noi; > > C:\code\d\bugs>149_1 > 1. struct passes > 2. union passes > 3. class passes > 4. interface passes > 5. enum passes > 7. delegate passes Shouldn't isPointer be defined as: # template isPointer( T ){ # const bool isPointer = is( T : void* ); # } http://www.digitalmars.com/d/expression.html#IsExpression # is ( Type : TypeSpecialization ) # The condition is satisfied if Type is semantically correct and it is # the same as or can be implicitly converted to TypeSpecialization. Thus "is(T : T*)" is always false. Added to DStress as http://dstress.kuehne.cn/run/i/is_05_A.d http://dstress.kuehne.cn/run/i/is_05_B.d http://dstress.kuehne.cn/run/i/is_05_C.d http://dstress.kuehne.cn/run/i/is_05_D.d http://dstress.kuehne.cn/run/i/is_05_E.d http://dstress.kuehne.cn/run/i/is_05_F.d http://dstress.kuehne.cn/run/i/is_05_G.d http://dstress.kuehne.cn/run/i/is_05_H.d http://dstress.kuehne.cn/run/i/is_06_A.d http://dstress.kuehne.cn/run/i/is_06_B.d http://dstress.kuehne.cn/run/i/is_06_C.d http://dstress.kuehne.cn/run/i/is_06_D.d http://dstress.kuehne.cn/run/i/is_06_E.d http://dstress.kuehne.cn/run/i/is_06_F.d http://dstress.kuehne.cn/run/i/is_06_G.d http://dstress.kuehne.cn/run/i/is_06_H.d http://dstress.kuehne.cn/run/i/is_07_A.d http://dstress.kuehne.cn/run/i/is_07_B.d http://dstress.kuehne.cn/run/i/is_07_C.d http://dstress.kuehne.cn/run/i/is_07_D.d http://dstress.kuehne.cn/run/i/is_07_E.d http://dstress.kuehne.cn/run/i/is_07_F.d http://dstress.kuehne.cn/run/i/is_07_G.d http://dstress.kuehne.cn/run/i/is_07_H.d http://dstress.kuehne.cn/run/i/is_08_A.d http://dstress.kuehne.cn/run/i/is_08_B.d http://dstress.kuehne.cn/run/i/is_08_C.d http://dstress.kuehne.cn/run/i/is_08_D.d http://dstress.kuehne.cn/run/i/is_08_E.d http://dstress.kuehne.cn/run/i/is_08_F.d http://dstress.kuehne.cn/run/i/is_08_G.d http://dstress.kuehne.cn/run/i/is_08_H.d http://dstress.kuehne.cn/run/i/is_09_A.d http://dstress.kuehne.cn/run/i/is_09_B.d http://dstress.kuehne.cn/run/i/is_09_C.d http://dstress.kuehne.cn/run/i/is_09_D.d http://dstress.kuehne.cn/run/i/is_09_E.d http://dstress.kuehne.cn/run/i/is_09_F.d http://dstress.kuehne.cn/run/i/is_09_G.d http://dstress.kuehne.cn/run/i/is_09_H.d http://dstress.kuehne.cn/run/i/is_10_A.d http://dstress.kuehne.cn/run/i/is_10_B.d http://dstress.kuehne.cn/run/i/is_10_C.d http://dstress.kuehne.cn/run/i/is_10_D.d http://dstress.kuehne.cn/run/i/is_10_E.d http://dstress.kuehne.cn/run/i/is_10_F.d http://dstress.kuehne.cn/run/i/is_10_G.d http://dstress.kuehne.cn/run/i/is_10_H.d http://dstress.kuehne.cn/run/i/is_11_A.d http://dstress.kuehne.cn/run/i/is_11_B.d http://dstress.kuehne.cn/run/i/is_11_C.d http://dstress.kuehne.cn/run/i/is_11_D.d http://dstress.kuehne.cn/run/i/is_11_E.d http://dstress.kuehne.cn/run/i/is_11_F.d http://dstress.kuehne.cn/run/i/is_11_G.d http://dstress.kuehne.cn/run/i/is_11_H.d http://dstress.kuehne.cn/run/i/is_12_A.d http://dstress.kuehne.cn/run/i/is_12_B.d http://dstress.kuehne.cn/run/i/is_12_C.d http://dstress.kuehne.cn/run/i/is_12_D.d http://dstress.kuehne.cn/run/i/is_12_E.d http://dstress.kuehne.cn/run/i/is_12_F.d http://dstress.kuehne.cn/run/i/is_12_G.d http://dstress.kuehne.cn/run/i/is_12_H.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFEF+Hc3w+/yD4P9tIRAgIbAJ48xca4iWYt1eWGLX4PDQe/mo3TkwCgka6x f0HGCToN9r63VP1tHakuLaU= =m1gS -----END PGP SIGNATURE-----
Comment #2 by sean — 2006-03-15T13:10:24Z
Thomas Kuehne wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > [email protected] schrieb am 2006-03-10: >> Given the documentation, I would expect all eight tests to pass, yet tests six >> and eight both fail. >> >> >> C:\code\d\bugs>type 149_1.d >> import std.c.stdio; >> >> template isPointer( T ) >> { >> const bool isPointer = is( T : T* ); >> } >> >> void main() >> { >> struct S {} >> union U {} >> class C {} >> interface I {} >> enum E { e } >> alias void function() fp; >> alias void delegate() dp; >> >> static if( is( S == struct ) ) printf( "1. struct passes\n" ); >> static if( is( U == union ) ) printf( "2. union passes\n" ); >> static if( is( C == class ) ) printf( "3. class passes\n" ); >> static if( is( I == interface ) ) printf( "4. interface passes\n" ); >> static if( is( E == enum ) ) printf( "5. enum passes\n" ); >> static if( is( fp == function ) ) printf( "6. function passes\n" ); >> static if( is( dp == delegate ) ) printf( "7. delegate passes\n" ); >> static if( isPointer!(int*) ) printf( "8. pointer passes\n" ); >> } >> C:\code\d\bugs>dmd 149_1.d >> C:\bin\dmd\bin\..\..\dm\bin\link.exe 149_1,,,user32+kernel32/noi; >> >> C:\code\d\bugs>149_1 >> 1. struct passes >> 2. union passes >> 3. class passes >> 4. interface passes >> 5. enum passes >> 7. delegate passes > > Shouldn't isPointer be defined as: > > # template isPointer( T ){ > # const bool isPointer = is( T : void* ); > # } > > http://www.digitalmars.com/d/expression.html#IsExpression > # is ( Type : TypeSpecialization ) > # The condition is satisfied if Type is semantically correct and it is > # the same as or can be implicitly converted to TypeSpecialization. > > Thus "is(T : T*)" is always false. Good point. However, this is inconsistent with the template specialization syntax, where "template foo( T : T* )" is completely valid. But perhaps that doesn't matter as IsExpression differs in other ways as well. I suppose that leaves 'function' then. By the way, this code: class C { void fn() {} } static if( is( typeof(C.fn) == function ) ) pragma( msg, "is function\n" ); static if( is( typeof(C.fn) == delegate ) ) pragma( msg, "is delegate\n" ); prints "is function" if compiled. Aren't non-static class functions actually delegates? Sean
Comment #3 by thomas-dloop — 2006-03-15T14:30:28Z
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Sean Kelly schrieb am 2006-03-15: > By the way, this code: > > class C { void fn() {} } > static if( is( typeof(C.fn) == function ) ) > pragma( msg, "is function\n" ); > static if( is( typeof(C.fn) == delegate ) ) > pragma( msg, "is delegate\n" ); > > > prints "is function" if compiled. Aren't non-static class functions > actually delegates? Added to DStress as http://dstress.kuehne.cn/run/i/is_13_A.d http://dstress.kuehne.cn/run/i/is_13_B.d http://dstress.kuehne.cn/run/i/is_13_C.d http://dstress.kuehne.cn/run/i/is_13_D.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFEGIIo3w+/yD4P9tIRApHHAKCMeCKhln+R8zdriLdDSpoIXCewgwCfcrrh J90Jn3ukfw0vcbr6T894iR4= =9GBQ -----END PGP SIGNATURE-----
Comment #4 by bugzilla — 2006-04-26T13:43:18Z
>alias void function() fp; >static if( is( fp == function ) ) printf( "6. function passes\n" ); fp is not declared as a function, it is declared as a pointer to a function. If fp is declared as: alias void fp(); it will 'pass'. >template isPointer( T ) >{ > const bool isPointer = is( T : T* ); >} >static if( isPointer!(int*) ) printf( "8. pointer passes\n" ); Here, int* is passed as T to isPointer. The is(T:T*) is evaluated as is(int*:int**), and so it fails. To detect a pointer, use is(T:void*). >class C { void fn() {} } > static if( is( typeof(C.fn) == function ) ) > pragma( msg, "is function\n" ); > static if( is( typeof(C.fn) == delegate ) ) > pragma( msg, "is delegate\n" ); >prints "is function" if compiled. Aren't non-static class functions >actually delegates? No. Class functions are functions. A delegate is a pointer to a class function.
Comment #5 by sean — 2006-05-04T18:35:15Z
[email protected] wrote: >> >> alias void function() fp; >> static if( is( fp == function ) ) printf( "6. function passes\n" ); > > fp is not declared as a function, it is declared as a pointer to a function. If > fp is declared as: > alias void fp(); > it will 'pass'. So how do I test if T is a function pointer? Currently, I can test if T is a delegate via "if( is(T==delegate) )" but "if( is(T==function) )" clearly has a different meaning. For example: void delegate() dp; template isDelegate( T ) { const bool isDelegate = is( T == delegate ); } static assert( isDelegate!(dp) ); So far so good, but: void function() fp; template isFunctionPointer( T ) { const bool isFunctionPointer = ???; } static assert( isFunctionPointer!(fp) ); Currently, I'm examining the mangled name, which is a terrible hack: template isFunctionPointer( T ) { const bool isFunctionPointer= T.mangleof.length > 2 && T.mangleof[0] == 'P' && T.mangleof[1] == 'F'; } Sean
Comment #6 by sean — 2006-05-04T18:50:14Z
Sean Kelly wrote: > > So how do I test if T is a function pointer? By the way. If you're planning to eventually merge function pointers into delegates then I suppose there's no point in adding language support for this (assuming something doesn't already exist that I'm simply missing). I'd be content to use the workaround until then. Sean