diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-12-11 00:57:15 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-12-10 23:57:15 +0000 |
commit | 958a627f8831aad2d1d87c1a95b622722f375e73 (patch) | |
tree | 81333eac2542fe1d73ebec68b922ed18cd399b73 /gcc | |
parent | 0c91a1fb3c6bf27bd513d6a160bdce14a7070a60 (diff) | |
download | gcc-958a627f8831aad2d1d87c1a95b622722f375e73.zip gcc-958a627f8831aad2d1d87c1a95b622722f375e73.tar.gz gcc-958a627f8831aad2d1d87c1a95b622722f375e73.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/lto/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/lto/lto-symtab.c | 52 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/lto/pr61886_0.c | 33 |
4 files changed, 90 insertions, 6 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 4fe2ebe..f0d90fc 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2015-12-11 Jan Hubicka <hubicka@ucw.cz> + + 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 <hubicka@ucw.cz> PR lto/68811 diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index d4868c4..35c690a 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 ef97e76..7257046 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-12-11 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/61886 + * gcc.dg/lto/pr61886_0.c: New testcase + 2015-12-10 Jan Hubicka <hubicka@ucw.cz> * 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 0000000..c583774 --- /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); +} |