* Re: enable-build-with-cxx bootstrap compare broken by r149964
[not found] ` <4A8F1EE7.9030001@redhat.com>
@ 2009-08-22 18:57 ` Jerry Quinn
0 siblings, 0 replies; 9+ messages in thread
From: Jerry Quinn @ 2009-08-22 18:57 UTC (permalink / raw)
To: Richard Henderson
Cc: Dave Korn, Jason Merrill, gcc, Pedro Lamarão, gcc-patches
On Fri, 2009-08-21 at 15:25 -0700, Richard Henderson wrote:
> On 08/21/2009 02:37 PM, Jerry Quinn wrote:
> > OK, I've gotten almost this far and can bootstrap (the asterisk is
> > actually not the very first char and I have to figure that out).
> > However, in the referenced test case, both typeinfos are apparently
> > merged, thus returning the same pointer for their name strings, so
> > pointer comparison still wouldn't work.
> >
> > Therefore, I guess I'll need to do the following:
> >
> >> You might also need to take steps to ensure that the typeinfo gets emitted
> >> as non-COMDAT with local symbols, so that each object does indeed end up with
> >> its own separate copy.
> >
> > Where should I look to do this?
>
> First thing you should do is make sure you're emitting a VAR_DECL
> with the string contents, rather than a STRING_CST constant. The
> later will be merged within an object file within the compiler.
>
> Second, make sure the VAR_DECL for the typeinfo is no DECL_ONE_ONLY.
> That flag sets up COMDAT sections, which will be merged by the linker.
It looks like I"ve got a working patch now. It bootstraps and has no
reqressions from make check, nor from make check in the libstdc++
directory.
Any thoughts?
Jerry
2009-08-22 Jerry Quinn <jlquinn@optonline.net>
* name-lookup.c (get_anonymous_namespace_name): Use fixed
namespace "cxx_anon_ns".
* mangle.c (write_nested_name): Insert '*' to mark fake anonymous
namespace.
(get_mangled_string_length): New function.
(mangle_type_string_for_rtti): Put '*' at start of mangled namestring.
* rtti.c (tinfo_base_init): Disable DECL_COMDAT for fake
anonymous namespaces.
2009-08-22 Jerry Quinn <jlquinn@optonline.net>
* libsupc++/tinfo.cc (typeinfo::operator==): Compare names
starting with '*' by pointer.
* libsupc++/tinfo2.cc (typeinfo::before): Same.
* libsupc++/typeinfo (typeinfo::operator==): Same.
* libsupc++/typeinfo (typeinfo::before): Same.
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c (revision 151008)
+++ gcc/cp/rtti.c (working copy)
@@ -862,9 +862,12 @@
DECL_TINFO_P (name_decl) = 1;
set_linkage_according_to_type (target, name_decl);
import_export_decl (name_decl);
+ /* Disable DECL_COMDAT if we have an anonymous namspace here. */
+ if (TREE_STRING_POINTER (name_string)[0] == '*')
+ DECL_COMDAT (name_decl) = 0;
DECL_INITIAL (name_decl) = name_string;
mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string);
2009-08-21 Jakub Jelinek <jakub@redhat.com>
PR c++/41131
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c (revision 151008)
+++ gcc/cp/mangle.c (working copy)
@@ -935,8 +935,14 @@
/* No, just use <prefix> */
write_prefix (DECL_CONTEXT (decl));
if (needs_fake_anon (decl))
- /* Pretend this static function is in an anonymous namespace. */
- write_source_name (get_anonymous_namespace_name ());
+ {
+ /* Add a * to mark fake anonymous namespaces in typeinfos as
+ compare-by-pointer. This * is used to put another one at the
+ front when done building the string. */
+ write_char ('*');
+ /* Pretend this static function is in an anonymous namespace. */
+ write_source_name (get_anonymous_namespace_name ());
+ }
write_unqualified_name (decl);
}
write_char ('E');
@@ -2755,6 +2761,14 @@
name_base = obstack_alloc (&name_obstack, 0);
}
+/* Returns the length of the mangled string array. */
+
+static inline int
+get_mangled_string_length (void)
+{
+ return obstack_object_size (mangle_obstack);
+}
+
/* Done with mangling. If WARN is true, and the name of G.entity will
be mangled differently in a future version of the ABI, issue a
warning. */
@@ -2851,13 +2865,20 @@
mangle_type_string_for_rtti (const tree type)
{
const char *result;
+ int result_len;
start_mangling (type);
/* Mangle in a fake anonymous namespace if necessary. */
fake_anon_scope = true;
+ /* Place marker to be removed if not dealing with a nested name. */
+ write_char('*');
write_type (type);
fake_anon_scope = false;
+ result_len = get_mangled_string_length ();
result = finish_mangling (/*warn=*/false);
+ /* Remove the marker if not needed. */
+ if (!strchr(result + 1, '*'))
+ result++;
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
return result;
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c (revision 151008)
+++ gcc/cp/name-lookup.c (working copy)
@@ -69,7 +69,7 @@
{
/* The anonymous namespace has to have a unique name
if typeinfo objects are being compared by name. */
- anonymous_namespace_name = get_file_function_name ("N");
+ anonymous_namespace_name = get_identifier ("cxx_anon_ns");
}
return anonymous_namespace_name;
}
Index: libstdc++-v3/libsupc++/tinfo2.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo2.cc (revision 151008)
+++ libstdc++-v3/libsupc++/tinfo2.cc (working copy)
@@ -37,7 +37,9 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
- return __builtin_strcmp (name (), arg.name ()) < 0;
+ return (name ()[0] == '*' && arg.name()[0] == '*')
+ ? name () < arg.name ()
+ : __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}
Index: libstdc++-v3/libsupc++/typeinfo
===================================================================
--- libstdc++-v3/libsupc++/typeinfo (revision 151008)
+++ libstdc++-v3/libsupc++/typeinfo (working copy)
@@ -110,12 +110,15 @@
// we can run into cases where type_info names aren't merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const
- { return __builtin_strcmp (__name, __arg.__name) < 0; }
+ { return (__name[0] == '*' && __arg.__name[0] == '*')
+ ? __name < __arg.__name
+ : __builtin_strcmp (__name, __arg.__name) < 0; }
bool operator==(const type_info& __arg) const
{
return ((__name == __arg.__name)
- || __builtin_strcmp (__name, __arg.__name) == 0);
+ || (__name[0] != '*' && __arg.__name[0] != '*' &&
+ __builtin_strcmp (__name, __arg.__name) == 0));
}
#else
// On some targets we can rely on type_info's NTBS being unique,
Index: libstdc++-v3/libsupc++/tinfo.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo.cc (revision 151008)
+++ libstdc++-v3/libsupc++/tinfo.cc (working copy)
@@ -41,7 +41,9 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () == arg.name ();
#else
- return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) ==
0);
+ return (&arg == this)
+ || (name ()[0] != '*' && arg.name ()[0] != '*'
+ && (__builtin_strcmp (name (), arg.name ()) == 0));
#endif
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
[not found] ` <4ABA391C.2050903@redhat.com>
@ 2009-10-24 5:28 ` Jerry Quinn
2009-10-26 11:15 ` Jakub Jelinek
0 siblings, 1 reply; 9+ messages in thread
From: Jerry Quinn @ 2009-10-24 5:28 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC, gcc-patches
On Wed, 2009-09-23 at 11:05 -0400, Jason Merrill wrote:
> On 09/23/2009 09:22 AM, Jerry Quinn wrote:
> > I'm not really sure how everything fits together here. Am I missing
> > something obvious?
>
> I notice that you're missing the fix_string_type that tinfo_name does.
> But I'd rather not duplicate the code that creates the STRING_CST;
> better to delay the call to tinfo_name and add the * there.
>
> Jason
Hi, Jason,
Sorry, it took me a while to get back to this.
Here's the latest patch I have updated to today's tree. It fixes
bootstrap, but there are a number of testsuite failures. They all
appear to plugin test failures similar to below. I don't know if this
is related to my patch or is caused by some other issue when building
with --enable-build-with-cxx.
PR 40923 is about the bootstrap problem, and I've attached the patch
there as well.
Jerry
Executing on build: gcc -g
-O2 /home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/g
++.dg/plugin/dumb_plugin.c -I.
-I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite
-I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/../../gcc
-I/home/jlquinn/gcc/dev/build/trunk-cxx/gcc/testsuite/g++/../../../gcc
-I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/../../include
-I/home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/../../libcpp/include
-DIN_GCC -fPIC -shared -o dumb_plugin.so (timeout = 300)
set_ld_library_path_env_vars:
ld_library_path=.:/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/./libstdc++-v3/src/.libs:/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/./libstdc++-v3/src/.libs:/home/jlquinn/gcc/dev/build/trunk-cxx/gcc:/home/jlquinn/gcc/dev/build/trunk-cxx/gcc/32
Executing on host: /home/jlquinn/gcc/dev/build/trunk-cxx/gcc/testsuite/g
++/../../g++ -B/home/jlquinn/gcc/dev/build/trunk-cxx/gcc/testsuite/g
++/../../ /home/jlquinn/gcc/dev/gcc-in-cxx/gcc/testsuite/g
++.dg/plugin/dumb-plugin-test-1.C -nostdinc++
-I/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/libstdc
++-v3/include/x86_64-unknown-linux-gnu
-I/home/jlquinn/gcc/dev/build/trunk-cxx/x86_64-unknown-linux-gnu/libstdc
++-v3/include -I/home/jlquinn/gcc/dev/gcc-in-cxx/libstdc++-v3/libsupc++
-I/home/jlquinn/gcc/dev/gcc-in-cxx/libstdc++-v3/include/backward
-I/home/jlquinn/gcc/dev/gcc-in-cxx/libstdc++-v3/testsuite/util
-fmessage-length=0 -fplugin=./dumb_plugin.so -O
-fplugin-arg-dumb_plugin-ref-pass-name=ccp
-fplugin-arg-dumb_plugin-ref-pass-instance-num=1 -S -o
dumb-plugin-test-1.s (timeout = 300)
cc1plus: error: Cannot load plugin ./dumb_plugin.so
./dumb_plugin.so: undefined symbol: tree_check_failed
compiler exited with status 1
output is:
cc1plus: error: Cannot load plugin ./dumb_plugin.so
./dumb_plugin.so: undefined symbol: tree_check_failed
FAIL: g++.dg/plugin/dumb-plugin-test-1.C -fplugin=./dumb_plugin.so
(test for warnings, line 10)
Patch below:
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c (revision 153489)
+++ gcc/cp/rtti.c (working copy)
@@ -102,7 +102,7 @@
static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
static tree ifnonnull (tree, tree);
-static tree tinfo_name (tree);
+static tree tinfo_name (tree, bool);
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
@@ -349,16 +349,31 @@
return exp;
}
-/* Generate the NTBS name of a type. */
+/* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in
front so that
+ comparisons will be done by pointer rather than string comparison.
*/
static tree
-tinfo_name (tree type)
+tinfo_name (tree type, bool mark_private)
{
const char *name;
+ int length;
tree name_string;
- name = mangle_type_string_for_rtti (type);
- name_string = fix_string_type (build_string (strlen (name) + 1,
name));
- return name_string;
+ name = mangle_type_string (type);
+ length = strlen (name);
+
+ if (mark_private)
+ {
+ /* Inject '*' at beginning of name to force pointer comparison.
*/
+ char* buf = (char*) XNEWVEC (char, length + 1);
+ buf[0] = '*';
+ memcpy (buf + 1, name, length);
+ name_string = build_string (length + 1, buf);
+ XDELETEVEC (buf);
+ }
+ else
+ name_string = build_string (length + 1, name);
+
+ return fix_string_type (name_string);
}
/* Return a VAR_DECL for the internal ABI defined type_info object for
@@ -839,13 +854,13 @@
tree vtable_ptr;
{
- tree name_name;
+ tree name_name, name_string;
/* Generate the NTBS array variable. */
tree name_type = build_cplus_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
NULL_TREE);
- tree name_string = tinfo_name (target);
+ // tree name_string = tinfo_name (target);
/* Determine the name of the variable -- and remember with which
type it is associated. */
@@ -862,6 +877,7 @@
DECL_TINFO_P (name_decl) = 1;
set_linkage_according_to_type (target, name_decl);
import_export_decl (name_decl);
+ name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
DECL_INITIAL (name_decl) = name_string;
mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string);
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c (revision 153489)
+++ gcc/cp/mangle.c (working copy)
@@ -105,10 +105,6 @@
static GTY (()) globals G;
-/* Whether or not to pretend that a static function is in an anonymous
- namespace. */
-static bool fake_anon_scope;
-
/* The obstack on which we build mangled names. */
static struct obstack *mangle_obstack;
@@ -734,20 +730,6 @@
}
}
-/* Since we now use strcmp to compare typeinfos on all targets because
of
- the RTLD_LOCAL problem, we need to munge the typeinfo name used for
- local classes of static functions to fix g++.dg/abi/local1.C. We do
- that by pretending that the function is in an anonymous namespace.
*/
-
-static bool
-needs_fake_anon (const_tree decl)
-{
- /* Pretend there's an anonymous namespace right around a static
- function if we're mangling for RTTI. */
- return (fake_anon_scope && !TREE_PUBLIC (decl)
- && TREE_CODE (decl) == FUNCTION_DECL);
-}
-
/* Lambdas can have a bit more context for mangling, specifically
VAR_DECL
or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
@@ -791,18 +773,13 @@
context = decl_mangling_context (decl);
- gcc_assert (context != NULL_TREE);
-
- /* If we need a fake anonymous namespace, force the nested name path.
*/
- if (needs_fake_anon (decl) && context == global_namespace)
- context = error_mark_node;
-
/* A decl in :: or ::std scope is treated specially. The former is
mangled using <unscoped-name> or <unscoped-template-name>, the
latter with a special substitution. Also, a name that is
directly in a local function scope is also mangled with
<unscoped-name> rather than a full <nested-name>. */
- if (context == global_namespace
+ if (context == NULL
+ || context == global_namespace
|| DECL_NAMESPACE_STD_P (context)
|| (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
{
@@ -820,9 +797,6 @@
}
else
{
- if (context == error_mark_node)
- context = global_namespace;
-
/* Handle local names, unless we asked not to (that is, invoked
under <local-name>, to handle only the part of the name under
the local scope). */
@@ -835,10 +809,10 @@
directly in that function's scope, either decl or one of
its enclosing scopes. */
tree local_entity = decl;
- while (context != global_namespace)
+ while (context != NULL && context != global_namespace)
{
/* Make sure we're always dealing with decls. */
- if (TYPE_P (context))
+ if (context != NULL && TYPE_P (context))
context = TYPE_NAME (context);
/* Is this a function? */
if (TREE_CODE (context) == FUNCTION_DECL
@@ -883,6 +857,7 @@
/* If not, it should be either in the global namespace, or
directly
in a local function scope. */
gcc_assert (context == global_namespace
+ || context != NULL
|| TREE_CODE (context) == FUNCTION_DECL);
write_unqualified_name (decl);
@@ -954,9 +929,6 @@
{
/* No, just use <prefix> */
write_prefix (DECL_CONTEXT (decl));
- if (needs_fake_anon (decl))
- /* Pretend this static function is in an anonymous namespace. */
- write_source_name (get_anonymous_namespace_name ());
write_unqualified_name (decl);
}
write_char ('E');
@@ -2921,10 +2893,6 @@
name_base = obstack_alloc (&name_obstack, 0);
}
-/* Done with mangling. If WARN is true, and the name of G.entity will
- be mangled differently in a future version of the ABI, issue a
- warning. */
-
static void
finish_mangling_internal (const bool warn)
{
@@ -3011,18 +2979,15 @@
SET_DECL_ASSEMBLER_NAME (decl, id);
}
-/* Generate the mangled representation of TYPE for the typeinfo name.
*/
+/* Generate the mangled representation of TYPE. */
const char *
-mangle_type_string_for_rtti (const tree type)
+mangle_type_string (const tree type)
{
const char *result;
start_mangling (type);
- /* Mangle in a fake anonymous namespace if necessary. */
- fake_anon_scope = true;
write_type (type);
- fake_anon_scope = false;
result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h (revision 153489)
+++ gcc/cp/cp-tree.h (working copy)
@@ -4507,7 +4507,6 @@
extern tree perform_qualification_conversions (tree, tree);
/* in name-lookup.c */
-extern tree get_anonymous_namespace_name (void);
extern tree pushdecl (tree);
extern tree pushdecl_maybe_friend (tree, bool);
extern void maybe_push_cleanup_level (tree);
@@ -5288,7 +5287,7 @@
/* in mangle.c */
extern void init_mangle (void);
extern void mangle_decl (tree);
-extern const char *mangle_type_string_for_rtti (tree);
+extern const char *mangle_type_string (tree);
extern tree mangle_typeinfo_for_type (tree);
extern tree mangle_typeinfo_string_for_type (tree);
extern tree mangle_vtbl_for_type (tree);
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c (revision 153489)
+++ gcc/cp/name-lookup.c (working copy)
@@ -69,7 +69,12 @@
{
/* The anonymous namespace has to have a unique name
if typeinfo objects are being compared by name. */
- anonymous_namespace_name = get_file_function_name ("N");
+ if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+ anonymous_namespace_name = get_file_function_name ("N");
+ else
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
}
return anonymous_namespace_name;
}
Index: libstdc++-v3/libsupc++/tinfo2.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo2.cc (revision 153489)
+++ libstdc++-v3/libsupc++/tinfo2.cc (working copy)
@@ -37,7 +37,9 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
- return __builtin_strcmp (name (), arg.name ()) < 0;
+ return (name ()[0] == '*' && arg.name()[0] == '*')
+ ? name () < arg.name ()
+ : __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}
Index: libstdc++-v3/libsupc++/typeinfo
===================================================================
--- libstdc++-v3/libsupc++/typeinfo (revision 153489)
+++ libstdc++-v3/libsupc++/typeinfo (working copy)
@@ -94,7 +94,7 @@
/** Returns an @e implementation-defined byte string; this is not
* portable between compilers! */
const char* name() const
- { return __name; }
+ { return __name[0] == '*' ? __name + 1 : __name; }
#if !__GXX_TYPEINFO_EQUALITY_INLINE
// In old abi, or when weak symbols are not supported, there can
@@ -110,12 +110,15 @@
// we can run into cases where type_info names aren't merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const
- { return __builtin_strcmp (__name, __arg.__name) < 0; }
+ { return (__name[0] == '*' && __arg.__name[0] == '*')
+ ? __name < __arg.__name
+ : __builtin_strcmp (__name, __arg.__name) < 0; }
bool operator==(const type_info& __arg) const
{
return ((__name == __arg.__name)
- || __builtin_strcmp (__name, __arg.__name) == 0);
+ || (__name[0] != '*' && __arg.__name[0] != '*' &&
+ __builtin_strcmp (__name, __arg.__name) == 0));
}
#else
// On some targets we can rely on type_info's NTBS being unique,
Index: libstdc++-v3/libsupc++/tinfo.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo.cc (revision 153489)
+++ libstdc++-v3/libsupc++/tinfo.cc (working copy)
@@ -41,7 +41,9 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () == arg.name ();
#else
- return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) ==
0);
+ return (&arg == this)
+ || (name ()[0] != '*' && arg.name ()[0] != '*'
+ && (__builtin_strcmp (name (), arg.name ()) == 0));
#endif
}
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-24 5:28 ` Jerry Quinn
@ 2009-10-26 11:15 ` Jakub Jelinek
2009-10-26 14:42 ` Jason Merrill
0 siblings, 1 reply; 9+ messages in thread
From: Jakub Jelinek @ 2009-10-26 11:15 UTC (permalink / raw)
To: Jerry Quinn; +Cc: Jason Merrill, GCC, gcc-patches
Hi!
Just some random comments:
On Sat, Oct 24, 2009 at 12:10:52AM -0400, Jerry Quinn wrote:
> + if (mark_private)
> + {
> + /* Inject '*' at beginning of name to force pointer comparison.
> */
> + char* buf = (char*) XNEWVEC (char, length + 1);
> + buf[0] = '*';
> + memcpy (buf + 1, name, length);
> + name_string = build_string (length + 1, buf);
> + XDELETEVEC (buf);
You could as well use XALLOCAVEC (char, length + 1) and remove
XDELETEVEC. No need to cast the result of XNEWVEC or XALLOCAVEC to
char *. And, the formatting is wrong, space goes after char, no space
between * and buf.
> /* Generate the NTBS array variable. */
> tree name_type = build_cplus_array_type
> (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
> NULL_TREE);
> - tree name_string = tinfo_name (target);
> + // tree name_string = tinfo_name (target);
This should be removed, rather than commented out.
> @@ -2921,10 +2893,6 @@
> name_base = obstack_alloc (&name_obstack, 0);
> }
>
> -/* Done with mangling. If WARN is true, and the name of G.entity will
> - be mangled differently in a future version of the ABI, issue a
> - warning. */
> -
> static void
> finish_mangling_internal (const bool warn)
> {
Why are you removing the comment?
> @@ -3011,18 +2979,15 @@
> SET_DECL_ASSEMBLER_NAME (decl, id);
> }
>
> -/* Generate the mangled representation of TYPE for the typeinfo name.
> */
> +/* Generate the mangled representation of TYPE. */
>
> const char *
> -mangle_type_string_for_rtti (const tree type)
> +mangle_type_string (const tree type)
Why this change?
> bool operator==(const type_info& __arg) const
> {
> return ((__name == __arg.__name)
> - || __builtin_strcmp (__name, __arg.__name) == 0);
> + || (__name[0] != '*' && __arg.__name[0] != '*' &&
> + __builtin_strcmp (__name, __arg.__name) == 0));
I see no point in both tests for * here, just __name[0] != '*'
should be enough (or __arg.__name[0] != '*'). If one string starts with *
and the other doesn't, strcmp will return non-0.
> --- libstdc++-v3/libsupc++/tinfo.cc (revision 153489)
> +++ libstdc++-v3/libsupc++/tinfo.cc (working copy)
> @@ -41,7 +41,9 @@
> #if __GXX_MERGED_TYPEINFO_NAMES
> return name () == arg.name ();
> #else
> - return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) ==
> 0);
> + return (&arg == this)
> + || (name ()[0] != '*' && arg.name ()[0] != '*'
> + && (__builtin_strcmp (name (), arg.name ()) == 0));
> #endif
> }
Likewise.
Jakub
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-26 11:15 ` Jakub Jelinek
@ 2009-10-26 14:42 ` Jason Merrill
2009-10-28 12:49 ` Jerry Quinn
0 siblings, 1 reply; 9+ messages in thread
From: Jason Merrill @ 2009-10-26 14:42 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Jerry Quinn, GCC, gcc-patches
On 10/26/2009 07:14 AM, Jakub Jelinek wrote:
>> -/* Generate the mangled representation of TYPE for the typeinfo name.
>> */
>> +/* Generate the mangled representation of TYPE. */
>>
>> const char *
>> -mangle_type_string_for_rtti (const tree type)
>> +mangle_type_string (const tree type)
>
> Why this change?
This change is part of reverting my earlier fake namespace patch.
I agree with Jakub's other comments, though.
Jason
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-26 14:42 ` Jason Merrill
@ 2009-10-28 12:49 ` Jerry Quinn
2009-10-28 15:52 ` Jason Merrill
0 siblings, 1 reply; 9+ messages in thread
From: Jerry Quinn @ 2009-10-28 12:49 UTC (permalink / raw)
To: Jason Merrill; +Cc: Jakub Jelinek, GCC, gcc-patches
On Mon, 2009-10-26 at 09:53 -0400, Jason Merrill wrote:
> On 10/26/2009 07:14 AM, Jakub Jelinek wrote:
> >> -/* Generate the mangled representation of TYPE for the typeinfo name.
> >> */
> >> +/* Generate the mangled representation of TYPE. */
> >>
> >> const char *
> >> -mangle_type_string_for_rtti (const tree type)
> >> +mangle_type_string (const tree type)
> >
> > Why this change?
>
> This change is part of reverting my earlier fake namespace patch.
>
> I agree with Jakub's other comments, though.
>
> Jason
Here's the updated patch.
2009-10-28 Jerry Quinn <jlquinn@optonline.net>
* mangle.c (mangle_type_string_for_rtti): Revert r149964.
(needs_fake_anon): Likewise.
(write_name): Likewise.
(write_nested_name): Likewise.
* cp-tree.h (mangle_type_string_for_rtti): Likewise.
(get_anonymous_namespace): Likewise.
* name-lookup.c (get_anonymous_namespace_name): Likewise.
* rtti.c (tinfo_name): Insert '*' in front of private names.
(tinfo_base_init): Use it.
2009-10-28 Jerry Quinn <jlquinn@optonline.net>
* libsupc++/tinfo.cc (operator=(const type_info&)): Compare by
pointer if name begins with '*'.
* libsupc++/typeinfo (type_info::name()): Likewise.
* libsupc++/tinfo2.cc (before): Likewise.
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c (revision 153489)
+++ gcc/cp/rtti.c (working copy)
@@ -102,7 +102,7 @@
static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
static tree ifnonnull (tree, tree);
-static tree tinfo_name (tree);
+static tree tinfo_name (tree, bool);
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
@@ -349,16 +349,30 @@
return exp;
}
-/* Generate the NTBS name of a type. */
+/* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in
front so that
+ comparisons will be done by pointer rather than string comparison.
*/
static tree
-tinfo_name (tree type)
+tinfo_name (tree type, bool mark_private)
{
const char *name;
+ int length;
tree name_string;
- name = mangle_type_string_for_rtti (type);
- name_string = fix_string_type (build_string (strlen (name) + 1,
name));
- return name_string;
+ name = mangle_type_string (type);
+ length = strlen (name);
+
+ if (mark_private)
+ {
+ /* Inject '*' at beginning of name to force pointer comparison.
*/
+ char* buf = (char*) XALLOCAVEC (char, length + 1);
+ buf[0] = '*';
+ memcpy (buf + 1, name, length);
+ name_string = build_string (length + 1, buf);
+ }
+ else
+ name_string = build_string (length + 1, name);
+
+ return fix_string_type (name_string);
}
/* Return a VAR_DECL for the internal ABI defined type_info object for
@@ -839,13 +853,12 @@
tree vtable_ptr;
{
- tree name_name;
+ tree name_name, name_string;
/* Generate the NTBS array variable. */
tree name_type = build_cplus_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
NULL_TREE);
- tree name_string = tinfo_name (target);
/* Determine the name of the variable -- and remember with which
type it is associated. */
@@ -862,6 +875,7 @@
DECL_TINFO_P (name_decl) = 1;
set_linkage_according_to_type (target, name_decl);
import_export_decl (name_decl);
+ name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
DECL_INITIAL (name_decl) = name_string;
mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string);
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog (revision 153489)
+++ gcc/cp/ChangeLog (working copy)
@@ -1,3 +1,15 @@
+2009-10-28 Jerry Quinn <jlquinn@optonline.net>
+
+ * mangle.c (mangle_type_string_for_rtti): Revert r149964.
+ (needs_fake_anon): Likewise.
+ (write_name): Likewise.
+ (write_nested_name): Likewise.
+ * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+ (get_anonymous_namespace): Likewise.
+ * name-lookup.c (get_anonymous_namespace_name): Likewise.
+ * rtti.c (tinfo_name): Insert '*' in front of private names.
+ (tinfo_base_init): Use it.
+
2009-10-21 Jakub Jelinek <jakub@redhat.com>
* mangle.c (finish_mangling_get_identifier): Use
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c (revision 153489)
+++ gcc/cp/mangle.c (working copy)
@@ -105,10 +105,6 @@
static GTY (()) globals G;
-/* Whether or not to pretend that a static function is in an anonymous
- namespace. */
-static bool fake_anon_scope;
-
/* The obstack on which we build mangled names. */
static struct obstack *mangle_obstack;
@@ -734,20 +730,6 @@
}
}
-/* Since we now use strcmp to compare typeinfos on all targets because
of
- the RTLD_LOCAL problem, we need to munge the typeinfo name used for
- local classes of static functions to fix g++.dg/abi/local1.C. We do
- that by pretending that the function is in an anonymous namespace.
*/
-
-static bool
-needs_fake_anon (const_tree decl)
-{
- /* Pretend there's an anonymous namespace right around a static
- function if we're mangling for RTTI. */
- return (fake_anon_scope && !TREE_PUBLIC (decl)
- && TREE_CODE (decl) == FUNCTION_DECL);
-}
-
/* Lambdas can have a bit more context for mangling, specifically
VAR_DECL
or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
@@ -791,18 +773,13 @@
context = decl_mangling_context (decl);
- gcc_assert (context != NULL_TREE);
-
- /* If we need a fake anonymous namespace, force the nested name path.
*/
- if (needs_fake_anon (decl) && context == global_namespace)
- context = error_mark_node;
-
/* A decl in :: or ::std scope is treated specially. The former is
mangled using <unscoped-name> or <unscoped-template-name>, the
latter with a special substitution. Also, a name that is
directly in a local function scope is also mangled with
<unscoped-name> rather than a full <nested-name>. */
- if (context == global_namespace
+ if (context == NULL
+ || context == global_namespace
|| DECL_NAMESPACE_STD_P (context)
|| (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
{
@@ -820,9 +797,6 @@
}
else
{
- if (context == error_mark_node)
- context = global_namespace;
-
/* Handle local names, unless we asked not to (that is, invoked
under <local-name>, to handle only the part of the name under
the local scope). */
@@ -835,10 +809,10 @@
directly in that function's scope, either decl or one of
its enclosing scopes. */
tree local_entity = decl;
- while (context != global_namespace)
+ while (context != NULL && context != global_namespace)
{
/* Make sure we're always dealing with decls. */
- if (TYPE_P (context))
+ if (context != NULL && TYPE_P (context))
context = TYPE_NAME (context);
/* Is this a function? */
if (TREE_CODE (context) == FUNCTION_DECL
@@ -883,6 +857,7 @@
/* If not, it should be either in the global namespace, or
directly
in a local function scope. */
gcc_assert (context == global_namespace
+ || context != NULL
|| TREE_CODE (context) == FUNCTION_DECL);
write_unqualified_name (decl);
@@ -954,9 +929,6 @@
{
/* No, just use <prefix> */
write_prefix (DECL_CONTEXT (decl));
- if (needs_fake_anon (decl))
- /* Pretend this static function is in an anonymous namespace. */
- write_source_name (get_anonymous_namespace_name ());
write_unqualified_name (decl);
}
write_char ('E');
@@ -3011,18 +2983,15 @@
SET_DECL_ASSEMBLER_NAME (decl, id);
}
-/* Generate the mangled representation of TYPE for the typeinfo name.
*/
+/* Generate the mangled representation of TYPE. */
const char *
-mangle_type_string_for_rtti (const tree type)
+mangle_type_string (const tree type)
{
const char *result;
start_mangling (type);
- /* Mangle in a fake anonymous namespace if necessary. */
- fake_anon_scope = true;
write_type (type);
- fake_anon_scope = false;
result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h (revision 153489)
+++ gcc/cp/cp-tree.h (working copy)
@@ -4507,7 +4507,6 @@
extern tree perform_qualification_conversions (tree, tree);
/* in name-lookup.c */
-extern tree get_anonymous_namespace_name (void);
extern tree pushdecl (tree);
extern tree pushdecl_maybe_friend (tree, bool);
extern void maybe_push_cleanup_level (tree);
@@ -5288,7 +5287,7 @@
/* in mangle.c */
extern void init_mangle (void);
extern void mangle_decl (tree);
-extern const char *mangle_type_string_for_rtti (tree);
+extern const char *mangle_type_string (tree);
extern tree mangle_typeinfo_for_type (tree);
extern tree mangle_typeinfo_string_for_type (tree);
extern tree mangle_vtbl_for_type (tree);
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c (revision 153489)
+++ gcc/cp/name-lookup.c (working copy)
@@ -62,14 +62,19 @@
/* Initialize anonymous_namespace_name if necessary, and return it. */
-tree
+static tree
get_anonymous_namespace_name (void)
{
if (!anonymous_namespace_name)
{
/* The anonymous namespace has to have a unique name
if typeinfo objects are being compared by name. */
- anonymous_namespace_name = get_file_function_name ("N");
+ if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+ anonymous_namespace_name = get_file_function_name ("N");
+ else
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
}
return anonymous_namespace_name;
}
Index: libstdc++-v3/libsupc++/tinfo2.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo2.cc (revision 153489)
+++ libstdc++-v3/libsupc++/tinfo2.cc (working copy)
@@ -37,7 +37,8 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
- return __builtin_strcmp (name (), arg.name ()) < 0;
+ return (name ()[0] == '*') ? name () < arg.name ()
+ : __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}
Index: libstdc++-v3/libsupc++/typeinfo
===================================================================
--- libstdc++-v3/libsupc++/typeinfo (revision 153489)
+++ libstdc++-v3/libsupc++/typeinfo (working copy)
@@ -94,7 +94,7 @@
/** Returns an @e implementation-defined byte string; this is not
* portable between compilers! */
const char* name() const
- { return __name; }
+ { return __name[0] == '*' ? __name + 1 : __name; }
#if !__GXX_TYPEINFO_EQUALITY_INLINE
// In old abi, or when weak symbols are not supported, there can
@@ -110,12 +110,15 @@
// we can run into cases where type_info names aren't merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const
- { return __builtin_strcmp (__name, __arg.__name) < 0; }
+ { return (__name[0] == '*' && __arg.__name[0] == '*')
+ ? __name < __arg.__name
+ : __builtin_strcmp (__name, __arg.__name) < 0; }
bool operator==(const type_info& __arg) const
{
return ((__name == __arg.__name)
- || __builtin_strcmp (__name, __arg.__name) == 0);
+ || (__name[0] != '*' &&
+ __builtin_strcmp (__name, __arg.__name) == 0));
}
#else
// On some targets we can rely on type_info's NTBS being unique,
Index: libstdc++-v3/libsupc++/tinfo.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo.cc (revision 153489)
+++ libstdc++-v3/libsupc++/tinfo.cc (working copy)
@@ -41,7 +41,8 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () == arg.name ();
#else
- return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) ==
0);
+ return (&arg == this)
+ || (name ()[0] != '*' && (__builtin_strcmp (name (), arg.name ())
== 0));
#endif
}
Index: libstdc++-v3/ChangeLog
===================================================================
--- libstdc++-v3/ChangeLog (revision 153489)
+++ libstdc++-v3/ChangeLog (working copy)
@@ -1,3 +1,10 @@
+2009-10-28 Jerry Quinn <jlquinn@optonline.net>
+
+ * libsupc++/tinfo.cc (operator=(const type_info&)): Compare by
+ pointer if name begins with '*'.
+ * libsupc++/typeinfo (type_info::name()): Likewise.
+ * libsupc++/tinfo2.cc (before): Likewise.
+
009-10-20 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/41773
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-28 12:49 ` Jerry Quinn
@ 2009-10-28 15:52 ` Jason Merrill
2009-10-29 5:35 ` Jerry Quinn
0 siblings, 1 reply; 9+ messages in thread
From: Jason Merrill @ 2009-10-28 15:52 UTC (permalink / raw)
To: Jerry Quinn; +Cc: Jakub Jelinek, GCC, gcc-patches
On 10/28/2009 07:29 AM, Jerry Quinn wrote:
> + length = strlen (name);
> + if (mark_private)
> + name_string = build_string (length + 1, buf);
> + else
> + name_string = build_string (length + 1, name);
These two calls shouldn't be using the same length. I think the +1 in
the old code was unnecessary, so you can just remove it from the second
call.
Jason
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-28 15:52 ` Jason Merrill
@ 2009-10-29 5:35 ` Jerry Quinn
2009-10-29 6:45 ` Jason Merrill
0 siblings, 1 reply; 9+ messages in thread
From: Jerry Quinn @ 2009-10-29 5:35 UTC (permalink / raw)
To: Jason Merrill; +Cc: Jakub Jelinek, GCC, gcc-patches
On Wed, 2009-10-28 at 11:35 -0400, Jason Merrill wrote:
> On 10/28/2009 07:29 AM, Jerry Quinn wrote:
> > + length = strlen (name);
> > + if (mark_private)
> > + name_string = build_string (length + 1, buf);
> > + else
> > + name_string = build_string (length + 1, name);
>
> These two calls shouldn't be using the same length. I think the +1 in
> the old code was unnecessary, so you can just remove it from the second
> call.
And here is the latest patch.
Index: gcc/cp/rtti.c
===================================================================
--- gcc/cp/rtti.c (revision 153489)
+++ gcc/cp/rtti.c (working copy)
@@ -102,7 +102,7 @@
static GTY (()) VEC(tinfo_s,gc) *tinfo_descs;
static tree ifnonnull (tree, tree);
-static tree tinfo_name (tree);
+static tree tinfo_name (tree, bool);
static tree build_dynamic_cast_1 (tree, tree, tsubst_flags_t);
static tree throw_bad_cast (void);
static tree throw_bad_typeid (void);
@@ -349,16 +349,30 @@
return exp;
}
-/* Generate the NTBS name of a type. */
+/* Generate the NTBS name of a type. If MARK_PRIVATE, put a '*' in
front so that
+ comparisons will be done by pointer rather than string comparison.
*/
static tree
-tinfo_name (tree type)
+tinfo_name (tree type, bool mark_private)
{
const char *name;
+ int length;
tree name_string;
- name = mangle_type_string_for_rtti (type);
- name_string = fix_string_type (build_string (strlen (name) + 1,
name));
- return name_string;
+ name = mangle_type_string (type);
+ length = strlen (name);
+
+ if (mark_private)
+ {
+ /* Inject '*' at beginning of name to force pointer comparison.
*/
+ char* buf = (char*) XALLOCAVEC (char, length + 1);
+ buf[0] = '*';
+ memcpy (buf + 1, name, length);
+ name_string = build_string (length + 1, buf);
+ }
+ else
+ name_string = build_string (length, name);
+
+ return fix_string_type (name_string);
}
/* Return a VAR_DECL for the internal ABI defined type_info object for
@@ -839,13 +853,12 @@
tree vtable_ptr;
{
- tree name_name;
+ tree name_name, name_string;
/* Generate the NTBS array variable. */
tree name_type = build_cplus_array_type
(build_qualified_type (char_type_node, TYPE_QUAL_CONST),
NULL_TREE);
- tree name_string = tinfo_name (target);
/* Determine the name of the variable -- and remember with which
type it is associated. */
@@ -862,6 +875,7 @@
DECL_TINFO_P (name_decl) = 1;
set_linkage_according_to_type (target, name_decl);
import_export_decl (name_decl);
+ name_string = tinfo_name (target, !TREE_PUBLIC (name_decl));
DECL_INITIAL (name_decl) = name_string;
mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string);
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog (revision 153489)
+++ gcc/cp/ChangeLog (working copy)
@@ -1,3 +1,15 @@
+2009-10-28 Jerry Quinn <jlquinn@optonline.net>
+
+ * mangle.c (mangle_type_string_for_rtti): Revert r149964.
+ (needs_fake_anon): Likewise.
+ (write_name): Likewise.
+ (write_nested_name): Likewise.
+ * cp-tree.h (mangle_type_string_for_rtti): Likewise.
+ (get_anonymous_namespace): Likewise.
+ * name-lookup.c (get_anonymous_namespace_name): Likewise.
+ * rtti.c (tinfo_name): Insert '*' in front of private names.
+ (tinfo_base_init): Use it.
+
2009-10-21 Jakub Jelinek <jakub@redhat.com>
* mangle.c (finish_mangling_get_identifier): Use
Index: gcc/cp/mangle.c
===================================================================
--- gcc/cp/mangle.c (revision 153489)
+++ gcc/cp/mangle.c (working copy)
@@ -105,10 +105,6 @@
static GTY (()) globals G;
-/* Whether or not to pretend that a static function is in an anonymous
- namespace. */
-static bool fake_anon_scope;
-
/* The obstack on which we build mangled names. */
static struct obstack *mangle_obstack;
@@ -734,20 +730,6 @@
}
}
-/* Since we now use strcmp to compare typeinfos on all targets because
of
- the RTLD_LOCAL problem, we need to munge the typeinfo name used for
- local classes of static functions to fix g++.dg/abi/local1.C. We do
- that by pretending that the function is in an anonymous namespace.
*/
-
-static bool
-needs_fake_anon (const_tree decl)
-{
- /* Pretend there's an anonymous namespace right around a static
- function if we're mangling for RTTI. */
- return (fake_anon_scope && !TREE_PUBLIC (decl)
- && TREE_CODE (decl) == FUNCTION_DECL);
-}
-
/* Lambdas can have a bit more context for mangling, specifically
VAR_DECL
or PARM_DECL context, which doesn't belong in DECL_CONTEXT. */
@@ -791,18 +773,13 @@
context = decl_mangling_context (decl);
- gcc_assert (context != NULL_TREE);
-
- /* If we need a fake anonymous namespace, force the nested name path.
*/
- if (needs_fake_anon (decl) && context == global_namespace)
- context = error_mark_node;
-
/* A decl in :: or ::std scope is treated specially. The former is
mangled using <unscoped-name> or <unscoped-template-name>, the
latter with a special substitution. Also, a name that is
directly in a local function scope is also mangled with
<unscoped-name> rather than a full <nested-name>. */
- if (context == global_namespace
+ if (context == NULL
+ || context == global_namespace
|| DECL_NAMESPACE_STD_P (context)
|| (ignore_local_scope && TREE_CODE (context) == FUNCTION_DECL))
{
@@ -820,9 +797,6 @@
}
else
{
- if (context == error_mark_node)
- context = global_namespace;
-
/* Handle local names, unless we asked not to (that is, invoked
under <local-name>, to handle only the part of the name under
the local scope). */
@@ -835,10 +809,10 @@
directly in that function's scope, either decl or one of
its enclosing scopes. */
tree local_entity = decl;
- while (context != global_namespace)
+ while (context != NULL && context != global_namespace)
{
/* Make sure we're always dealing with decls. */
- if (TYPE_P (context))
+ if (context != NULL && TYPE_P (context))
context = TYPE_NAME (context);
/* Is this a function? */
if (TREE_CODE (context) == FUNCTION_DECL
@@ -883,6 +857,7 @@
/* If not, it should be either in the global namespace, or
directly
in a local function scope. */
gcc_assert (context == global_namespace
+ || context != NULL
|| TREE_CODE (context) == FUNCTION_DECL);
write_unqualified_name (decl);
@@ -954,9 +929,6 @@
{
/* No, just use <prefix> */
write_prefix (DECL_CONTEXT (decl));
- if (needs_fake_anon (decl))
- /* Pretend this static function is in an anonymous namespace. */
- write_source_name (get_anonymous_namespace_name ());
write_unqualified_name (decl);
}
write_char ('E');
@@ -3011,18 +2983,15 @@
SET_DECL_ASSEMBLER_NAME (decl, id);
}
-/* Generate the mangled representation of TYPE for the typeinfo name.
*/
+/* Generate the mangled representation of TYPE. */
const char *
-mangle_type_string_for_rtti (const tree type)
+mangle_type_string (const tree type)
{
const char *result;
start_mangling (type);
- /* Mangle in a fake anonymous namespace if necessary. */
- fake_anon_scope = true;
write_type (type);
- fake_anon_scope = false;
result = finish_mangling (/*warn=*/false);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h (revision 153489)
+++ gcc/cp/cp-tree.h (working copy)
@@ -4507,7 +4507,6 @@
extern tree perform_qualification_conversions (tree, tree);
/* in name-lookup.c */
-extern tree get_anonymous_namespace_name (void);
extern tree pushdecl (tree);
extern tree pushdecl_maybe_friend (tree, bool);
extern void maybe_push_cleanup_level (tree);
@@ -5288,7 +5287,7 @@
/* in mangle.c */
extern void init_mangle (void);
extern void mangle_decl (tree);
-extern const char *mangle_type_string_for_rtti (tree);
+extern const char *mangle_type_string (tree);
extern tree mangle_typeinfo_for_type (tree);
extern tree mangle_typeinfo_string_for_type (tree);
extern tree mangle_vtbl_for_type (tree);
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c (revision 153489)
+++ gcc/cp/name-lookup.c (working copy)
@@ -62,14 +62,19 @@
/* Initialize anonymous_namespace_name if necessary, and return it. */
-tree
+static tree
get_anonymous_namespace_name (void)
{
if (!anonymous_namespace_name)
{
/* The anonymous namespace has to have a unique name
if typeinfo objects are being compared by name. */
- anonymous_namespace_name = get_file_function_name ("N");
+ if (! flag_weak || ! SUPPORTS_ONE_ONLY)
+ anonymous_namespace_name = get_file_function_name ("N");
+ else
+ /* The demangler expects anonymous namespaces to be called
+ something starting with '_GLOBAL__N_'. */
+ anonymous_namespace_name = get_identifier ("_GLOBAL__N_1");
}
return anonymous_namespace_name;
}
Index: libstdc++-v3/libsupc++/tinfo2.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo2.cc (revision 153489)
+++ libstdc++-v3/libsupc++/tinfo2.cc (working copy)
@@ -37,7 +37,8 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () < arg.name ();
#else
- return __builtin_strcmp (name (), arg.name ()) < 0;
+ return (name ()[0] == '*') ? name () < arg.name ()
+ : __builtin_strcmp (name (), arg.name ()) < 0;
#endif
}
Index: libstdc++-v3/libsupc++/typeinfo
===================================================================
--- libstdc++-v3/libsupc++/typeinfo (revision 153489)
+++ libstdc++-v3/libsupc++/typeinfo (working copy)
@@ -94,7 +94,7 @@
/** Returns an @e implementation-defined byte string; this is not
* portable between compilers! */
const char* name() const
- { return __name; }
+ { return __name[0] == '*' ? __name + 1 : __name; }
#if !__GXX_TYPEINFO_EQUALITY_INLINE
// In old abi, or when weak symbols are not supported, there can
@@ -110,12 +110,15 @@
// we can run into cases where type_info names aren't merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const
- { return __builtin_strcmp (__name, __arg.__name) < 0; }
+ { return (__name[0] == '*' && __arg.__name[0] == '*')
+ ? __name < __arg.__name
+ : __builtin_strcmp (__name, __arg.__name) < 0; }
bool operator==(const type_info& __arg) const
{
return ((__name == __arg.__name)
- || __builtin_strcmp (__name, __arg.__name) == 0);
+ || (__name[0] != '*' &&
+ __builtin_strcmp (__name, __arg.__name) == 0));
}
#else
// On some targets we can rely on type_info's NTBS being unique,
Index: libstdc++-v3/libsupc++/tinfo.cc
===================================================================
--- libstdc++-v3/libsupc++/tinfo.cc (revision 153489)
+++ libstdc++-v3/libsupc++/tinfo.cc (working copy)
@@ -41,7 +41,8 @@
#if __GXX_MERGED_TYPEINFO_NAMES
return name () == arg.name ();
#else
- return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) ==
0);
+ return (&arg == this)
+ || (name ()[0] != '*' && (__builtin_strcmp (name (), arg.name ())
== 0));
#endif
}
Index: libstdc++-v3/ChangeLog
===================================================================
--- libstdc++-v3/ChangeLog (revision 153489)
+++ libstdc++-v3/ChangeLog (working copy)
@@ -1,3 +1,10 @@
+2009-10-28 Jerry Quinn <jlquinn@optonline.net>
+
+ * libsupc++/tinfo.cc (operator=(const type_info&)): Compare by
+ pointer if name begins with '*'.
+ * libsupc++/typeinfo (type_info::name()): Likewise.
+ * libsupc++/tinfo2.cc (before): Likewise.
+
009-10-20 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/41773
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-29 5:35 ` Jerry Quinn
@ 2009-10-29 6:45 ` Jason Merrill
2009-11-01 5:02 ` Jason Merrill
0 siblings, 1 reply; 9+ messages in thread
From: Jason Merrill @ 2009-10-29 6:45 UTC (permalink / raw)
To: Jerry Quinn; +Cc: Jakub Jelinek, GCC, gcc-patches
On 10/29/2009 01:06 AM, Jerry Quinn wrote:
> And here is the latest patch.
This one is OK, thanks.
Jason
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: enable-build-with-cxx bootstrap compare broken by r149964
2009-10-29 6:45 ` Jason Merrill
@ 2009-11-01 5:02 ` Jason Merrill
0 siblings, 0 replies; 9+ messages in thread
From: Jason Merrill @ 2009-11-01 5:02 UTC (permalink / raw)
To: Jerry Quinn; +Cc: Jakub Jelinek, GCC, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 54 bytes --]
Here's the fix I'm checking in for the * path.
Jason
[-- Attachment #2: tinfo-null.patch --]
[-- Type: text/x-patch, Size: 1506 bytes --]
commit 16463ef55164d4668d6f1eeb150974452e1dbe58
Author: Jason Merrill <jason@redhat.com>
Date: Sat Oct 31 18:10:17 2009 -0400
* rtti.c (tinfo_name): Fix lengths for private case.
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 2926f97..c7af74a 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -364,10 +364,10 @@ tinfo_name (tree type, bool mark_private)
if (mark_private)
{
/* Inject '*' at beginning of name to force pointer comparison. */
- char* buf = (char*) XALLOCAVEC (char, length + 1);
+ char* buf = (char*) XALLOCAVEC (char, length + 2);
buf[0] = '*';
- memcpy (buf + 1, name, length);
- name_string = build_string (length + 1, buf);
+ memcpy (buf + 1, name, length + 1);
+ name_string = build_string (length + 2, buf);
}
else
name_string = build_string (length + 1, name);
diff --git a/gcc/testsuite/g++.dg/rtti/typeid9.C b/gcc/testsuite/g++.dg/rtti/typeid9.C
new file mode 100644
index 0000000..381252d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/rtti/typeid9.C
@@ -0,0 +1,21 @@
+// Test that the typeid name for a local class is properly null-terminated.
+// { dg-do run }
+
+#include <string.h>
+#include <typeinfo>
+#include <stdio.h>
+
+int f()
+{
+ struct A {}; struct B {};
+ const std::type_info &ti = typeid(A);
+ const std::type_info &ti2 = typeid(B);
+ puts (ti.name());
+ puts (ti2.name());
+ return strcmp (ti.name(), "Z1fvE1A") || strcmp (ti2.name(), "Z1fvE1B");
+}
+
+int main()
+{
+ return f();
+}
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-11-01 5:02 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <1250345548.19163.155.camel@cerberus.qb5.org>
[not found] ` <4A89BA99.1000900@redhat.com>
[not found] ` <1250563251.4312.6.camel@cerberus.qb5.org>
[not found] ` <4A8ACC37.8020200@redhat.com>
[not found] ` <1250743680.4312.38.camel@cerberus.qb5.org>
[not found] ` <4A8D218D.20209@gmail.com>
[not found] ` <1250771594.4312.40.camel@cerberus.qb5.org>
[not found] ` <4A8D4A1A.4080902@gmail.com>
[not found] ` <1250775261.4312.48.camel@cerberus.qb5.org>
[not found] ` <4A8D5C3B.7010604@gmail.com>
[not found] ` <1250890624.4312.54.camel@cerberus.qb5.org>
[not found] ` <4A8F1EE7.9030001@redhat.com>
2009-08-22 18:57 ` enable-build-with-cxx bootstrap compare broken by r149964 Jerry Quinn
[not found] ` <4A960A78.8040704@redhat.com>
[not found] ` <1251694626.7629.2.camel@cerberus.qb5.org>
[not found] ` <4AAE6745.3070706@redhat.com>
[not found] ` <4AB7B28E.7030501@redhat.com>
[not found] ` <1253617474.4274.2795.camel@cerberus.qb5.org>
[not found] ` <4AB8D3D1.8010704@redhat.com>
[not found] ` <1253712164.4274.2800.camel@cerberus.qb5.org>
[not found] ` <4ABA391C.2050903@redhat.com>
2009-10-24 5:28 ` Jerry Quinn
2009-10-26 11:15 ` Jakub Jelinek
2009-10-26 14:42 ` Jason Merrill
2009-10-28 12:49 ` Jerry Quinn
2009-10-28 15:52 ` Jason Merrill
2009-10-29 5:35 ` Jerry Quinn
2009-10-29 6:45 ` Jason Merrill
2009-11-01 5:02 ` Jason Merrill
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).