aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2022-06-07 15:52:30 -0400
committerJason Merrill <jason@redhat.com>2022-06-08 16:38:25 -0400
commite8ed26c2ac38ab1f6ed5a627d9089a9243e06a0c (patch)
tree9dca7d858cc4aac7528d18a71525faf40a9b53b7
parent7d87790a871482e9c5142a8e885b4a5f76d197c8 (diff)
downloadgcc-e8ed26c2ac38ab1f6ed5a627d9089a9243e06a0c.zip
gcc-e8ed26c2ac38ab1f6ed5a627d9089a9243e06a0c.tar.gz
gcc-e8ed26c2ac38ab1f6ed5a627d9089a9243e06a0c.tar.bz2
c++: non-templated friends [PR105852]
The previous patch for 105852 avoids copying DECL_TEMPLATE_INFO from a non-templated friend, but it really shouldn't have it in the first place. PR c++/105852 gcc/cp/ChangeLog: * decl.cc (duplicate_decls): Change non-templated friend check to an assert. * pt.cc (tsubst_function_decl): Don't set DECL_TEMPLATE_INFO on non-templated friends. (tsubst_friend_function): Adjust.
-rw-r--r--gcc/cp/decl.cc9
-rw-r--r--gcc/cp/pt.cc14
2 files changed, 15 insertions, 8 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 3e86995..7f3b3c3 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -2664,10 +2664,11 @@ duplicate_decls (tree newdecl, tree olddecl, bool hiding, bool was_hidden)
= TINFO_USED_TEMPLATE_ID (new_template_info);
}
- if (non_templated_friend_p (olddecl))
- /* Don't copy tinfo from a non-templated friend (PR105761). */;
- else
- DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
+ /* We don't want to copy template info from a non-templated friend
+ (PR105761), but these shouldn't have DECL_TEMPLATE_INFO now. */
+ gcc_checking_assert (!DECL_TEMPLATE_INFO (olddecl)
+ || !non_templated_friend_p (olddecl));
+ DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
}
if (DECL_DECLARES_FUNCTION_P (newdecl))
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 9c1b026..3154186 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -11298,9 +11298,10 @@ tsubst_friend_function (tree decl, tree args)
tree new_friend_template_info = DECL_TEMPLATE_INFO (new_friend);
tree new_friend_result_template_info = NULL_TREE;
bool new_friend_is_defn =
- (DECL_INITIAL (DECL_TEMPLATE_RESULT
- (template_for_substitution (new_friend)))
- != NULL_TREE);
+ (new_friend_template_info
+ && (DECL_INITIAL (DECL_TEMPLATE_RESULT
+ (template_for_substitution (new_friend)))
+ != NULL_TREE));
tree not_tmpl = new_friend;
if (TREE_CODE (new_friend) == TEMPLATE_DECL)
@@ -14084,6 +14085,10 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
&& !LAMBDA_FUNCTION_P (t))
return t;
+ /* A non-templated friend doesn't get DECL_TEMPLATE_INFO. */
+ if (non_templated_friend_p (t))
+ goto friend_case;
+
/* Calculate the most general template of which R is a
specialization. */
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
@@ -14129,6 +14134,7 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
tsubst_friend_function, and we want only to create a
new decl (R) with appropriate types so that we can call
determine_specialization. */
+ friend_case:
gen_tmpl = NULL_TREE;
argvec = NULL_TREE;
}
@@ -14324,7 +14330,7 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
/* If this is an instantiation of a member template, clone it.
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
- if (PRIMARY_TEMPLATE_P (gen_tmpl))
+ if (gen_tmpl && PRIMARY_TEMPLATE_P (gen_tmpl))
clone_cdtor (r, /*update_methods=*/false);
}
else if ((complain & tf_error) != 0