public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: c++/3211: Incorrect, substitution related mangling.
@ 2001-11-13 15:16 loewis
  0 siblings, 0 replies; 6+ messages in thread
From: loewis @ 2001-11-13 15:16 UTC (permalink / raw)
  To: carlo, gcc-bugs, gcc-gnats, gcc-prs, nobody

Synopsis: Incorrect, substitution related mangling.

State-Changed-From-To: open->closed
State-Changed-By: loewis
State-Changed-When: Mon Nov 19 08:17:22 2001
State-Changed-Why:
    Closed on request of submitter.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3211&database=gcc


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++/3211: Incorrect, substitution related mangling.
@ 2001-11-13 15:16 loewis
  0 siblings, 0 replies; 6+ messages in thread
From: loewis @ 2001-11-13 15:16 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/3211; it has been noted by GNATS.

From: loewis@gcc.gnu.org
To: carlo@alinoe.com, gcc-bugs@gcc.gnu.org, gcc-gnats@gcc.gnu.org,
  gcc-prs@gcc.gnu.org, nobody@gcc.gnu.org
Cc:  
Subject: Re: c++/3211: Incorrect, substitution related mangling.
Date: 19 Nov 2001 16:17:23 -0000

 Synopsis: Incorrect, substitution related mangling.
 
 State-Changed-From-To: open->closed
 State-Changed-By: loewis
 State-Changed-When: Mon Nov 19 08:17:22 2001
 State-Changed-Why:
     Closed on request of submitter.
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&pr=3211&database=gcc


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++/3211: Incorrect, substitution related mangling.
@ 2001-06-18 16:56 Carlo Wood
  0 siblings, 0 replies; 6+ messages in thread
From: Carlo Wood @ 2001-06-18 16:56 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/3211; it has been noted by GNATS.

From: Carlo Wood <carlo@alinoe.com>
To: Mark Mitchell <mark@codesourcery.com>
Cc: gcc-gnats@gcc.gnu.org
Subject: Re: c++/3211: Incorrect, substitution related mangling.
Date: Tue, 19 Jun 2001 01:51:50 +0200

 On Mon, Jun 18, 2001 at 10:08:29AM -0700, Mark Mitchell wrote:
 ...
 > But, we will not change the G++ mangling under any circumstances --
 > unless there are programs that do not work because two mangled names
 > conflict when they should not.
 > 
 > --
 > Mark Mitchell                   mark@codesourcery.com
 > CodeSourcery, LLC               http://www.codesourcery.com
 
 Then PR c++/3211 can be closed.
 
 -- 
 Carlo Wood <carlo@alinoe.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: c++/3211: Incorrect, substitution related mangling.
@ 2001-06-17 17:36 Carlo Wood
  0 siblings, 0 replies; 6+ messages in thread
From: Carlo Wood @ 2001-06-17 17:36 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/3211; it has been noted by GNATS.

From: Carlo Wood <carlo@alinoe.com>
To: gcc-bugs@gcc.gnu.org
Cc: gcc-gnats@gcc.gnu.org
Subject: Re: c++/3211: Incorrect, substitution related mangling.
Date: Mon, 18 Jun 2001 02:31:05 +0200

 On Sun, Jun 17, 2001 at 06:59:39PM +0200, Carlo Wood wrote:
 > Please note that even:
 > 
 > --------------------
 > #include <iostream>
 > #include <typeinfo>
 >  
 > struct A {
 >   int member(void) { }
 > };
 >  
 > template<typename T>
 >   struct const_test {
 >     typedef int (member_type)(void);
 >     member_type (T::*member_pointer);
 >   };
 >  
 > int main(void)
 > {
 >   std::cout << typeid(const_test<A const>::member_pointer).name() << '\n';
 >   return 0;
 > }
 > --------------------
 > 
 > Returns "MK1AFivE", where "1A" is <type1> and "FivE" is <type2>.  There is no
 > 'const' qualifier for "1A".
 
 Hmmpf.  Ok, that was nonsense... There *is* a 'K' there...
 But it doesn't change the fact that there can only be a 'K' when <type2>
 is a (member) function.  I don't think this changes the relevance of my
 argument that "K1A" shouldn't be a candidate for substitution, nor should
 a substitution be used at that place for "K1A" is one such substitution
 already exists.
 
 -- 
 Carlo Wood <carlo@alinoe.com>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* c++/3211: Incorrect, substitution related mangling.
@ 2001-06-17 10:06 Carlo Wood
  0 siblings, 0 replies; 6+ messages in thread
From: Carlo Wood @ 2001-06-17 10:06 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR c++/3211; it has been noted by GNATS.

From: Carlo Wood <carlo@alinoe.com>
To: gcc-bugs@gcc.gnu.org
Cc: gcc-gnats@gcc.gnu.org
Subject: c++/3211: Incorrect, substitution related mangling.
Date: Sun, 17 Jun 2001 18:59:39 +0200

 I am afraid this is going to be a long one.  The background is that
 I've been working on a demangler for several weeks now, using g++-3.0 (pre)
 and the demangler in libiberty for comparision (without looking at the source).
 
 Now I've come to a point where start to find bugs in g++ instead of in
 my own demangler ;).
 
 PS If you don't have time to read it all, there is a CONCLUSION half way.
 
 I've used http://reality.sgi.com/dehnert_engr/cxx/abi.html#mangling-type
 as reference for writing my demangler.
 
 ---
 
 This reference defines
 
 <pointer-to-member-type> ::= M <class type> <member type>
 
 being a <type> itself, it is subject to substitution.
 
 Moreover, "<CV-qualifiers> <some type>" being a <type>, both
 "<CV-qualifiers> <some type>" and "<some type>" are subject to
 substitution.
 
 For clarity, let <type> be an unqualified type below.  So we
 have to write:
 
 <pointer-to-member-type> ::= [<CV-qualifiers>] M [<CV-qualifiers>] <type1> [<CV-qualifiers>] <type2>
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   pointer-to-member-type ____/                   ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
                                   class type ____/         member type ____/
 
 and subsitution members are:
 
 <type1>
 <CV-qualifiers> <type1>
 <type2>
 <CV-qualifiers> <type2>
 M <CV-qualifiers> <type1> <CV-qualifiers> <type2>
 <CV-qualifiers> M <CV-qualifiers> <type1> <CV-qualifiers> <type2>
 
 As an example, <type2> has qualifiers in this case:
 
 --------------------
 struct A {
   int volatile member;
 };
    
 int volatile (A::*member_pointer) = &A::member;
 --------------------
 
 We can use the following test program to find what g++-3.0 makes of it:
 
 --------------------
 #include <iostream>
 #include <typeinfo>
  
 struct A {
   int volatile member;
 };
  
 int volatile (A::*member_pointer) = &A::member;
  
 int main(void)
 {
   std::cout << typeid(member_pointer).name() << '\n';
   return 0;
 }
 --------------------
 
 which gives:
 
 M1AVi
 
 
 Now note that "A const::*" is incorrect C++.
 
 The following test case:
 
 --------------------
 #include <iostream>
 #include <typeinfo>
  
 struct A {
   int volatile member;
 };
  
 template<typename T>
   struct const_test {
     static int volatile (T::*member_pointer);
   };
  
 template<typename T>
   int volatile (T::*const_test<T>::member_pointer) = &T::member;
  
 int main(void)
 {
   std::cout << typeid(const_test<A const>::member_pointer).name() << '\n';
   return 0;
 }
 --------------------
 
 Still return "M1AVi", because the 'const' is simply dropped.
 
 The only way to get a qualifier before <type1> is when <type2> is a member *function*
 that is `const'.  Please not that even:
 
 --------------------
 #include <iostream>
 #include <typeinfo>
  
 struct A {
   int member(void) { }
 };
  
 template<typename T>
   struct const_test {
     typedef int (member_type)(void);
     member_type (T::*member_pointer);
   };
  
 int main(void)
 {
   std::cout << typeid(const_test<A const>::member_pointer).name() << '\n';
   return 0;
 }
 --------------------
 
 Returns "MK1AFivE", where "1A" is <type1> and "FivE" is <type2>.  There is no
 'const' qualifier for "1A".
 
 This seems to indicate that qualifiers directly after the "M" really
 belong to the member *function*.  For example:
 
 --------------------
 #include <iostream>
 #include <typeinfo>
  
 struct A {
   int member(void) const { }
 };
  
 int (A::*member_pointer)(void) const = &A::member;
  
 int main(void)
 {
   std::cout << typeid(member_pointer).name() << '\n';
   return 0;
 }
 --------------------
 
 returns "MK1AFivE", with a 'K' in front of the <type1> -- which as we saw before
 really can't BE there *unless* <type2> is a function.
 
 [ Note that this is very equivalent with how qualifiers work with nested functions,
   for example:
 
   --------------------
     struct A {
       int f1(float);
       int f2(float) const volatile;
     };
      
     int A::f1(float) { }
     int A::f2(float) const volatile { }
   --------------------
 
   results in the mangled names:
 
   00000000 T _ZN1A2f1Ef
   00000010 T _ZNVK1A2f2Ef
 
   very similar like
 
   --------------------
   struct A;
   void f1p(int (A::*)(float)) { }
   void f2p(int (A::*)(float) const volatile) { }
   --------------------
 
   results in the mangled names
 
   00000000 T _Z3f1pM1AFifE
   00000020 T _Z3f2pMVK1AFifE
 ]
 
 Imho, the draft is wrong and should have defined <pointer-to-member> like
 it defines <nested-name>:
 
 <pointer-to-member-type> ::= M [CV-qualifiers] <class type> <member type>
 
 stripping off qualifiers that otherwise *errornous* seem to belong to the
 class type (which is not possible).
 
 Another argument for this is found by looking at what happens when
 <class type> is a <nested-name> itself.  For example:
 
 --------------------
 #include <iostream>
 #include <typeinfo>
  
 struct A {
   struct B {
     int member(void) const { }
   };
 };
  
 int (A::B::*member_pointer)(void) const = &A::B::member;
  
 int main(void)
 {
   std::cout << typeid(member_pointer).name() << '\n';
   return 0;
 }
 --------------------
 
 prints "MKN1A1BEFivE", as it should (imho) and NOT "MN1AK1BEFivE", or
 "MNK1A1BEFivE" for that matter.
 
 The demangler in libiberty is already *heavily* broken concerning qualifiers
 (as I reported before), but how does the above affect the mangling of g++?
 
 It does because it has effect on the used substitutions, after all - when using
 
 <pointer-to-member-type> ::= M [CV-qualifiers] <class type> <member type>
 
 the resulting substitutions would be:
 
 <type1>			<-- unqualified, even when being a <nested-name>
 <type2>
 <CV-qualifiers> <type2>
 M <CV-qualifiers> <type1> <CV-qualifiers> <type2>
 <CV-qualifiers> M <CV-qualifiers> <type1> <CV-qualifiers> <type2>
 
 And "<CV-qualifiers> <type1>" is gone from the list.
 
 Now before you say 'yes, but this is at most a bug in the reference and not in g++',
 let me point out an inconsistency in the reference related to this.  It states:
 "substitutable components are the represented symbolic constructs, not their
  associated mangling character strings".  This would mean that a substitution
 for "<CV-qualifiers> <type1>" would result in storing and re-using a string like
 "A::B const", but it is possible to get:
 
 MS3_FivE
 
 for example, where S3_ represents the mentioned qualified <type1>.  Following the
 reference literally we'd HAVE to demangle that as:
 
 "void (A::B const::*)(int)"
 
 where the string "A::B const" (S3_) appears literally.
 
 ==========
 CONCLUSION
 ==========
 
 This is why I am convinced that this substitution is wrong, it shouldn't exist.
 The correct way to mangle the above is as follows:
 
 with for example:
 
 S2_ == "A::B"
 S3_ == "A::B const"
 
 "void (A::B::*)(int) const"
 
 should mangle as
 
 "MKS2_FviE" and not as "MS3_FviE".
 
 g++-3.0 makes of this:
 
 ----------------------
 struct A {
   struct B {
     int member(void) const { }
     static int (A::B::* const member_pointer)(void) const = &A::B::member;
     void foo(A::B const*, typeof(member_pointer));
   };
 };
  
 void A::B::foo(A::B const*, typeof(A::B::member_pointer)) { }
 ----------------------
 
 where 'A::B::foo' is mangled as "_ZN1A1B3fooEPKS0_MS1_FivE".
 
                  this should be "_ZN1A1B3fooEPKS0_MKS0_FivE" imho.
 
 
 -- 
 Carlo Wood <carlo@alinoe.com>
 
 =====================================================================================
 PS Note that the demangler in libiberty chokes on this as well:
 
 /usr/src/gcc/gcc-cvs-3.0/libiberty>c++filt _ZN1A1B3fooEPKS0_MKS0_FivE
  -> mangled-name             at position   0
  -> encoding                 at position   2
  -> name                     at position   2
  -> nested-name              at position   2
  -> prefix                   at position   3
  -> unqualified-name         at position   3
  -> source-name              at position   3
  -> number                   at position   3
  -> number*                  at position   3
  -> identifier               at position   4
 SUBSTITUTIONS:
  S_   : A
  -> unqualified-name         at position   5
  -> source-name              at position   5
  -> number                   at position   5
  -> number*                  at position   5
  -> identifier               at position   6
 SUBSTITUTIONS:
  S_   : A
  S0_  : A::B
  -> unqualified-name         at position   7
  -> source-name              at position   7
  -> number                   at position   7
  -> number*                  at position   7
  -> identifier               at position   8
  -> bare-function-type       at position  12
  -> type                     at position  12
  -> type*                    at position  12
  -> type*                    at position  13
  -> type                     at position  13
  -> CV-qualifiers            at position  13
  -> type                     at position  14
  -> substitution             at position  14
  -> number                   at position  15
  -> number*                  at position  15
 SUBSTITUTIONS:
  S_   : A
  S0_  : A::B
  S1_  : A::B const
 SUBSTITUTIONS:
  S_   : A
  S0_  : A::B
  S1_  : A::B const
  S2_  : A::B const*
  -> type                     at position  17
  -> type*                    at position  17
  -> type                     at position  18
  -> CV-qualifiers            at position  18
  -> type                     at position  19
  -> substitution             at position  19
  -> number                   at position  20
  -> number*                  at position  20
 SUBSTITUTIONS:
  S_   : A
  S0_  : A::B
  S1_  : A::B const
  S2_  : A::B const*
  S3_  : A::B const
  -> type*                    at position  22
  -> function-type            at position  22
  -> bare-function-type       at position  23
  -> type                     at position  23
  -> builtin-type             at position  23
 SUBSTITUTIONS:
  S_   : A
  S0_  : A::B
  S1_  : A::B const
  S2_  : A::B const*
  S3_  : A::B const
  S4_  : int ()()
 SUBSTITUTIONS:
  S_   : A
  S0_  : A::B
  S1_  : A::B const
  S2_  : A::B const*
  S3_  : A::B const
  S4_  : int ()()
  S5_  : int (A::B const::*)()
 A::B::foo(A::B const*, int (A::B const::*)())
 
 
 Where "A::B const" appears TWICE in the substitution list, which is a definite bug.
 Moreover, I am not convinved that "int ()()" should be there (it can neither be
 used as a literal replacement; same argument).  Finally, the "A::B const::*"
 is syntactical nonsense.
 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* c++/3211: Incorrect, substitution related mangling.
@ 2001-06-17  9:56 carlo
  0 siblings, 0 replies; 6+ messages in thread
From: carlo @ 2001-06-17  9:56 UTC (permalink / raw)
  To: gcc-gnats

>Number:         3211
>Category:       c++
>Synopsis:       Incorrect, substitution related mangling.
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 17 09:56:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Carlo Wood
>Release:        3.0
>Organization:
>Environment:

>Description:
There are still issues with (de)mangling and qualifiers.
Qualifiers and pointer-to-member may even result in
wrong mangling as a result of errornous substitutions.
>How-To-Repeat:
See audit trail that I will post in a moment.
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-11-19 16:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-11-13 15:16 c++/3211: Incorrect, substitution related mangling loewis
  -- strict thread matches above, loose matches on Subject: below --
2001-11-13 15:16 loewis
2001-06-18 16:56 Carlo Wood
2001-06-17 17:36 Carlo Wood
2001-06-17 10:06 Carlo Wood
2001-06-17  9:56 carlo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).