Hi, I noticed this while working on early-merging LTO. The DECL_VINDEX slot of FUNCTION_DECLs is supposed to hold the numeric index of the vtable slot if it's a virtual function. During parsing the C++ frontend uses it to hold a reference to itself, which then later is supposed to be transformed into the real index. Sometimes the C++ frontend copies function_decls, leaving the old one reachable via various means (but not as a reachable function, merely in scopes and the like), but fixes up only the copy.
Instead of diddling with the frontend we can just as well zero out meaningless DECL_VINDEX slots (i.e. when they're not an integer). It's used for debug info generation (when it's an integer) and as a flag ala "this function is a virtual method" by the middle-end. Regstrapped on x86_64-linux with the other three cleanups. Okay for trunk? Ciao, Michael. -- * tree.c (free_lang_data_in_decl): Zero DECL_VINDEX if it's not an integer. * tree.h (tree_decl_non_common.vindex): Adjust comment. Index: tree.c =================================================================== --- tree.c (revision 171537) +++ tree.c (working copy) @@ -4647,6 +4647,13 @@ free_lang_data_in_decl (tree decl) && RECORD_OR_UNION_TYPE_P (DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)))) DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE; + + /* Sometimes the C++ frontend doesn't manage to transform a temporary + DECL_VINDEX referring to itself into a vtable slot number as it + should. Happens with functions that are copied and then forgotten + about. Just clear it, it won't matter anymore. */ + if (DECL_VINDEX (decl) && !host_integerp (DECL_VINDEX (decl), 0)) + DECL_VINDEX (decl) = NULL_TREE; } else if (TREE_CODE (decl) == VAR_DECL) { Index: tree.h =================================================================== --- tree.h (revision 171537) +++ tree.h (working copy) @@ -3228,7 +3233,7 @@ struct GTY(()) tree arguments; /* Almost all FE's use this. */ tree result; - /* C++ uses this in namespaces. */ + /* C++ uses this in namespaces and function_decls. */ tree vindex; };