mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 21:41:14 +08:00
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.
This commit is contained in:
parent
56e2cc43de
commit
8158a46408
@ -1,3 +1,11 @@
|
||||
2020-01-21 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/91476 - anon-namespace reference temp clash between TUs.
|
||||
* 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.
|
||||
|
||||
2020-01-21 Bin Cheng <bin.cheng@linux.alibaba.com>
|
||||
|
||||
* coroutines.cc (finish_co_await_expr): Set return value flag.
|
||||
|
@ -11973,14 +11973,7 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
|
||||
GR and suffixed with a sequence number mangled using the usual rules
|
||||
for a seq-id. Temporaries are numbered with a pre-order, depth-first,
|
||||
left-to-right walk of the complete initializer. */
|
||||
|
||||
TREE_STATIC (var) = TREE_STATIC (decl);
|
||||
TREE_PUBLIC (var) = TREE_PUBLIC (decl);
|
||||
if (vague_linkage_p (decl))
|
||||
comdat_linkage (var);
|
||||
|
||||
CP_DECL_THREAD_LOCAL_P (var) = CP_DECL_THREAD_LOCAL_P (decl);
|
||||
set_decl_tls_model (var, DECL_TLS_MODEL (decl));
|
||||
copy_linkage (var, decl);
|
||||
|
||||
tree name = mangle_ref_init_variable (decl);
|
||||
DECL_NAME (var) = name;
|
||||
|
@ -6636,6 +6636,7 @@ extern bool mark_used (tree);
|
||||
extern bool mark_used (tree, tsubst_flags_t);
|
||||
extern void finish_static_data_member_decl (tree, tree, bool, tree, int);
|
||||
extern tree cp_build_parm_decl (tree, tree, tree);
|
||||
extern void copy_linkage (tree, tree);
|
||||
extern tree get_guard (tree);
|
||||
extern tree get_guard_cond (tree, bool);
|
||||
extern tree set_guard (tree);
|
||||
|
@ -7657,6 +7657,14 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
||||
TREE_READONLY (decl) = 0;
|
||||
}
|
||||
|
||||
/* This needs to happen before extend_ref_init_temps. */
|
||||
if (VAR_OR_FUNCTION_DECL_P (decl))
|
||||
{
|
||||
if (VAR_P (decl))
|
||||
maybe_commonize_var (decl);
|
||||
determine_visibility (decl);
|
||||
}
|
||||
|
||||
if (VAR_P (decl))
|
||||
{
|
||||
duration_kind dk = decl_storage_duration (decl);
|
||||
@ -7786,12 +7794,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
|
||||
if (VAR_P (decl))
|
||||
{
|
||||
layout_var_decl (decl);
|
||||
maybe_commonize_var (decl);
|
||||
if (!flag_weak)
|
||||
/* Check again now that we have an initializer. */
|
||||
maybe_commonize_var (decl);
|
||||
}
|
||||
|
||||
/* This needs to happen after the linkage is set. */
|
||||
determine_visibility (decl);
|
||||
|
||||
if (var_definition_p && TREE_STATIC (decl))
|
||||
{
|
||||
/* If a TREE_READONLY variable needs initialization
|
||||
@ -8328,23 +8335,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count)
|
||||
}
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
TREE_PUBLIC (v[i]) = TREE_PUBLIC (decl);
|
||||
TREE_STATIC (v[i]) = TREE_STATIC (decl);
|
||||
DECL_COMMON (v[i]) = DECL_COMMON (decl);
|
||||
DECL_COMDAT (v[i]) = DECL_COMDAT (decl);
|
||||
if (TREE_STATIC (v[i]))
|
||||
{
|
||||
CP_DECL_THREAD_LOCAL_P (v[i])
|
||||
= CP_DECL_THREAD_LOCAL_P (decl);
|
||||
set_decl_tls_model (v[i], DECL_TLS_MODEL (decl));
|
||||
if (DECL_ONE_ONLY (decl))
|
||||
make_decl_one_only (v[i], cxx_comdat_group (v[i]));
|
||||
if (TREE_PUBLIC (decl))
|
||||
DECL_WEAK (v[i]) = DECL_WEAK (decl);
|
||||
DECL_VISIBILITY (v[i]) = DECL_VISIBILITY (decl);
|
||||
DECL_VISIBILITY_SPECIFIED (v[i])
|
||||
= DECL_VISIBILITY_SPECIFIED (decl);
|
||||
}
|
||||
copy_linkage (v[i], decl);
|
||||
cp_finish_decl (v[i], init, /*constexpr*/false,
|
||||
/*asm*/NULL_TREE, LOOKUP_NORMAL);
|
||||
}
|
||||
|
@ -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;
|
||||
|
17
gcc/testsuite/g++.dg/ext/visibility/ref-temp1.C
Normal file
17
gcc/testsuite/g++.dg/ext/visibility/ref-temp1.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/91476
|
||||
// Test that hidden and internal visibility propagates to reference temps.
|
||||
|
||||
#define HIDDEN __attribute((visibility("hidden")))
|
||||
|
||||
// { dg-final { scan-hidden "_ZGRZ1fvE3foo_" } }
|
||||
HIDDEN inline const int* f() { static const int &foo = 1; return &foo; }
|
||||
|
||||
// { dg-final { scan-assembler-not "(weak|globl)\[^\n\]*_ZGRN12_GLOBAL__N_13fooE_" } }
|
||||
namespace { const int &foo = 1; }
|
||||
|
||||
const void *volatile p;
|
||||
int main()
|
||||
{
|
||||
p = f();
|
||||
p = &foo;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user