Hi. This removes false positive warning when having trailing array at the end of a struct.
Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. Ready to be installed? Martin gcc/lto/ChangeLog: 2018-01-23 Martin Liska <mli...@suse.cz> PR lto/81440 * lto-symtab.c (lto_symtab_merge): Handle and do not warn about trailing arrays at the end of a struct. gcc/testsuite/ChangeLog: 2018-01-23 Martin Liska <mli...@suse.cz> PR lto/81440 * gcc.dg/lto/pr81440.h: New test. * gcc.dg/lto/pr81440_0.c: New test. * gcc.dg/lto/pr81440_1.c: New test. --- gcc/lto/lto-symtab.c | 25 +++++++++++++++++++------ gcc/testsuite/gcc.dg/lto/pr81440.h | 4 ++++ gcc/testsuite/gcc.dg/lto/pr81440_0.c | 9 +++++++++ gcc/testsuite/gcc.dg/lto/pr81440_1.c | 6 ++++++ 4 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lto/pr81440.h create mode 100644 gcc/testsuite/gcc.dg/lto/pr81440_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr81440_1.c
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index ee02a534714..0f0b958e98d 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -352,18 +352,31 @@ lto_symtab_merge (symtab_node *prevailing, symtab_node *entry) return false; if (DECL_SIZE (decl) && DECL_SIZE (prevailing_decl) - && !tree_int_cst_equal (DECL_SIZE (decl), DECL_SIZE (prevailing_decl)) + && !tree_int_cst_equal (DECL_SIZE (decl), DECL_SIZE (prevailing_decl))) + { + if (!DECL_COMMON (decl) && !DECL_EXTERNAL (decl)) + return false; + + tree type = TREE_TYPE (decl); + + /* For record type, check for array at the end of the structure. */ + if (TREE_CODE (type) == RECORD_TYPE) + { + tree field = TYPE_FIELDS (type); + while (DECL_CHAIN (field) != NULL_TREE) + field = DECL_CHAIN (field); + + return TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE; + } /* As a special case do not warn about merging int a[]; and int a[]={1,2,3}; here the first declaration is COMMON and sizeof(a) == sizeof (int). */ - && ((!DECL_COMMON (decl) && !DECL_EXTERNAL (decl)) - || TREE_CODE (TREE_TYPE (decl)) != ARRAY_TYPE - || TYPE_SIZE (TREE_TYPE (decl)) - != TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl))))) - return false; + else if (TREE_CODE (type) == ARRAY_TYPE) + return (TYPE_SIZE (decl) == TYPE_SIZE (TREE_TYPE (type))); + } return true; } diff --git a/gcc/testsuite/gcc.dg/lto/pr81440.h b/gcc/testsuite/gcc.dg/lto/pr81440.h new file mode 100644 index 00000000000..d9e6c3da645 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr81440.h @@ -0,0 +1,4 @@ +typedef struct { + int i; + int ints[]; +} struct_t; diff --git a/gcc/testsuite/gcc.dg/lto/pr81440_0.c b/gcc/testsuite/gcc.dg/lto/pr81440_0.c new file mode 100644 index 00000000000..07f2a87da21 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr81440_0.c @@ -0,0 +1,9 @@ +/* { dg-lto-do link } */ + +#include "pr81440.h" + +extern struct_t my_struct; + +int main() { + return my_struct.ints[0]; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr81440_1.c b/gcc/testsuite/gcc.dg/lto/pr81440_1.c new file mode 100644 index 00000000000..d03533029c1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr81440_1.c @@ -0,0 +1,6 @@ +#include "pr81440.h" + +struct_t my_struct = { + 20, + { 1, 2 } +};