diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2019-07-17 19:19:21 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2019-07-17 17:19:21 +0000 |
commit | 17b99c984b69b0b4927af6f81380c855c60475b7 (patch) | |
tree | b140eaf828f28635be4c93f04ac03ebcfd6395e4 /gcc/alias.c | |
parent | a7dbb77712c20e1e04186d68377875a428b635f5 (diff) | |
download | gcc-17b99c984b69b0b4927af6f81380c855c60475b7.zip gcc-17b99c984b69b0b4927af6f81380c855c60475b7.tar.gz gcc-17b99c984b69b0b4927af6f81380c855c60475b7.tar.bz2 |
alias.c (record_component_aliases): Do not simplify pointed-to types of ODR types
* alias.c (record_component_aliases): Do not simplify pointed-to
types of ODR types
* testsuite/g++.dg/lto/alias-4_0.C
From-SVN: r273552
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 87 |
1 files changed, 46 insertions, 41 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index eece84a..2755df7 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1202,47 +1202,52 @@ record_component_aliases (tree type) case RECORD_TYPE: case UNION_TYPE: case QUAL_UNION_TYPE: - for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field)) - { - /* LTO type merging does not make any difference between - component pointer types. We may have - - struct foo {int *a;}; - - as TYPE_CANONICAL of - - struct bar {float *a;}; - - Because accesses to int * and float * do not alias, we would get - false negative when accessing the same memory location by - float ** and bar *. We thus record the canonical type as: - - struct {void *a;}; - - void * is special cased and works as a universal pointer type. - Accesses to it conflicts with accesses to any other pointer - type. */ - tree t = TREE_TYPE (field); - if (in_lto_p) - { - /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their - element type and that type has to be normalized to void *, - too, in the case it is a pointer. */ - while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t)) - { - gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t)); - t = TREE_TYPE (t); - } - if (POINTER_TYPE_P (t)) - t = ptr_type_node; - else if (flag_checking) - gcc_checking_assert (get_alias_set (t) - == get_alias_set (TREE_TYPE (field))); - } - - record_alias_subset (superset, get_alias_set (t)); - } + { + /* LTO non-ODR type merging does not make any difference between + component pointer types. We may have + + struct foo {int *a;}; + + as TYPE_CANONICAL of + + struct bar {float *a;}; + + Because accesses to int * and float * do not alias, we would get + false negative when accessing the same memory location by + float ** and bar *. We thus record the canonical type as: + + struct {void *a;}; + + void * is special cased and works as a universal pointer type. + Accesses to it conflicts with accesses to any other pointer + type. */ + bool void_pointers = in_lto_p + && (!odr_type_p (type) + || !odr_based_tbaa_p (type)); + for (field = TYPE_FIELDS (type); field != 0; field = DECL_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL && !DECL_NONADDRESSABLE_P (field)) + { + tree t = TREE_TYPE (field); + if (void_pointers) + { + /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their + element type and that type has to be normalized to void *, + too, in the case it is a pointer. */ + while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t)) + { + gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t)); + t = TREE_TYPE (t); + } + if (POINTER_TYPE_P (t)) + t = ptr_type_node; + else if (flag_checking) + gcc_checking_assert (get_alias_set (t) + == get_alias_set (TREE_TYPE (field))); + } + + record_alias_subset (superset, get_alias_set (t)); + } + } break; case COMPLEX_TYPE: |