From 958a627f8831aad2d1d87c1a95b622722f375e73 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 11 Dec 2015 00:57:15 +0100 Subject: [PATCH] re PR lto/61886 (LTO breaks fread with _FORTIFY_SOURCE=2) PR ipa/61886 * lto-symtab.c (lto_symtab_merge_p): Avoid merging across different values of error and warning attributes. * gcc.dg/lto/pr61886_0.c: New testcase From-SVN: r231548 --- gcc/lto/ChangeLog | 6 ++++ gcc/lto/lto-symtab.c | 52 ++++++++++++++++++++++++---- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/lto/pr61886_0.c | 33 ++++++++++++++++++ 4 files changed, 90 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lto/pr61886_0.c diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 4fe2ebe1888..f0d90fc328b 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2015-12-11 Jan Hubicka + + PR ipa/61886 + * lto-symtab.c (lto_symtab_merge_p): Avoid merging across different + values of error and warning attributes. + 2015-12-08 Jan Hubicka PR lto/68811 diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index d4868c4dcd7..35c690ae41a 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -511,19 +511,59 @@ static bool lto_symtab_merge_p (tree prevailing, tree decl) { if (TREE_CODE (prevailing) != TREE_CODE (decl)) - return false; + { + if (symtab->dump_file) + fprintf (symtab->dump_file, "Not merging decls; " + "TREE_CODE mismatch\n"); + return false; + } if (TREE_CODE (prevailing) == FUNCTION_DECL) { if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl)) - return false; + { + if (symtab->dump_file) + fprintf (symtab->dump_file, "Not merging decls; " + "DECL_BUILT_IN mismatch\n"); + return false; + } if (DECL_BUILT_IN (prevailing) && (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl) || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl))) - return false; + { + if (symtab->dump_file) + fprintf (symtab->dump_file, "Not merging decls; " + "DECL_BUILT_IN_CLASS or CODE mismatch\n"); + return false; + } + } + if (DECL_ATTRIBUTES (prevailing) != DECL_ATTRIBUTES (decl)) + { + tree prev_attr = lookup_attribute ("error", DECL_ATTRIBUTES (prevailing)); + tree attr = lookup_attribute ("error", DECL_ATTRIBUTES (decl)); + if ((prev_attr == NULL) != (attr == NULL) + || (prev_attr + && TREE_VALUE (TREE_VALUE (prev_attr)) + != TREE_VALUE (TREE_VALUE (attr)))) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, "Not merging decls; " + "error attribute mismatch\n"); + return false; + } + + prev_attr = lookup_attribute ("warning", DECL_ATTRIBUTES (prevailing)); + attr = lookup_attribute ("warning", DECL_ATTRIBUTES (decl)); + if ((prev_attr == NULL) != (attr == NULL) + || (prev_attr + && TREE_VALUE (TREE_VALUE (prev_attr)) + != TREE_VALUE (TREE_VALUE (attr)))) + { + if (symtab->dump_file) + fprintf (symtab->dump_file, "Not merging decls; " + "warning attribute mismatch\n"); + return false; + } } - /* There are several other cases where merging can not be done, but until - aliasing code is fixed to support aliases it we can not really return - false on non-readonly var, yet. */ return true; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef97e761d45..72570461492 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-11 Jan Hubicka + + PR ipa/61886 + * gcc.dg/lto/pr61886_0.c: New testcase + 2015-12-10 Jan Hubicka * gcc.c-torture/execute/20010122-1.c: Disable cloning. diff --git a/gcc/testsuite/gcc.dg/lto/pr61886_0.c b/gcc/testsuite/gcc.dg/lto/pr61886_0.c new file mode 100644 index 00000000000..c583774acac --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr61886_0.c @@ -0,0 +1,33 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options { { -flto -O2 -Werror } } } */ + +typedef __SIZE_TYPE__ size_t; +typedef struct _IO_FILE FILE; + +extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "__fread_chk") __attribute__ ((__warn_unused_result__)); +extern size_t __fread_chk_warn (void *__restrict __ptr, size_t __ptrlen, size_t __size, size_t __n, FILE *__restrict __stream) __asm__ ("" "__fread_chk") __attribute__ ((__warn_unused_result__)) __attribute__((__warning__ ("fread called with bigger size * nmemb than length " "of destination buffer"))); + +extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) __attribute__ ((__warn_unused_result__)) +size_t +fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) +{ + if (__builtin_object_size (__ptr, 0) != (size_t) -1) + { + if (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) + return __fread_chk (__ptr, __builtin_object_size (__ptr, 0), __size, __n, __stream); + if (__size * __n > __builtin_object_size (__ptr, 0)) + return __fread_chk_warn (__ptr, __builtin_object_size (__ptr, 0), __size, __n, __stream); + } +} + +volatile size_t nmemb; +FILE *fp; +int main () +{ + char file_contents[4096]; + /* We shouldn't get this resolved to a call to __fread_chk_warn. */ + return fread (file_contents, 1, nmemb, fp); +} -- 2.30.2