aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-05-14 07:13:54 -0700
committerNathan Sidwell <nathan@acm.org>2020-05-14 07:18:04 -0700
commit5adbd0907563f494b602b9f38283d29c7b029bdf (patch)
tree305e967d0389fde7039edf620d1f55d346483e7b
parentc4bff4c230c8d3414bc77f7a58ffc5f61b6bd08c (diff)
downloadgcc-5adbd0907563f494b602b9f38283d29c7b029bdf.zip
gcc-5adbd0907563f494b602b9f38283d29c7b029bdf.tar.gz
gcc-5adbd0907563f494b602b9f38283d29c7b029bdf.tar.bz2
c++: Adjust push_template_decl_real
Push_template_decl_real's friend-pushing logic was confusing me. This is more understandable. Fix a latent type bug I disovered. * pt.c (push_template_decl_real): Adjust friend pushing logic. Reinit template type.
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/pt.c36
2 files changed, 25 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 45b60de..9bc3e8d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
2020-05-14 Nathan Sidwell <nathan@acm.org>
+ * pt.c (push_template_decl_real): Adjust friend pushing logic.
+ Reinit template type.
+
* pt.c (build_template_decl): Init DECL_TEMPLATE_RESULT &
TREE_TYPE here ...
(process_partial_specialization): ... not here ...
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 837644f..68d113b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5979,24 +5979,32 @@ push_template_decl_real (tree decl, bool is_friend)
gcc_checking_assert (DECL_TEMPLATE_RESULT (tmpl) == decl);
- /* Push template declarations for global functions and types. Note
- that we do not try to push a global template friend declared in a
- template class; such a thing may well depend on the template
- parameters of the class. */
- if (new_template_p && !ctx
- && !(is_friend && template_class_depth (current_class_type) > 0))
- {
- tmpl = pushdecl_namespace_level (tmpl, is_friend);
- if (tmpl == error_mark_node)
- return error_mark_node;
- /* Hide template friend classes that haven't been declared yet. */
- if (is_friend && TREE_CODE (decl) == TYPE_DECL)
+ if (new_template_p)
+ {
+ /* Push template declarations for global functions and types.
+ Note that we do not try to push a global template friend
+ declared in a template class; such a thing may well depend on
+ the template parameters of the class and we'll push it when
+ instantiating the befriending class. */
+ if (!ctx
+ && !(is_friend && template_class_depth (current_class_type) > 0))
{
- DECL_ANTICIPATED (tmpl) = 1;
- DECL_FRIEND_P (tmpl) = 1;
+ tmpl = pushdecl_namespace_level (tmpl, is_friend);
+ if (tmpl == error_mark_node)
+ return error_mark_node;
+
+ /* Hide template friend classes that haven't been declared yet. */
+ if (is_friend && TREE_CODE (decl) == TYPE_DECL)
+ {
+ DECL_ANTICIPATED (tmpl) = 1;
+ DECL_FRIEND_P (tmpl) = 1;
+ }
}
}
+ else
+ /* The type may have been completed, or (erroneously) changed. */
+ TREE_TYPE (tmpl) = TREE_TYPE (decl);
if (is_primary)
{