aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/method.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2003-10-24 07:59:41 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2003-10-24 07:59:41 +0000
commitbb88593883c783c600c89b8d1e5d7973c90d3f5a (patch)
tree30f00d7a2377783a5112afcd6c22c5508f1c6309 /gcc/cp/method.c
parent0f3340356d5a1b7847301b0d20161b242cfc5dbd (diff)
downloadgcc-bb88593883c783c600c89b8d1e5d7973c90d3f5a.zip
gcc-bb88593883c783c600c89b8d1e5d7973c90d3f5a.tar.gz
gcc-bb88593883c783c600c89b8d1e5d7973c90d3f5a.tar.bz2
PR c++/12698, c++/12699, c++/12700, c++/12566
cp: PR c++/12698, c++/12699, c++/12700, c++/12566 * cp-tree.h (THUNK_ALIAS_P, THUNK_ALIAS): New. (debug_class, debug_thunks): New. * class.c (dump_class_hierarchy_1): New break out from ... (dump_class_hierarchy): ... here. (dump_thunk, debug_thunks, debug_class): New. (update_vtable_entry_for_fn): Add ssizetype casts. Correct continued search for primary binfo via virtual. (build_vtbl_initializer): Follow covariant thunk alias. * method.c (make_thunk): Clear DECL_THUNKS of the thunk. (finish_thunk): Look for an alias of the covariant thunk and point to it. (use_thunk): We should never use an alias. * semantics.c (emit_associated_thunks): Do not emit aliases. PR c++/12566 * cp-tree.h (cp_fname_init): Add TYPE pointer param. * decl.c (cp_fname_init): Add TYPE pointer param. Set it. Don't create an ad-hoc ERROR_MARK. (cp_make_fname_decl): Adjust. * pt.c (tsubst_expr): Adjust. testsuite: PR c++/12698, c++/12699, c++/12700, c++/12566 * g++.dg/inherit/covariant9.C: New test. * g++.dg/inherit/covariant10.C: New test. * g++.dg/inherit/covariant11.C: New test. From-SVN: r72882
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r--gcc/cp/method.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 5277004..c6651e8 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -107,6 +107,8 @@ make_thunk (tree function, bool this_adjusting,
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 20021025);
/* We can have this thunks to covariant thunks, but not vice versa. */
my_friendly_assert (!DECL_THIS_THUNK_P (function), 20021127);
+ my_friendly_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting,
+ 20031123);
/* Scale the VIRTUAL_OFFSET to be in terms of bytes. */
if (this_adjusting && virtual_offset)
@@ -140,6 +142,8 @@ make_thunk (tree function, bool this_adjusting,
thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (thunk);
+ DECL_THUNKS (thunk) = NULL_TREE;
+
DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
TREE_READONLY (thunk) = TREE_READONLY (function);
TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
@@ -171,6 +175,7 @@ make_thunk (tree function, bool this_adjusting,
DECL_DECLARED_INLINE_P (thunk) = 0;
/* Nor has it been deferred. */
DECL_DEFERRED_FN (thunk) = 0;
+
/* Add it to the list of thunks associated with FUNCTION. */
TREE_CHAIN (thunk) = DECL_THUNKS (function);
DECL_THUNKS (function) = thunk;
@@ -193,6 +198,27 @@ finish_thunk (tree thunk)
function = THUNK_TARGET (thunk);
name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
fixed_offset, virtual_offset);
+
+ /* We can end up with declarations of (logically) different
+ covariant thunks, that do identical adjustments. The two thunks
+ will be adjusting between within different hierarchies, which
+ happen to have the same layout. We must nullify one of them to
+ refer to the other. */
+ if (DECL_RESULT_THUNK_P (thunk))
+ {
+ tree cov_probe;
+
+ for (cov_probe = DECL_THUNKS (function);
+ cov_probe; cov_probe = TREE_CHAIN (cov_probe))
+ if (DECL_NAME (cov_probe) == name)
+ {
+ my_friendly_assert (!DECL_THUNKS (thunk), 20031023);
+ THUNK_ALIAS (thunk) = (THUNK_ALIAS_P (cov_probe)
+ ? THUNK_ALIAS (cov_probe) : cov_probe);
+ break;
+ }
+ }
+
DECL_NAME (thunk) = name;
SET_DECL_ASSEMBLER_NAME (thunk, name);
}
@@ -307,6 +333,10 @@ use_thunk (tree thunk_fndecl, bool emit_p)
/* We should have called finish_thunk to give it a name. */
my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
+ /* We should never be using an alias, always refer to the
+ aliased thunk. */
+ my_friendly_assert (!THUNK_ALIAS_P (thunk_fndecl), 20031023);
+
if (TREE_ASM_WRITTEN (thunk_fndecl))
return;