C++ demangler ABI vs. g++

Carlo Wood carlo at alinoe.com
Sat Nov 22 06:34:08 UTC 2003


I can only completely agree with this.

>From the source code comments of bits/demangle.h:

// It is unclear why g++ doesn't add a substitution for
// "<Q2>F<R><B>E" as it should I think.

I've chosen to let the demangler match whatever g++ does
rather than what the ABI says ;).

It is very well possible that the best/correct thing
is a change/clarification of the ABI.  Hence, a CC to cxx-abi-dev at codesourcery.com


On Fri, Nov 21, 2003 at 09:33:18PM -0500, Ian Lance Taylor wrote:
> Since I just dug through the C++ V3 mangling ABI in spec and in usage,
> I thought I should report a discrepancy I found.  I found it because I
> implemented the demangler based on my reading of the ABI, and then
> found that there were some symbols generated by g++ which the
> demangler did not handle correctly.
> 
> I can file a PR on this if that would be appropriate.  Basically,
> though, I think the mangling ABI should be changed.
> 
> I used the mangling ABI found here:
>     http://www.codesourcery.com/cxx-abi/abi.html#mangling
> (I don't know if this is in the gcc repository anywhere, but I think
> it would be appropriate.)
> 
> The mangling ABI says that whenever the grammar uses <substitution>,
> that is a substitution candidate (with some restrictions which are not
> relevant here).  The grammar includes these productions:
>     <type> ::= <substitution>
>     <pointer-to-member-type> ::= M <type> <type>
> This clearly suggests that the second <type> in
> <pointer-to-member-type> is a substitution candidate.
> 
> However, g++ does not work that way.  Only the base type of the second
> <type> is a substitution candidate.  If the second <type> is
> CV-qualified, the fully qualified type is not a substitution
> candidate.
> 
> The ABI specifies that any CV-qualifiers on the second <type> are
> qualifiers for the member function which is being pointed to.  So the
> second <type> is slightly unusual.  But the ABI does not say that
> those CV-qualifiers are not themselves a substitution candidate as is
> indicated by the grammar.
> 
> In the code in cp/mangle.c, see write_function_type().  For a
> pointer-to-member-function, it writes out the CV qualifiers for the
> first parameter to the function type, and it passes the function type
> to write_bare_function_type(), but it never calls add_substitution()
> for the qualified type.  This is understandable, since it does not
> have the correct type to pass to add_substitution().  But to me it
> looks like a violation of the mangling ABI.
> 
> Here is a test case:
> 
> class G { int g; }; class H { int h; };
> template<class t> class what { int w1; };
> template<class t> class what2 { int w2; };
> void r(int (G::*)(), int (G::*)() const, G, int (H::*)(), int (G::*)(),
>        what<G const>, what2<G const>, int (G::*)() const) {}
> 
> The mangled name of the function r is
>     _Z1rM1GFivEMS_KFivES_M1HFivES1_4whatIKS_E5what2IS8_ES3_
> which demangles into
>     r(int (G::*)(), int (G::*)() const, G, int (H::*)(), int (G::*)(), what<G const>, what2<G const>, int (G::*)() const)
> 
> Breaking this down, we get (substitution candidates are labelled with
> SUB and the substitution index):
> 
> _Z                   (prefix)
>  1r                  (name 'r')
>  M                   (pointer to member)
>   1G                 (name 'G') (SUB 0)
>   F                  (function)
>    i                 (int--return type)
>    v                 (void--no parameters)
>   E                  (end function) (fn is SUB 1) (ptr-to-mem is SUB 2)
>  M                   (pointer to member)
>   S_                 (substitution 0 == name 'G')
>   K                  (const)
>    FivE              (function as above) (fn is SUB 3) (p-to-m is SUB 4) ***
>  S_                  (substitution 0 == name 'G')
>  M1HFivE             (pointer to member as above)
>                      ('H' is SUB 5) (fn is SUB 6) (p-to-m is SUB 7)
>  S1_                 (substitution 2 == first ptr-to-mem above)
>  4what               (name 'what') (SUB 8)
>   I                  (template arguments follow)
>    K                 (const)
>     S_               (substitution 0 == name 'G') (SUB 9)
>   E                  (end template arguments)
>  5what2              (name 'what2') (SUB 10)
>   I                  (template arguments follow)
>    S8_               (substitution 9 == 'G const')
>   E                  (end template arguments)
>  S3_                 (substitution 4 == second ptr-to-mem above)
> 
> So, if you followed all that, look closely at the line with ***.
> There you see that the function FivE is a substitution candidate, and
> the full pointer to member MS_KFivE is a substitution candidate.
> However, by the reading of the grammar, the qualified type KFivE
> should also be a substitution candidate.  However, it is not.  If it
> were, the rest of the name would be mangled incorrectly, because the
> references to substitution 4 and 9 would refer to the incorrect
> types.
> 
> I think the simplest fix is to change the ABI to say
>     <pointer-to-member-type> ::= M <type> <CV-qualifers> <type>
> That would clarify that the <CV-qualifiers> do not form a substitution
> candidate with the second <type>.
> 
> Ian

-- 
Carlo Wood <carlo at alinoe.com>



More information about the cxx-abi-dev mailing list