aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-20 13:27:10 -0500
committerJason Merrill <jason@redhat.com>2020-01-21 10:17:50 -0500
commit8158a4640819dbb3210326e37786fb874f450272 (patch)
treec7724af94aa2132a7bfdeb8f6fb8abbfc04058e3 /gcc/cp/decl2.c
parent56e2cc43de6e47312c186398c35732b890de0049 (diff)
downloadgcc-8158a4640819dbb3210326e37786fb874f450272.zip
gcc-8158a4640819dbb3210326e37786fb874f450272.tar.gz
gcc-8158a4640819dbb3210326e37786fb874f450272.tar.bz2
PR c++/91476 - anon-namespace reference temp clash between TUs.
The problem in the PR was that make_temporary_var_for_ref_to_temp ran before determine_visibility, so when we copied the linkage of the reference variable it had not yet been restricted by its anonymous namespace context, so the temporary wrongly ended up with TREE_PUBLIC set. The natural solution is to run determine_visibility earlier. But that needs to happen after maybe_commonize_var increases the linkage of some local variables, and on targets without weak symbol support, that function does different things based on the results of check_initializer, which is what calls make_temporary_var_for_ref_to_temp. To break this circular dependency I'm calling maybe_commonize_var early, and then again later if the target doesn't support weak symbols. It also occurred to me that make_temporary_var_for_ref_to_temp wasn't handling DECL_VISIBILITY at all, and verified that we were doing the wrong thing. So I've combined the linkage-copying code from there and two other places. * decl2.c (copy_linkage): Factor out of get_guard. * call.c (make_temporary_var_for_ref_to_temp): Use it. * decl.c (cp_finish_decomp): Use it. (cp_finish_decl): determine_visibility sooner.
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 042d6fa..1ecf0b9 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3214,6 +3214,29 @@ build_cleanup (tree decl)
return clean;
}
+/* GUARD is a helper variable for DECL; make them have the same linkage and
+ visibility. */
+
+void
+copy_linkage (tree guard, tree decl)
+{
+ TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
+ TREE_STATIC (guard) = TREE_STATIC (decl);
+ DECL_COMMON (guard) = DECL_COMMON (decl);
+ DECL_COMDAT (guard) = DECL_COMDAT (decl);
+ if (TREE_STATIC (guard))
+ {
+ CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl);
+ set_decl_tls_model (guard, DECL_TLS_MODEL (decl));
+ /* We can't rely on DECL_WEAK (decl) or DECL_ONE_ONLY (decl) here, as
+ they may not be set until import_export_decl at EOF. */
+ if (vague_linkage_p (decl))
+ comdat_linkage (guard);
+ DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
+ DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl);
+ }
+}
+
/* Returns the initialization guard variable for the variable DECL,
which has static storage duration. */
@@ -3236,18 +3259,7 @@ get_guard (tree decl)
VAR_DECL, sname, guard_type);
/* The guard should have the same linkage as what it guards. */
- TREE_PUBLIC (guard) = TREE_PUBLIC (decl);
- TREE_STATIC (guard) = TREE_STATIC (decl);
- DECL_COMMON (guard) = DECL_COMMON (decl);
- DECL_COMDAT (guard) = DECL_COMDAT (decl);
- CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl);
- set_decl_tls_model (guard, DECL_TLS_MODEL (decl));
- if (DECL_ONE_ONLY (decl))
- make_decl_one_only (guard, cxx_comdat_group (guard));
- if (TREE_PUBLIC (decl))
- DECL_WEAK (guard) = DECL_WEAK (decl);
- DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl);
- DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl);
+ copy_linkage (guard, decl);
DECL_ARTIFICIAL (guard) = 1;
DECL_IGNORED_P (guard) = 1;