c++/2166: More mangling bugs
carlo@alinoe.com
carlo@alinoe.com
Sat Mar 3 17:56:00 GMT 2001
>Number: 2166
>Category: c++
>Synopsis: More mangling bugs
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Mar 03 17:56:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: carlo@alinoe.com
>Release: g++-3.0/3.1
>Organization:
>Environment:
any
>Description:
Anonymous namespaces should get a mangled name that
is unique and therefore should include the filename
and/or a truely random part.
Example:
~/c++/libcw/src/gcc.bugs>cat 20010304.cc
int const foo = 3;
namespace {
int unique;
};
~/c++/libcw/src/gcc.bugs>g++-3.0 -c 20010304.cc
~/c++/libcw/src/gcc.bugs>nm 20010304.o
00000000 B _ZN28_GLOBAL_.N.20010304.ccBbrZvd6uniqueE
00000000 r foo
00000000 t gcc2_compiled.
which is correct. However, the code snippet below
results in a mangled name that does NOT contain the
file name or a random part, but instead seems to contain
the mangled name of the first symbol in the file, which
obviously is not random enough:
~/c++/libcw/src/libcwd/tests>g++-3.0 -c mangling.cc && nm mangling.o | grep anon
00000004 B _ZN19_GLOBAL_.N._Z4testv9anonymousE
where "4testv" is supposed to be the random part.
mangling.cc is a test file that I was writing in order
to understand how the mangling works of the new ABI.
It contained at the moment of this failure the following:
// Used helper types.
class prefix { };
class return_type { };
class parameterI { };
class parameterII { };
class parameterIII { };
return_type test(void) { }
struct scopetype {
return_type symbol_scopetype_func(parameterI, parameterII, parameterIII);
return_type symbol_scopetype_func_const(parameterI, parameterII, parameterIII) const;
};
return_type scopetype::symbol_scopetype_func(parameterI, parameterII, parameterIII) { }
return_type scopetype::symbol_scopetype_func_const(parameterI, parameterII, parameterIII) const { }
class ttypeI { };
class ttypeII { };
class ttypeIII { };
// Non-scope parameters (as parameter of nonscopetype_*).
void nonscopetype_void(void) { }
void nonscopetype_ellipsis(...) { }
void nonscopetype_bool(bool) { }
void nonscopetype_float(float) { }
void nonscopetype_double(double) { }
void nonscopetype_long_double(long double) { }
void nonscopetype_wchar_t(wchar_t) { }
void nonscopetype_signed_char(signed char) { }
void nonscopetype_unsigned_char(unsigned char) { }
void nonscopetype_char(char) { }
void nonscopetype_unsigned_short(unsigned short) { }
void nonscopetype_short(short) { }
void nonscopetype_unsigned(unsigned int) { }
void nonscopetype_int(int) { }
void nonscopetype_unsigned_long(unsigned long) { }
void nonscopetype_long(long) { }
void nonscopetype_unsigned_long_long(unsigned long long) { }
void nonscopetype_long_long(long long) { }
void nonscopetype_pointer(prefix*) { }
void nonscopetype_reference(prefix&) { }
void nonscopetype_function_pointer(return_type (*)(parameterI, parameterII, parameterIII)) { }
void nonscopetype_function_reference(return_type (&)(parameterI, parameterII, parameterIII)) { }
void nonscopetype_member_function_pointer(return_type (scopetype::*foo)(parameterI, parameterII, parameterIII)) { }
void nonscopetype_const_member_function_pointer(return_type (scopetype::*foo)(parameterI, parameterII, parameterIII) const) { }
// Scope types.
struct class_name {
void scopetype_class_name(void);
void scopetype_class_name_const(void) const;
};
void class_name::scopetype_class_name(void) { }
void class_name::scopetype_class_name_const(void) const { }
void scopetype_member_function_example_class_name(return_type (class_name::*foo2)(parameterI, parameterII, parameterIII)) { }
void scopetype_member_function_example_class_name_const(return_type (class_name::*foo3)(parameterI, parameterII, parameterIII) const) { }
template<typename ttypeI, typename ttypeII, typename ttypeIII>
struct template_name {
void scopetype_template_name_ttypes(void);
void scopetype_template_name_ttypes_const(void) const;
};
template<typename ttypeI, typename ttypeII, typename ttypeIII>
void template_name<ttypeI, ttypeII, ttypeIII>::scopetype_template_name_ttypes(void) { }
template<typename ttypeI, typename ttypeII, typename ttypeIII>
void template_name<ttypeI, ttypeII, ttypeIII>::scopetype_template_name_ttypes_const(void) const { }
void scopetype_member_function_example_template_name_ttypes(return_type (template_name<ttypeI, ttypeII, ttypeIII>::*foo4)(parameterI, parameterII, parameterIII)) { }
void scopetype_member_function_example_template_name_ttypes_const(return_type (template_name<ttypeI, ttypeII, ttypeIII>::*foo5)(parameterI, parameterII, parameterIII) const) { }
// Possible scope types
scopetype const st = { };
template<class ScopetypeConst> void possiblescopetype_const(ScopetypeConst& foo) { }
struct scopetypeI {
struct scopetypeII {
struct scopetypeIII {
class type { };
};
};
};
void possiblescopetype_scopetypes_type(scopetypeI::scopetypeII::scopetypeIII::type) { }
// Symbols
int symbol_int;
int symbol_func(parameterI, parameterII, parameterIII) { return 0; }
struct scopetypeIV {
struct symbol_constructor_void {
symbol_constructor_void(void);
~symbol_constructor_void();
};
struct symbol_constructor_types {
symbol_constructor_types(parameterI, parameterII, parameterIII);
~symbol_constructor_types();
};
virtual void virtual_func(void);
static int symbol_scopetype_symbol;
};
scopetypeIV::symbol_constructor_void::symbol_constructor_void(void) { }
scopetypeIV::symbol_constructor_types::symbol_constructor_types(parameterI, parameterII, parameterIII) { }
scopetypeIV::symbol_constructor_void::~symbol_constructor_void() { }
scopetypeIV::symbol_constructor_types::~symbol_constructor_types() { }
void scopetypeIV::virtual_func(void) { }
int scopetypeIV::symbol_scopetype_symbol;
// Template instantiation
int main(void)
{
template_name<ttypeI, ttypeII, ttypeIII> instantiate;
instantiate.scopetype_template_name_ttypes();
possiblescopetype_const(st);
return 0;
}
namespace {
int anonymous;
}
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-bugs
mailing list