+2014-09-09 Jason Merrill <jason@redhat.com>
+
+ PR lto/53808
+ PR c++/61659
+ * decl2.c (note_comdat_fn): New.
+ (set_comdat): New.
+ (cp_write_global_declarations): Call set_comdat.
+ * method.c (implicitly_declare_fn): Call note_comdat_fn.
+ * pt.c (tsubst_decl) [FUNCTION_DECL]: Likewise.
+ * decl2.c (mark_needed): Mark clones.
+ (import_export_decl): Not here.
+
+ PR c++/61214
+ PR c++/62224
+ * decl2.c (decl_needed_p): Revert virtual functions change.
+
2014-07-16 Release Manager
* GCC 4.9.1 released.
may need to emit outline anyway. */
static GTY(()) vec<tree, va_gc> *deferred_fns;
+/* A list of functions which we might want to set DECL_COMDAT on at EOF. */
+
+static GTY(()) vec<tree, va_gc> *maybe_comdat_fns;
+
/* A list of decls that use types with no linkage, which we need to make
sure are defined. */
static GTY(()) vec<tree, va_gc> *no_linkage_decls;
definition. */
struct cgraph_node *node = cgraph_get_create_node (decl);
node->forced_by_abi = true;
+
+ /* #pragma interface and -frepo code can call mark_needed for
+ maybe-in-charge 'tors; mark the clones as well. */
+ tree clone;
+ FOR_EACH_CLONE (clone, decl)
+ mark_needed (clone);
}
else if (TREE_CODE (decl) == VAR_DECL)
{
{
/* The repository indicates that this entity should be defined
here. Make sure the back end honors that request. */
- if (VAR_P (decl))
- mark_needed (decl);
- else if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
- || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
- {
- tree clone;
- FOR_EACH_CLONE (clone, decl)
- mark_needed (clone);
- }
- else
- mark_needed (decl);
+ mark_needed (decl);
/* Output the definition as an ordinary strong definition. */
DECL_EXTERNAL (decl) = 0;
DECL_INTERFACE_KNOWN (decl) = 1;
}
}
+/* Much like the above, but not necessarily defined. 4.9 hack for setting
+ DECL_COMDAT on DECL_EXTERNAL functions, along with set_comdat. */
+
+void
+note_comdat_fn (tree decl)
+{
+ vec_safe_push (maybe_comdat_fns, decl);
+}
+
+/* DECL is a function with vague linkage that was not
+ instantiated/synthesized in this translation unit. Set DECL_COMDAT for
+ the benefit of can_refer_decl_in_current_unit_p. */
+
+static void
+set_comdat (tree decl)
+{
+ DECL_COMDAT (decl) = true;
+
+ tree clone;
+ FOR_EACH_CLONE (clone, decl)
+ set_comdat (clone);
+
+ if (DECL_VIRTUAL_P (decl))
+ for (tree thunk = DECL_THUNKS (decl); thunk;
+ thunk = DECL_CHAIN (thunk))
+ DECL_COMDAT (thunk) = true;
+}
+
/* This routine is called at the end of compilation.
Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction
vtv_build_vtable_verify_fndecl ();
}
+ FOR_EACH_VEC_SAFE_ELT (maybe_comdat_fns, i, decl)
+ if (!DECL_COMDAT (decl) && vague_linkage_p (decl))
+ set_comdat (decl);
+
finalize_compilation_unit ();
if (flag_vtable_verify)
--- /dev/null
+// PR c++/61659
+// { dg-options "-O3" }
+// { dg-final { scan-assembler-not "_ZN6parserIiE9getOptionEv" } }
+
+struct generic_parser_base {
+ virtual void getOption();
+ void getExtraOptionNames() { getOption(); }
+};
+template <class DataType> struct parser : public generic_parser_base {
+ virtual void getOption() {}
+};
+struct PassNameParser : public parser<int> {
+ PassNameParser();
+};
+struct list {
+ PassNameParser Parser;
+ virtual void getExtraOptionNames() { return Parser.getExtraOptionNames(); }
+};
+list PassList;