diff options
Diffstat (limited to 'gcc/cp/method.c')
-rw-r--r-- | gcc/cp/method.c | 30 |
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; |