Commit b01659aa by Jan Hubicka Committed by Jan Hubicka

lto-common.c (gimple_register_canonical_type_1): Do not look for non-ODR…

lto-common.c (gimple_register_canonical_type_1): Do not look for non-ODR conflicts of types in anonymous namespaces.

	* lto-common.c (gimple_register_canonical_type_1): Do not look for
	non-ODR conflicts of types in anonymous namespaces.
	(unify_scc): Do not merge anonymous namespace types.
	* g++.dg/lto/alias-5_0.C: New testcase.
	* g++.dg/lto/alias-5_1.C: New.
	* g++.dg/lto/alias-5_2.c: New.

From-SVN: r273571
parent 3796e3b3
2019-07-18 Jan Hubicka <hubicka@ucw.cz>
* lto-common.c (gimple_register_canonical_type_1): Do not look for
non-ODR conflicts of types in anonymous namespaces.
(unify_scc): Do not merge anonymous namespace types.
2019-07-09 Martin Sebor <msebor@redhat.com> 2019-07-09 Martin Sebor <msebor@redhat.com>
PR c++/61339 PR c++/61339
......
...@@ -418,6 +418,11 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash) ...@@ -418,6 +418,11 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
if (RECORD_OR_UNION_TYPE_P (t) if (RECORD_OR_UNION_TYPE_P (t)
&& odr_type_p (t) && !odr_type_violation_reported_p (t)) && odr_type_p (t) && !odr_type_violation_reported_p (t))
{ {
/* Anonymous namespace types never conflict with non-C++ types. */
if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
slot = NULL;
else
{
/* Here we rely on fact that all non-ODR types was inserted into /* Here we rely on fact that all non-ODR types was inserted into
canonical type hash and thus we can safely detect conflicts between canonical type hash and thus we can safely detect conflicts between
ODR types and interoperable non-ODR types. */ ODR types and interoperable non-ODR types. */
...@@ -425,6 +430,7 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash) ...@@ -425,6 +430,7 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
&& TYPE_MAIN_VARIANT (t) == t); && TYPE_MAIN_VARIANT (t) == t);
slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
NO_INSERT); NO_INSERT);
}
if (slot && !TYPE_CXX_ODR_P (*(tree *)slot)) if (slot && !TYPE_CXX_ODR_P (*(tree *)slot))
{ {
tree nonodr = *(tree *)slot; tree nonodr = *(tree *)slot;
...@@ -1640,11 +1646,14 @@ unify_scc (class data_in *data_in, unsigned from, ...@@ -1640,11 +1646,14 @@ unify_scc (class data_in *data_in, unsigned from,
tree t = streamer_tree_cache_get_tree (cache, from + i); tree t = streamer_tree_cache_get_tree (cache, from + i);
scc->entries[i] = t; scc->entries[i] = t;
/* Do not merge SCCs with local entities inside them. Also do /* Do not merge SCCs with local entities inside them. Also do
not merge TRANSLATION_UNIT_DECLs. */ not merge TRANSLATION_UNIT_DECLs and anonymous namespace types. */
if (TREE_CODE (t) == TRANSLATION_UNIT_DECL if (TREE_CODE (t) == TRANSLATION_UNIT_DECL
|| (VAR_OR_FUNCTION_DECL_P (t) || (VAR_OR_FUNCTION_DECL_P (t)
&& !(TREE_PUBLIC (t) || DECL_EXTERNAL (t))) && !(TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
|| TREE_CODE (t) == LABEL_DECL) || TREE_CODE (t) == LABEL_DECL
|| (TYPE_P (t)
&& type_with_linkage_p (TYPE_MAIN_VARIANT (t))
&& type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t))))
{ {
/* Avoid doing any work for these cases and do not worry to /* Avoid doing any work for these cases and do not worry to
record the SCCs for further merging. */ record the SCCs for further merging. */
......
2019-07-18 Jan Hubicka <hubicka@ucw.cz>
* g++.dg/lto/alias-5_0.C: New testcase.
* g++.dg/lto/alias-5_1.C: New.
* g++.dg/lto/alias-5_2.c: New.
2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com> 2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
PR tree-optimization/91137 PR tree-optimization/91137
......
/* { dg-lto-do run } */
/* { dg-lto-options { { -O3 -flto } } } */
/* This testcase tests that anonymous namespaces in different TUs are treated
as different types by LTO TBAA and that they never alias with structurally
same C types. */
namespace {
__attribute__((used))
struct a {int a;} *p,**ptr=&p;
};
void
set1()
{
*ptr=0;
}
void
get1()
{
if (!__builtin_constant_p (*ptr==0))
__builtin_abort ();
}
extern void set2();
extern "C" void set3();
int n = 1;
int
main()
{
for (int i = 0; i < n; i++)
{
set1();
set2();
set3();
get1();
}
return 0;
}
namespace {
__attribute__((used))
struct a {int a;} *p,**ptr=&p,q;
};
void
set2()
{
*ptr=&q;
}
__attribute__((used))
struct a {int a;} *p,**ptr=&p,q;
void
set3()
{
*ptr=&q;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment