Demangling ambiguity for templated conversion operators
Mike Herrick
mjh at edg.com
Tue Aug 10 19:36:57 UTC 2010
I was doing some "house cleaning" and came upon this apparent demangling ambiguity in the IA-64 ABI that we ran into a while back (unrelated to recent SFINAE discussions). I thought I'd highlight it here along with the demangler heuristic we implemented as a workaround in case that information is useful to other implementers.
Take this example:
$ cat ex.c
template <class T> struct A { };
template <class T> struct B { };
struct S {
template <class T> operator T();
} s;
void f() {
s.operator A< A<int> >();
s.operator A< B< A<int> > >();
}
$ g++450 -c ex.c
$ nm -u ex.o
U _ZN1ScvT_I1AI1BIS2_IiEEEEEv
U _ZN1ScvT_I1AIS2_IiEEEEv
$ nm -u -C ex.o
U S::operator A<B<B<int> > ><A<B<B<int> > > >()
U _ZN1ScvT_I1AIS2_IiEEEEv
GNU (and EDG and others) can't correctly demangle these names (the substitutions are wrong in the first demangled name above).
I believe the problem arises when using this rule for a template conversion function:
<operator-name> ::= cv <type> # (cast)
In the case for "_ZN1ScvT_I1AIS2_IiEEEEv" above, after the demangler sees the "cv", it's presented with "T_I1AIS2_IiEEEEv" and asked to demangle a <type>, but <type> can be either "T_" (a <template-param>) or "T_I1AIS2_IiEEE" (a <template-template-param> <template-args>). As far as I can tell, there's no way to know if the <template-args> are part of the <type> or belong to an enclosing production (i.e., <template-prefix> <template-args> -- where <template-prefix> is reduced to <operator-name>).
Here's an example that produces both cases depending on whether or not FOO is defined:
template <class T> struct A { };
struct S {
#ifdef FOO
template <class T> operator T();
#else
template <template <class> class T> operator T<int>();
#endif
} s;
void f() {
s.operator A<int>();
}
We've made a change to our demangler to initially not parse any <template-args> as part of the <type> when demangling a conversion function, but if the demangling fails, it makes a second attempt, this time allowing <template-args> as part of the <type>. With these changes, we now give these demangled names (for the initial example):
$ nm -u ex.o | edg_decode
U S::operator T1<A<B<A<int>>>>()
U S::operator T1<A<A<int>>>()
Mike Herrick
Edison Design Group
More information about the cxx-abi-dev
mailing list