typeof: automatic ID generation and GCC problems

Hi everybody, I modified the code to automatically generate IDs of registration groups. The registration now is as simple as: #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() BOOST_TYPEOF_REGISTER_TYPE(...); BOOST_TYPEOF_REGISTER_TEMPLATE(...); ... I also added some tests that should cause the ODR violation (see odr.hpp, odr1.cpp, odr2.cpp). VC7.1 is fine with them, however I can't make GCC 3.3 to compile this, and it stops much before the ODR could be diagnosed. Looks like this compiler totally can't handle the case when I try to use typeof (native or not) inside a template. When I force the typeof emulation, I am getting: "sorry, unimplemented: `method_call_expr' not supported by dump_expr" on every attempt to use my encoding/decoding stuff inside a template. From searching the web it looks like this is some kind of known bug related to improper handeling of sizeof(). Since sizeof() is the central part of all this, I don't really know how to work it around... This would probably be OK, since GCC has the native typeof support. However, when I use the native support, I run into a different problem that can be illustrated by the following code: template<class T, class U> typeof(T() + U()) sum(const T& t, const U& u) { return t + u; } main() { sum(5, 3.14); // this is line 9 return 0; } The compile of this code fails with following message: a.cpp:9: internal compiler error: in write_type, at cp/mangle.c:1555 GCC appears to be fine when the native typeof is used inside _class_ templates, though. I would really appreciate if anybody shed some light on any of these problems... The code is in the Spirit CVS and at: http://groups.yahoo.com/group/boost/files/typeof.zip Again, eveything is working fine in VC7.1. If anybody could try any other compiler (to build main.cpp, odr1.cpp, and odr2.cpp together), I would really appreciate this. Thanks, Arkadiy

Arkadiy Vertleyb wrote:
When I force the typeof emulation, I am getting:
"sorry, unimplemented: `method_call_expr' not supported by dump_expr"
Do you have a testcase?
a.cpp:9: internal compiler error: in write_type, at cp/mangle.c:1555
This is this bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11078 Apparently this is quite an old bug. It also appears in the latest development version of GCC as of a few days ago, so it seems as if its not fixed yet. Quite likely not to be fixed soon without someone showing some interest, or fixing it themselves. Aaron W. LaFramboise

Aaron W. LaFramboise wrote:
a.cpp:9: internal compiler error: in write_type, at cp/mangle.c:1555
This is this bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11078
Apparently this is quite an old bug. It also appears in the latest development version of GCC as of a few days ago, so it seems as if its not fixed yet. Quite likely not to be fixed soon without someone showing some interest, or fixing it themselves.
No, the real point is that this is a defect in the Itanium C++ ABI, which does not specify a way to mangle typeof (being non-standard...) nor other complex expressions used in function signatures (like function calls or method calls within sizeof expressions). I am told that the C++ ABI committee is reluctant to update the ABI at the moment because there have been some talks in the C++ reflectors to prohibit such degenerated expressions. Of course, GCC could just emit a "sorry: cannot mangle this due to a defect in the C++ ABI" like we do for the other situations, instead of just segfaulting. I will take care of this personally. As for a workaround, the whole point is to bring the typeof() out of the function signature, so that it does not need to be mangled anymore. I see Aleksey already provided a working solution along these lines, and it looks like the best workaround to me. -- Giovanni Bajo

Arkadiy Vertleyb wrote:
However, when I use the native support, I run into a different problem that can be illustrated by the following code:
template<class T, class U> typeof(T() + U()) sum(const T& t, const U& u) { return t + u; }
That's a common problem. You need to declare a function to return the temporaries you need, this usually helps: template< typename T > T provide(); template< typename T, typename U > typeof( provide<T>() + provide<U>() ) sum(...) {} Regards, Daniel -- Daniel Frey aixigo AG - financial solutions & technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de The hacks that we write today become the bugs of tomorrow.

"Daniel Frey" <daniel.frey@aixigo.de> wrote
That's a common problem. You need to declare a function to return the temporaries you need, this usually helps:
template< typename T > T provide();
template< typename T, typename U > typeof( provide<T>() + provide<U>() ) sum(...) {}
I am afraid this doesnt help :( The following code produces the same "internal compiler error": template<class T> T make(); template<class T, class U> typeof(make<T>() + make<U>()) sum(const T& t, const U& u) { return t + u; } main() { sum(5, 3.14); return 0; } Regards, Arkadiy

Arkadiy Vertleyb wrote:
I am afraid this doesnt help :(
Oops, my fault. But the following works, at least on the 3.3.1 where I tested it 2 minutes ago :) template<class T, class U> struct operator_plus_result { static T t(); static U u(); typedef __typeof__( t() + u() ) type; }; template<class T, class U> typename operator_plus_result<T,U>::type sum(const T& t, const U& u) { return t + u; } int main() { sum(5, 3.14); } Regards, Daniel -- Daniel Frey aixigo AG - financial solutions & technology Schloß-Rahe-Straße 15, 52072 Aachen, Germany fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99 eMail: daniel.frey@aixigo.de, web: http://www.aixigo.de The hacks that we write today become the bugs of tomorrow.

This would probably be OK, since GCC has the native typeof support. However, when I use the native support, I run into a different problem
Arkadiy Vertleyb writes: that
can be illustrated by the following code:
template<class T, class U> typeof(T() + U()) sum(const T& t, const U& u) { return t + u; }
main() { sum(5, 3.14); // this is line 9 return 0; }
The compile of this code fails with following message:
a.cpp:9: internal compiler error: in write_type, at cp/mangle.c:1555
The following compiles for me (GCC 3.3.3 mingw special): template<class T, class U> struct typeof_ { typedef typeof(T() + U()) type; }; template<class T, class U> typename typeof_<T,U>::type sum(const T& t, const U& u) { return t + u; } int main() { sum(5, 3.14); // this is line 9 return 0; } -- Aleksey Gurtovoy MetaCommunications Engineering
participants (5)
-
Aaron W. LaFramboise
-
Aleksey Gurtovoy
-
Arkadiy Vertleyb
-
Daniel Frey
-
Giovanni Bajo