www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 7024] New: inconsistent mangling of shared in extern(C++)

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024

           Summary: inconsistent mangling of shared in extern(C++)
           Product: D
           Version: D2
          Platform: Other
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: dawg dawgfoto.de



module fail;

extern(C++) void foo1(void*);
extern(C++) void bar1(shared void*);

pragma(msg, foo1.mangleof);
pragma(msg, bar1.mangleof); // shared is ignored here, because C++ doesn't have
shared, this make sense.

extern(C++) void foo2(void function(void*));
extern(C++) void bar2(void function(shared void*));

pragma(msg, foo2.mangleof);
pragma(msg, bar2.mangleof); // shared is ignored here, because C++ doesn't have
shared, this make sense.

extern(C++) void foo3(void function(void*), void*);
extern(C++) void bar3(void function(shared void*), void*);

pragma(msg, foo3.mangleof);
pragma(msg, bar3.mangleof); // shared generate a different mangling here.

extern(C++) void foo4(void function(void*), shared void*);
extern(C++) void bar4(void function(shared void*), shared void*);

pragma(msg, foo4.mangleof); // Same mangling as bar3.
pragma(msg, bar4.mangleof); // back to correct mangling (the one expected by
g++).

extern(C++) void foo5(void* function(void*), void*);
extern(C++) void bar5(void* function(shared void*), void*);

pragma(msg, foo5.mangleof);
pragma(msg, bar5.mangleof); // shared generate a different mangling here.

extern(C++) void foo6(void* function(void*), shared void*);
extern(C++) void bar6(void* function(shared void*), shared void*);

pragma(msg, foo6.mangleof); // shared generate a different mangling here.
pragma(msg, bar6.mangleof); // function pointer mangled as in bar5, but second
parameter get a "0" in the mangling that none of the mangling above had.

----

It is expected that shared be ignored as in the foo1/bar1 case.

filed on behalf of deadalnix.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 28 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024


deadalnix <deadalnix gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |deadalnix gmail.com



Hi,

As I said in the topic, I was using GDC to generate informations. I didn't try
with DMD so it is not sure the problem actually exists on this compiler.

I'm currently repporting the issue to GDC bugtracker.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 28 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024




Yes, it exists with dmd too.

It is an error with the compression in name mangling.
http://sourcery.mentor.com/public/cxx-abi/abi.html#mangling-compression
The compiler fails to substitute 'void*' and 'shared void*'.
But for both shared is ignored for mangling.

It needs to be decided whether all qualifiers (probably except for const)
be silently stripped or if they should result in an error/warning.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 28 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024




current workaround:

Don't use shared/immutable/inout with extern(C++) declarations.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 29 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024


Iain Buclaw <ibuclaw ubuntu.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |ibuclaw ubuntu.com



Rather than trying to fix the C++ mangling, wouldn't it make more sense to
disallow 'shared' in extern(C++) declarations?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024




It'd be a cleaner cut to disallow immutable/shared/inout for extern(C++)
declarations. Not sure though how big the impact is.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 01 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024





 Rather than trying to fix the C++ mangling, wouldn't it make more sense to
 disallow 'shared' in extern(C++) declarations?
As thoses concept doesn't exists in C++, this is up to the C++ programmer to ensure that something is shared or not. Sometime, C++ code is just made to handle shared data, it is just not explicit. In this case, you ends up using convoluted casts to handle everything. I have a practical case : start a thread from C++, but that could interract with D (so you must go throw D's way of starting thread). You end up writing something like this : alias extern(C++) void* function(void*) EntryPoint; extern(C++) void* D_start_thread(EntryPoint entryPoint, void* userData) { Tid tid = spawn(function void(EntryPoint entryPoint, shared void* userData) { entryPoint(cast(void*) userData); }, entryPoint, cast(shared void*) userData); return cast(void*) [tid].ptr; } So I would recommand to ignore shared in mangling of C++ function and mangle immutable as const. It is up to the programmer to ensure that thoses are right qualifiers. inout can't be handled nicely so it should generate a compile time error. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 02 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024




The baseline of D type system is to disallow things that can't be guaranteed.
C++ definitely can't guarantee any of the three.
To avoid explicit casting at every caller place, you could add
a D wrapper that does the calling.

extern(C++) void _spawn(void function() fun, void* data);

void spawn(extern(C++) void function() fun, shared void* data)
{
  _spawn(fun, cast(void*)data);
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 02 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024





 The baseline of D type system is to disallow things that can't be guaranteed.
 C++ definitely can't guarantee any of the three.
 To avoid explicit casting at every caller place, you could add
 a D wrapper that does the calling.
 
 extern(C++) void _spawn(void function() fun, void* data);
 
 void spawn(extern(C++) void function() fun, shared void* data)
 {
   _spawn(fun, cast(void*)data);
 }
This piece of code miss completely the point of the one before. But back to the problem, obviously, C++ cannot guarantee, with it's type system, that something is immutable, shared, or whatever. This is why a bindong is required, and the same thing must be express the D way and the C++ way to interact. It is up to the person writting the binding to ensure that it is correct. C++ can have immutable data, or shared one's. It isn't guaranteed by the type system, but can be guaranteed by the logic of the application. So it make sense to express those in bindings. C++ cannot guarantee anything that D guarantee. It can corrupt memory, share non shared data across thread, etc . . . So if we agree on this argument, extern(C++) must be simply and completely removed from D's specification and implementation. When it comes to binding, it is up to the person writting the binding to ensure that code on both sides express the same thing, and it cannot, and never will, be enforced by a specification. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Dec 03 2011
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=7024




- The current D policy is to not base such things on trust but
   require explicit casting.

 - You have no way to guarantee atomic access for shared in C++.

 - Overloaded extern(C++) functions will clash during linking or
   even worse resolve to the same symbol.

The only pro argument is less typing for the caller,
where the example code just showed another solution to this.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Dec 03 2011