The first patch uses get_template_info instead of more verbose code.
The second patch avoids decls with DECL_COMDAT && !TREE_PUBLIC, which honza has complained about in the past.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 6447d3fc822afb4f8fe0d8488a0423cb0240e262 Author: Jason Merrill <ja...@redhat.com> Date: Wed Apr 15 12:25:48 2015 -0400 * decl2.c (determine_visibility): Use get_template_info. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 989a030..5a58d33 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2386,9 +2386,7 @@ determine_visibility (tree decl) { /* If the specialization doesn't specify visibility, use the visibility from the template. */ - tree tinfo = (TREE_CODE (decl) == TYPE_DECL - ? TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) - : DECL_TEMPLATE_INFO (decl)); + tree tinfo = get_template_info (decl); tree args = TI_ARGS (tinfo); tree attribs = (TREE_CODE (decl) == TYPE_DECL ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
commit 09c84c670045716d21f39287f29757e189221eaa Author: Jason Merrill <ja...@redhat.com> Date: Wed Apr 15 12:25:29 2015 -0400 * decl.c (grokmethod): Only set DECL_COMDAT if TREE_PUBLIC is set. * method.c (implicitly_declare_fn): Likewise. * decl2.c (vague_linkage_p): Check TREE_PUBLIC first. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c8323b0..0538570 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14422,7 +14422,8 @@ grokmethod (cp_decl_specifier_seq *declspecs, check_template_shadow (fndecl); - DECL_COMDAT (fndecl) = 1; + if (TREE_PUBLIC (fndecl)) + DECL_COMDAT (fndecl) = 1; DECL_DECLARED_INLINE_P (fndecl) = 1; DECL_NO_INLINE_WARNING_P (fndecl) = 1; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5a58d33..b2251d8 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1861,15 +1861,19 @@ maybe_make_one_only (tree decl) bool vague_linkage_p (tree decl) { + if (!TREE_PUBLIC (decl)) + { + gcc_checking_assert (!DECL_COMDAT (decl)); + return false; + } /* Unfortunately, import_export_decl has not always been called before the function is processed, so we cannot simply check DECL_COMDAT. */ if (DECL_COMDAT (decl) - || (((TREE_CODE (decl) == FUNCTION_DECL - && DECL_DECLARED_INLINE_P (decl)) - || (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_INSTANTIATION (decl))) - && TREE_PUBLIC (decl))) + || (TREE_CODE (decl) == FUNCTION_DECL + && DECL_DECLARED_INLINE_P (decl)) + || (DECL_LANG_SPECIFIC (decl) + && DECL_TEMPLATE_INSTANTIATION (decl))) return true; else if (DECL_FUNCTION_SCOPE_P (decl)) /* A local static in an inline effectively has vague linkage. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 33e2f3c..81f50e6 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -1925,8 +1925,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, DECL_EXTERNAL (fn) = true; DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; - DECL_COMDAT (fn) = 1; set_linkage_according_to_type (type, fn); + if (TREE_PUBLIC (fn)) + DECL_COMDAT (fn) = 1; rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof); gcc_assert (!TREE_USED (fn));