[Bug c++/12783] New: potential C++ ABI issue

carlo at gcc dot gnu dot org gcc-bugzilla@gcc.gnu.org
Mon Oct 27 02:48:00 GMT 2003


PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12783

           Summary: potential C++ ABI issue
           Product: gcc
           Version: 3.4
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: carlo at gcc dot gnu dot org
                CC: gcc-bugs at gcc dot gnu dot org

While fixing a demangler bug, I wrote a few tests to get
an insight in how the compiler mangles names with a complex
mixture of const and array qualifiers.  I then ran into
a perculiar name mangling that seemed to be wrong.  Hopefully
the below proves that there is indeed an issue here.

First, consider the simple case where we use 'int' as
base type.  This code:

typedef int t1;

template<typename T>
  void
  foo(T&)
  {
  }

void f()
{
  t1 x1;
  foo<t1>(x1);
}

results in the mangled name: _Z3fooIiEvRT_

And this code:

typedef int t1;

template<typename T>
  void
  foo(T const&)  // The only difference with the above
                 // code is that there is a 'const' here.
  {
  }

void f()
{
  t1 x1;
  foo<t1>(x1);
}

results in the mangled name: _Z3fooIiEvRKT_
note the extra 'K' before the T_.
This is correct.

Now, lets re-do the above for a different t1,
instead of 'int' we use:

typedef int const t1;

Now, the first case results in the mangled name: _Z3fooIKiEvRT_,
note the extra K (Ki between the I and E is the 'int const' template
parameter). 
and the second case results in: _Z3fooIiEvRKT_, note the extra 'K'
before the T_ and the DISAPPEARANCE of the K in the template parameter!
In other words, this results in a foo<int>(int const&), and not
foo<int const>(int const&).  Also this is correct.

Next we replace the 'int' above with 'int [6]':

typedef int t1 [6];

This gives,
for the first case: _Z3fooIA6_iEvRT_
and the second case: _Z3fooIA6_iEvRKT_
equivalent to the 'int' case.

and finally we try:

typedef int const t1 [6];

which gives for the first case: _Z3fooIA6_KiEvRT_
note the extra 'K' in the template parameter, just
as with the 'int'/'int const' case.  Note also that
A6_Ki demangles as 'int const [6]', being an array
of size 6 of constant ints.  This is because a
constant array of ints is the same as an array of
constant ints, and the mangling KA (first K then A)
does not exist, so - this mangling is correct.

The second case gives us however: _Z3fooIA6_KiEvRKT_
where there is correctly a new 'K' in front of the T_
but the K in the template parameter did NOT disappear now!

The latter is a bug imho, the mangling should have been:

_Z3fooIA6_iEvRKT_

equivalent with the 'int'/'int const' case.

Later research revealed that this bug is related
to the use of the typedef.  Therefore I'd like
to summarize this report as follows:

This code snippet:

template<typename T>
  void
  foo(T const&)
  {
  }

typedef int const t[6];

void f()
{
  int const x[6] = { 0, };
  t y = { 0, };
  foo(x);
  foo(y);
}

results in TWO different instantiations of foo:

_Z3fooIA6_iEvRKT_    (correct)

and

_Z3fooIA6_KiEvRKT_   (incorrect)

there should have been just one function.



More information about the Gcc-bugs mailing list