Bug 16845 - demangler not working for plain "int"
Summary: demangler not working for plain "int"
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Ian Lance Taylor
URL:
Keywords:
: 19284 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-07-31 11:04 UTC by Ivan Godard
Modified: 2005-07-23 22:49 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ivan Godard 2004-07-31 11:04:54 UTC
#include <exception>
#include <iostream>
#include <cxxabi.h>

struct empty { };

template <typename T, int N>
  struct bar { };


  int main()
  {
    int     status;
    char   *realname;

    // exception classes not in <stdexcept>, thrown by the implementation
    // instead of the user
    std::bad_exception  e;
    realname = abi::__cxa_demangle(e.what(), 0, 0, &status);
    std::cout << e.what() << "\t=> " << realname << "\t: " << status << '\n';
    free(realname);


    // typeid
    bar<empty,17>          u;
    const std::type_info  &ti = typeid(u);

    realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
    std::cout << ti.name() << "\t=> " << realname << "\t: " << status << '\n';
    free(realname);

    // typeid
    const std::type_info  &tj = typeid(int);

    realname = abi::__cxa_demangle(tj.name(), 0, 0, &status);
    std::cout << tj.name() << "\t=> " << realname << "\t: " << status << '\n';
    free(realname);

    return 0;
    }


gets you:

~/ootbc/common/src$ a.out
St13bad_exception       => std::bad_exception   : 0
3barI5emptyLi17EE       => bar<empty, 17>       : 0
i       => ~/ootbc/common/src$


It works for some complicated types, but not for plain "int"

Ivan
Comment 1 Ivan Godard 2004-07-31 11:06:49 UTC
Here's the -v:

Reading specs from /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/spec
s
Configured with: ../gcc/configure --prefix=/site
Thread model: posix
gcc version 3.4.0
 /mnt/export/local/bin/../libexec/gcc/i686-pc-linux-gnu/3.4.0/cc1plus -quiet -v
-iprefix /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/ -D_GNU_SOURCE
 foo.cc -quiet -dumpbase foo.cc -mtune=pentiumpro -auxbase foo -version -o /tmp/
ccDO2GVs.s
ignoring nonexistent directory "/mnt/export/local/bin/../lib/gcc/i686-pc-linux-g
nu/3.4.0/../../../../i686-pc-linux-gnu/include"
ignoring duplicate directory "/site/lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../
include/c++/3.4.0"
ignoring duplicate directory "/site/lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../
include/c++/3.4.0/i686-pc-linux-gnu"
ignoring duplicate directory "/site/lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../
include/c++/3.4.0/backward"
ignoring duplicate directory "/site/lib/gcc/i686-pc-linux-gnu/3.4.0/include"
ignoring nonexistent directory "/site/lib/gcc/i686-pc-linux-gnu/3.4.0/../../../.
./i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../include/c+
+/3.4.0
 /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../include/c+
+/3.4.0/i686-pc-linux-gnu
 /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/../../../../include/c+
+/3.4.0/backward
 /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/include
 /usr/local/include
 /site/include
 /usr/include
End of search list.
GNU C++ version 3.4.0 (i686-pc-linux-gnu)
    compiled by GNU C version 3.4.0.
GGC heuristics: --param ggc-min-expand=38 --param ggc-min-heapsize=15744
 as -V -Qy -o /tmp/ccKZ44yK.o /tmp/ccDO2GVs.s
GNU assembler version 2.14.90.0.4 (i386-linux) using BFD version 2.14.90.0.4 200
30523 Debian GNU/Linux
 /mnt/export/local/bin/../libexec/gcc/i686-pc-linux-gnu/3.4.0/collect2 --eh-fram
e-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/cr
ti.o /mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/crtbegin.o -L/mnt/export/local/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0 -L/mnt/export/local/bin/../l
ib/gcc -L/site/lib/gcc/i686-pc-linux-gnu/3.4.0 -L/mnt/export/local/bin/../lib/gc
c/i686-pc-linux-gnu/3.4.0/../../.. -L/site/lib/gcc/i686-pc-linux-gnu/3.4.0/../..
/.. /tmp/ccKZ44yK.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /mnt/export/loc
al/bin/../lib/gcc/i686-pc-linux-gnu/3.4.0/crtend.o /usr/lib/crtn.o
Comment 2 Paolo Carlini 2004-07-31 19:44:42 UTC
Ian, could you please have a look?
Thanks in advance.
Comment 4 Ivan Godard 2004-07-31 23:42:27 UTC
After reading the citations from pinskia, it seems that there is a bug here regardless of the semantics. Your ABI may require that "i" demangle as "i", although I'd be appalled that it would, or as "int", but if you look at the test case it demangles as nothing at all (and reports a -2 error). That has to be a bug.

Three comments: 

1) I understand that there must be a link/RTTI demangler for data names. However, the ability to print a typename (from "typeid(...).name()") is also important to those mere users who are not compiler implementers. If the demangling syntax is different across the two cases (and if it is I predict big trouble when the day comes that you need to support an "extern "C" typedef...") then the library should provide a means by which both are available. The demangler in 3.4.0 /ext/demangle.h does so, but appears to be otherwise hopelessly broken (I tried to use it as a workaround).

2) At least for use from c++, the demangler should be integrated with streams; then the desired semantics can be specified by a format effector, as is done with "bool". The demangler should not have an interface that invites buffer-overrun exploits.

3) IMO, RTTI type info improvement is desperately needed. You know what you have to do to print the name of an enum value?

Ivan
Comment 5 Ian Lance Taylor 2004-08-01 02:06:32 UTC
I believe that the behaviour of __cxa_demangle conforms to the API.  I also
believe that the API is broken.  The present code conforms to the broken API.

The API is here:
http://www.codesourcery.com/cxx-abi/abi.html#demangler

It says 'Ambiguities are possible between extern "C" object names and internal
built-in type names, e.g. "i" may be either an object named "i" or the built-in
"int" type. Such ambiguities should be resolved to user names over built-in
names.'  All internal built-in type names are mangled as a single lower-case
character.  I interpret the API statement to mean that any string consisting of
a single lower-case character should not be demangled.

The API further says "If there is an error in demangling, the return value is a
null pointer."  Therefore, in this case, the function must return NULL.  Of the
options for a value to put in *status, -2 is the only reasonable choice.

There is a mailing list thread which discusses this here:
http://gcc.gnu.org/ml/libstdc++/2004-02/msg00333.html

Others agree that my reading of the API is reasonable.  I continue to think that
it is the only reasonable reading.

So I don't think there is a bug in __cxa_demangle.  As the submitter notes,
there is another demangler, written in C++, in ext/demangle.h.  That demangler
has many more features.  For more general C++ usage, that is the demangler to
use.  The submitter says there is some problem with it, but in my (limited)
experience it works fine.

In closing, I repeat that I think that the API is broken, but I have had very
limited response in my comments about this or about other broken aspects of the
mangling scheme in general.
Comment 6 Ivan Godard 2004-08-01 02:15:21 UTC
This original poster seems to be directed back to the ext/demangle.h which is asserted to be usable. So I'll file a new report on that.

Ivan
Comment 7 Andrew Pinski 2005-01-06 00:59:48 UTC
*** Bug 19284 has been marked as a duplicate of this bug. ***