Hi. I'm sending GCC 7 branch backports I've just tested and regbootstrapped. I'm going to install that.
Thanks, Martin
>From 10479fa4d3576b19b58d7ffc0949c2828ab6c2ff Mon Sep 17 00:00:00 2001 From: segher <segher@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 23 Feb 2018 14:17:35 +0000 Subject: [PATCH 17/17] Backport r257932 gcc/testsuite/ChangeLog: 2018-02-23 Segher Boessenkool <seg...@kernel.crashing.org> PR testsuite/80551 * c-c++-common/tsan/race_on_mutex.c: Change regexp to allow __GI___pthread_mutex_init as well. --- gcc/testsuite/c-c++-common/tsan/race_on_mutex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c index def1d47de7b..2e4b7ac3cb9 100644 --- a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c +++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c @@ -42,5 +42,5 @@ int main() { /* { dg-output " #1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */ /* { dg-output " Previous write of size \[0-9]\+ at .* by thread T1:(\n|\r\n|\r)" } */ /* { dg-output "( #0 \[^\n\r\]*(\n|\r\n|\r))?" } */ -/* { dg-output " #\[01\] (__)?pthread_mutex_init \[^\n\r\]* (.)*" } */ +/* { dg-output " #\[01\] ((__GI_)?__)?pthread_mutex_init \[^\n\r\]* (.)*" } */ /* { dg-output " #\[12\] Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */ -- 2.16.2
>From cdf8aac55c7bddbb4e25bab8368f3057d1387d36 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 20 Feb 2018 10:04:13 +0000 Subject: [PATCH 16/17] Backport r257842 gcc/ChangeLog: 2018-02-20 Martin Liska <mli...@suse.cz> PR c/84310 PR target/79747 * final.c (shorten_branches): Build align_tab array with one more element. * opts.c (finish_options): Add alignment option limit check. (MAX_CODE_ALIGN): Likewise. (MAX_CODE_ALIGN_VALUE): Likewise. * doc/invoke.texi: Document maximum allowed option value for all -falign-* options. gcc/testsuite/ChangeLog: 2018-02-20 Martin Liska <mli...@suse.cz> PR c/84310 PR target/79747 * gcc.target/i386/pr84310.c: New test. * gcc.target/i386/pr84310-2.c: Likewise. --- gcc/doc/invoke.texi | 4 ++++ gcc/final.c | 4 ++-- gcc/opts.c | 20 ++++++++++++++++++++ gcc/testsuite/gcc.target/i386/pr84310-2.c | 10 ++++++++++ gcc/testsuite/gcc.target/i386/pr84310.c | 8 ++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr84310-2.c create mode 100644 gcc/testsuite/gcc.target/i386/pr84310.c diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 41bb8f05216..d65bd32a092 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8690,6 +8690,7 @@ Some assemblers only support this flag when @var{n} is a power of two; in that case, it is rounded up. If @var{n} is not specified or is zero, use a machine-dependent default. +The maximum allowed @var{n} option value is 65536. Enabled at levels @option{-O2}, @option{-O3}. @@ -8715,6 +8716,7 @@ are greater than this value, then their values are used instead. If @var{n} is not specified or is zero, use a machine-dependent default which is very likely to be @samp{1}, meaning no alignment. +The maximum allowed @var{n} option value is 65536. Enabled at levels @option{-O2}, @option{-O3}. @@ -8728,6 +8730,7 @@ operations. @option{-fno-align-loops} and @option{-falign-loops=1} are equivalent and mean that loops are not aligned. +The maximum allowed @var{n} option value is 65536. If @var{n} is not specified or is zero, use a machine-dependent default. @@ -8745,6 +8748,7 @@ need be executed. equivalent and mean that loops are not aligned. If @var{n} is not specified or is zero, use a machine-dependent default. +The maximum allowed @var{n} option value is 65536. Enabled at levels @option{-O2}, @option{-O3}. diff --git a/gcc/final.c b/gcc/final.c index 820162b2d28..20af67816bb 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -906,7 +906,7 @@ shorten_branches (rtx_insn *first) char *varying_length; rtx body; int uid; - rtx align_tab[MAX_CODE_ALIGN]; + rtx align_tab[MAX_CODE_ALIGN + 1]; /* Compute maximum UID and allocate label_align / uid_shuid. */ max_uid = get_max_uid (); @@ -1015,7 +1015,7 @@ shorten_branches (rtx_insn *first) alignment of n. */ uid_align = XCNEWVEC (rtx, max_uid); - for (i = MAX_CODE_ALIGN; --i >= 0;) + for (i = MAX_CODE_ALIGN + 1; --i >= 0;) align_tab[i] = NULL_RTX; seq = get_last_insn (); for (; seq; seq = PREV_INSN (seq)) diff --git a/gcc/opts.c b/gcc/opts.c index f03b57aa343..e5126618f35 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1014,6 +1014,26 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm) sorry ("transactional memory is not supported with " "%<-fsanitize=kernel-address%>"); + + /* Comes from final.c -- no real reason to change it. */ +#define MAX_CODE_ALIGN 16 +#define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN) + + if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-loops=%d is not between 0 and %d", + opts->x_align_loops, MAX_CODE_ALIGN_VALUE); + + if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-jumps=%d is not between 0 and %d", + opts->x_align_jumps, MAX_CODE_ALIGN_VALUE); + + if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-functions=%d is not between 0 and %d", + opts->x_align_functions, MAX_CODE_ALIGN_VALUE); + + if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE) + error_at (loc, "-falign-labels=%d is not between 0 and %d", + opts->x_align_labels, MAX_CODE_ALIGN_VALUE); } #define LEFT_COLUMN 27 diff --git a/gcc/testsuite/gcc.target/i386/pr84310-2.c b/gcc/testsuite/gcc.target/i386/pr84310-2.c new file mode 100644 index 00000000000..dbf5db6ff87 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84310-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -malign-loops=16" } */ +/* { dg-warning "is obsolete" "" { target *-*-* } 0 } */ + +void +c (void) +{ + for (;;) + ; +} diff --git a/gcc/testsuite/gcc.target/i386/pr84310.c b/gcc/testsuite/gcc.target/i386/pr84310.c new file mode 100644 index 00000000000..f82327e45f3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84310.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -falign-functions=100000" } */ +/* { dg-error "is not between 0 and 65536" "" { target *-*-* } 0 } */ + +void +test_func (void) +{ +} -- 2.16.2
>From 4e1fc52057e151854fb85809b0adba6bab406e51 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Mon, 19 Feb 2018 09:54:09 +0000 Subject: [PATCH 15/17] Backport r257803 gcc/ChangeLog: 2018-02-19 Martin Liska <mli...@suse.cz> PR other/80589 * doc/invoke.texi: Fix typo. * params.def (PARAM_MAX_LOOP_HEADER_INSNS): Likewise. --- gcc/doc/invoke.texi | 2 +- gcc/params.def | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index c5860d9387b..41bb8f05216 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8132,7 +8132,7 @@ This flag is enabled by default at @option{-O2} and higher and depends on @item -fisolate-erroneous-paths-attribute @opindex fisolate-erroneous-paths-attribute -Detect paths that trigger erroneous or undefined behavior due a null value +Detect paths that trigger erroneous or undefined behavior due to a null value being used in a way forbidden by a @code{returns_nonnull} or @code{nonnull} attribute. Isolate those paths from the main control flow and turn the statement with erroneous or undefined behavior into a trap. This is not diff --git a/gcc/params.def b/gcc/params.def index 6b07518a34b..9c83b0af3ef 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -344,11 +344,11 @@ DEFPARAM(PARAM_MAX_UNSWITCH_LEVEL, "The maximum number of unswitchings in a single loop.", 3, 0, 0) -/* The maximum number of insns in loop header duplicated by he copy loop +/* The maximum number of insns in loop header duplicated by the copy loop headers pass. */ DEFPARAM(PARAM_MAX_LOOP_HEADER_INSNS, "max-loop-header-insns", - "The maximum number of insns in loop header duplicated by he copy loop headers pass.", + "The maximum number of insns in loop header duplicated by the copy loop headers pass.", 20, 0, 0) /* The maximum number of iterations of a loop the brute force algorithm -- 2.16.2
>From ce7917dcfb130095fe42a11b8a45f2c5f165ef26 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Mon, 5 Feb 2018 09:59:16 +0000 Subject: [PATCH 14/17] Backport r257384 gcc/ChangeLog: 2018-02-05 Martin Liska <mli...@suse.cz> PR gcov-profile/84137 * doc/gcov.texi: Fix typo in documentation. --- gcc/doc/gcov.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index 32df292a023..4c232113ca3 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -322,7 +322,7 @@ program source code. The format is Additional block information may succeed each line, when requested by command line option. The @var{execution_count} is @samp{-} for lines containing no code. Unexecuted lines are marked @samp{#####} or -@samp{====}, depending on whether they are reachable by +@samp{=====}, depending on whether they are reachable by non-exceptional paths or only exceptional paths such as C++ exception handlers, respectively. Given @samp{-a} option, unexecuted blocks are marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block -- 2.16.2
>From a12ae05a6d8ef234b7866913fa3391fec33a486a Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Mon, 5 Feb 2018 09:19:18 +0000 Subject: [PATCH 13/17] Backport r257383 gcc/ChangeLog: 2018-02-05 Martin Liska <mli...@suse.cz> PR gcov-profile/83879 * doc/gcov.texi: Document necessity of --dynamic-list-data when using dlopen functionality. --- gcc/doc/gcov.texi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index 88b8d6d9071..32df292a023 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -618,6 +618,8 @@ Instrumented applications use a static destructor with priority 99 to invoke the @code{__gcov_dump} function. Thus @code{__gcov_dump} is executed after all user defined static destructors, as well as handlers registered with @code{atexit}. +If an executable loads a dynamic shared object via dlopen functionality, +@option{-Wl,--dynamic-list-data} is needed to dump all profile data. @c man end -- 2.16.2
>From 53ce8c1de1cda4f8aa0aaab6256711c071d17443 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 23 Jan 2018 15:46:02 +0000 Subject: [PATCH 12/17] Backport r256989 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 5ce5a447b3f..4cef26897fe 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -365,18 +365,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 } +}; -- 2.16.2
>From 63100f6d357506614f2c4112ec0862ae2cddd807 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 19 Dec 2017 13:20:07 +0000 Subject: [PATCH 11/17] Backport r255818 gcc/ChangeLog: 2017-12-19 Martin Liska <mli...@suse.cz> PR rtl-optimization/82675 * loop-unroll.c (unroll_loop_constant_iterations): Allocate one more element in sbitmap. --- gcc/loop-unroll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index 3d48a8fb7bc..21959f716b1 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -477,7 +477,7 @@ unroll_loop_constant_iterations (struct loop *loop) exit_mod = niter % (max_unroll + 1); - auto_sbitmap wont_exit (max_unroll + 1); + auto_sbitmap wont_exit (max_unroll + 2); bitmap_ones (wont_exit); auto_vec<edge> remove_edges; -- 2.16.2
>From 24982bb404a0aa7e2d1c00fc82af17ada0bde015 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu, 27 Apr 2017 14:28:06 +0000 Subject: [PATCH 10/17] Backport r247342 gcc/testsuite/ChangeLog: 2017-04-27 Martin Liska <mli...@suse.cz> PR testsuite/79455 * c-c++-common/tsan/race_on_mutex.c: Make the scanned pattern more generic. --- gcc/testsuite/c-c++-common/tsan/race_on_mutex.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c index ae30d053c92..def1d47de7b 100644 --- a/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c +++ b/gcc/testsuite/c-c++-common/tsan/race_on_mutex.c @@ -37,9 +37,10 @@ int main() { } /* { dg-output "WARNING: ThreadSanitizer: data race.*(\n|\r\n|\r)" } */ -/* { dg-output " Atomic read of size 1 at .* by thread T2:(\n|\r\n|\r)" } */ +/* { dg-output " Atomic read of size \[0-9]\+ at .* by thread T2:(\n|\r\n|\r)" } */ /* { dg-output " #0 pthread_mutex_lock.*" } */ /* { dg-output " #1 Thread2.* .*(race_on_mutex.c:22|\\?{2}:0) (.*)" } */ -/* { dg-output " Previous write of size 1 at .* by thread T1:(\n|\r\n|\r)" } */ -/* { dg-output " #0 pthread_mutex_init .* (.)*" } */ -/* { dg-output " #1 Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */ +/* { dg-output " Previous write of size \[0-9]\+ at .* by thread T1:(\n|\r\n|\r)" } */ +/* { dg-output "( #0 \[^\n\r\]*(\n|\r\n|\r))?" } */ +/* { dg-output " #\[01\] (__)?pthread_mutex_init \[^\n\r\]* (.)*" } */ +/* { dg-output " #\[12\] Thread1.* .*(race_on_mutex.c:12|\\?{2}:0) .*" } */ -- 2.16.2
>From 289fc4cf2cdfda0b595fdff356711e564c5b9539 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Mon, 5 Mar 2018 15:30:47 +0100 Subject: [PATCH 09/17] Fix IPA profile merging, fixed in trunk with r253910. gcc/ChangeLog: 2018-03-05 Martin Liska <mli...@suse.cz> * ipa-utils.c (ipa_merge_profiles): Do not merge alias or a function without profile. --- gcc/ipa-utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 959e31a68e6..f7dd29f925c 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -404,6 +404,8 @@ ipa_merge_profiles (struct cgraph_node *dst, if (!dst->count) return; + if (!src->count || src->alias) + return; if (symtab->dump_file) { fprintf (symtab->dump_file, "Merging profiles of %s/%i to %s/%i\n", -- 2.16.2
>From 0686170bf059362f6bced6d336fdc230f082636a Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 23 Feb 2018 18:18:07 +0000 Subject: [PATCH 08/17] Backport r257939 gcc/lto/ChangeLog: 2018-02-08 Jan Hubicka <hubi...@ucw.cz> * lto-partition.c (lto_balanced_map): Watch overflow. --- gcc/lto/lto-partition.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index e27d0d1690c..a624dfa8847 100644 --- a/gcc/lto/lto-partition.c +++ b/gcc/lto/lto-partition.c @@ -756,7 +756,8 @@ lto_balanced_map (int n_lto_partitions, int max_partition_size) if (npartitions < n_lto_partitions) partition_size = total_size / (n_lto_partitions - npartitions); else - partition_size = INT_MAX; + /* Watch for overflow. */ + partition_size = INT_MAX / 16; if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) partition_size = PARAM_VALUE (MIN_PARTITION_SIZE); -- 2.16.2
>From 4d2b6f6e556c5d9e35607ef38c6917bc08c99637 Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed, 21 Feb 2018 19:05:30 +0000 Subject: [PATCH 07/17] Backport r257877 gcc/ChangeLog: 2018-02-21 Jan Hubicka <hubi...@ucw.cz> PR c/84229 * ipa-cp.c (determine_versionability): Do not version functions caling va_arg_pack. --- gcc/ipa-cp.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 716c8cc3a1f..f5dcfc0341b 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -621,6 +621,24 @@ determine_versionability (struct cgraph_node *node, reason = "calls comdat-local function"; } + /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN + works only when inlined. Cloning them may still lead to better code + becuase ipa-cp will not give up on cloning further. If the function is + external this however leads to wrong code becuase we may end up producing + offline copy of the function. */ + if (DECL_EXTERNAL (node->decl)) + for (cgraph_edge *edge = node->callees; !reason && edge; + edge = edge->next_callee) + if (DECL_BUILT_IN (edge->callee->decl) + && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL) + { + if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK) + reason = "external function which calls va_arg_pack"; + if (DECL_FUNCTION_CODE (edge->callee->decl) + == BUILT_IN_VA_ARG_PACK_LEN) + reason = "external function which calls va_arg_pack_len"; + } + if (reason && dump_file && !node->alias && !node->thunk.thunk_p) fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n", node->name (), node->order, reason); -- 2.16.2
>From 1556fbdf74f4b99f4fc14947debba845efccf165 Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu, 8 Feb 2018 14:51:51 +0000 Subject: [PATCH 06/17] Backport r257490 gcc/ChangeLog: 2018-02-08 Jan Hubicka <hubi...@ucw.cz> PR ipa/81360 * cgraph.h (symtab_node::output_to_lto_symbol_table_p): Declare * symtab.c: Include builtins.h (symtab_node::output_to_lto_symbol_table_p): Move here from lto-streamer-out.c:output_symbol_p. * lto-streamer-out.c (write_symbol): Turn early exit to assert. (output_symbol_p): Move all logic to symtab.c (produce_symtab): Update. gcc/lto/ChangeLog: 2018-02-08 Jan Hubicka <hubi...@ucw.cz> PR ipa/81360 * lto.c (unify_scc): Register prevailing trees, not trees to be freed. (read_cgraph_and_symbols): Use symtab_node::output_to_lto_symbol_table_p. --- gcc/cgraph.h | 3 +++ gcc/lto-streamer-out.c | 54 ++++++------------------------------------------ gcc/lto/lto.c | 17 ++++++++++----- gcc/symtab.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree.c | 7 ++++--- 5 files changed, 81 insertions(+), 56 deletions(-) diff --git a/gcc/cgraph.h b/gcc/cgraph.h index be4eaee71e2..ee053885442 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -321,6 +321,9 @@ public: or abstract function kept for debug info purposes only. */ bool real_symbol_p (void); + /* Return true when the symbol needs to be output to the LTO symbol table. */ + bool output_to_lto_symbol_table_p (void); + /* Determine if symbol declaration is needed. That is, visible to something either outside this translation unit, something magic in the system configury. This function is used just during symbol creation. */ diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index b96b9df63b7..89313727068 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -2524,13 +2524,10 @@ write_symbol (struct streamer_tree_cache_d *cache, const char *comdat; unsigned char c; - /* None of the following kinds of symbols are needed in the - symbol table. */ - if (!TREE_PUBLIC (t) - || is_builtin_fn (t) - || DECL_ABSTRACT_P (t) - || (VAR_P (t) && DECL_HARD_REGISTER (t))) - return; + gcc_checking_assert (TREE_PUBLIC (t) + && !is_builtin_fn (t) + && !DECL_ABSTRACT_P (t) + && (!VAR_P (t) || !DECL_HARD_REGISTER (t))); gcc_assert (VAR_OR_FUNCTION_DECL_P (t)); @@ -2618,45 +2615,6 @@ write_symbol (struct streamer_tree_cache_d *cache, lto_write_data (&slot_num, 4); } -/* Return true if NODE should appear in the plugin symbol table. */ - -bool -output_symbol_p (symtab_node *node) -{ - struct cgraph_node *cnode; - if (!node->real_symbol_p ()) - return false; - /* We keep external functions in symtab for sake of inlining - and devirtualization. We do not want to see them in symbol table as - references unless they are really used. */ - cnode = dyn_cast <cgraph_node *> (node); - if (cnode && (!node->definition || DECL_EXTERNAL (cnode->decl)) - && cnode->callers) - return true; - - /* Ignore all references from external vars initializers - they are not really - part of the compilation unit until they are used by folding. Some symbols, - like references to external construction vtables can not be referred to at all. - We decide this at can_refer_decl_in_current_unit_p. */ - if (!node->definition || DECL_EXTERNAL (node->decl)) - { - int i; - struct ipa_ref *ref; - for (i = 0; node->iterate_referring (i, ref); i++) - { - if (ref->use == IPA_REF_ALIAS) - continue; - if (is_a <cgraph_node *> (ref->referring)) - return true; - if (!DECL_EXTERNAL (ref->referring->decl)) - return true; - } - return false; - } - return true; -} - - /* Write an IL symbol table to OB. SET and VSET are cgraph/varpool node sets we are outputting. */ @@ -2681,7 +2639,7 @@ produce_symtab (struct output_block *ob) { symtab_node *node = lsei_node (lsei); - if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl)) + if (DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ()) continue; write_symbol (cache, node->decl, &seen, false); } @@ -2690,7 +2648,7 @@ produce_symtab (struct output_block *ob) { symtab_node *node = lsei_node (lsei); - if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl)) + if (!DECL_EXTERNAL (node->decl) || !node->output_to_lto_symbol_table_p ()) continue; write_symbol (cache, node->decl, &seen, false); } diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index e6b58ef197a..8a82f923b6e 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1638,13 +1638,16 @@ unify_scc (struct data_in *data_in, unsigned from, { map2[i*2] = (tree)(uintptr_t)(from + i); map2[i*2+1] = scc->entries[i]; - lto_maybe_register_decl (data_in, scc->entries[i], from + i); } qsort (map2, len, 2 * sizeof (tree), cmp_tree); qsort (map, len, 2 * sizeof (tree), cmp_tree); for (unsigned i = 0; i < len; ++i) - streamer_tree_cache_replace_tree (cache, map[2*i], - (uintptr_t)map2[2*i]); + { + lto_maybe_register_decl (data_in, map[2*i], + (uintptr_t)map2[2*i]); + streamer_tree_cache_replace_tree (cache, map[2*i], + (uintptr_t)map2[2*i]); + } } /* Free the tree nodes from the read SCC. */ @@ -2886,8 +2889,12 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) res = snode->lto_file_data->resolution_map->get (snode->decl); if (!res || *res == LDPR_UNKNOWN) - fatal_error (input_location, "missing resolution data for %s", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (snode->decl))); + { + if (snode->output_to_lto_symbol_table_p ()) + fatal_error (input_location, "missing resolution data for %s", + IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (snode->decl))); + } else snode->resolution = *res; } diff --git a/gcc/symtab.c b/gcc/symtab.c index 342cc36f3af..c18f1b25199 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "ipa-utils.h" #include "calls.h" +#include "builtins.h" static const char *ipa_ref_use_name[] = {"read","write","addr","alias","chkp"}; @@ -2279,3 +2280,58 @@ symtab_node::binds_to_current_def_p (symtab_node *ref) return false; } + +/* Return true if symbol should be output to the symbol table. */ + +bool +symtab_node::output_to_lto_symbol_table_p (void) +{ + /* Only externally visible symbols matter. */ + if (!TREE_PUBLIC (decl)) + return false; + if (!real_symbol_p ()) + return false; + /* FIXME: variables probably should not be considered as real symbols at + first place. */ + if (VAR_P (decl) && DECL_HARD_REGISTER (decl)) + return false; + /* FIXME: Builtins corresponding to real functions probably should have + symbol table entries. */ + if (is_builtin_fn (decl)) + return false; + + /* We have real symbol that should be in symbol table. However try to trim + down the refernces to libraries bit more because linker will otherwise + bring unnecesary object files into the final link. + FIXME: The following checks can easily be confused i.e. by self recursive + function or self-referring variable. */ + + /* We keep external functions in symtab for sake of inlining + and devirtualization. We do not want to see them in symbol table as + references unless they are really used. */ + cgraph_node *cnode = dyn_cast <cgraph_node *> (this); + if (cnode && (!definition || DECL_EXTERNAL (decl)) + && cnode->callers) + return true; + + /* Ignore all references from external vars initializers - they are not really + part of the compilation unit until they are used by folding. Some symbols, + like references to external construction vtables can not be referred to at + all. We decide this at can_refer_decl_in_current_unit_p. */ + if (!definition || DECL_EXTERNAL (decl)) + { + int i; + struct ipa_ref *ref; + for (i = 0; iterate_referring (i, ref); i++) + { + if (ref->use == IPA_REF_ALIAS) + continue; + if (is_a <cgraph_node *> (ref->referring)) + return true; + if (!DECL_EXTERNAL (ref->referring->decl)) + return true; + } + return false; + } + return true; +} diff --git a/gcc/tree.c b/gcc/tree.c index 698213c3501..0e98f53af96 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5454,9 +5454,10 @@ free_lang_data_in_decl (tree decl) At this point, it is not needed anymore. */ DECL_SAVED_TREE (decl) = NULL_TREE; - /* Clear the abstract origin if it refers to a method. Otherwise - dwarf2out.c will ICE as we clear TYPE_METHODS and thus the - origin will not be output correctly. */ + /* Clear the abstract origin if it refers to a method. + Otherwise dwarf2out.c will ICE as we splice functions out of + TYPE_FIELDS and thus the origin will not be output + correctly. */ if (DECL_ABSTRACT_ORIGIN (decl) && DECL_CONTEXT (DECL_ABSTRACT_ORIGIN (decl)) && RECORD_OR_UNION_TYPE_P -- 2.16.2
>From b04a9457628fa6f37f847a7cdfe1ed14edecb220 Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed, 7 Feb 2018 10:20:03 +0000 Subject: [PATCH 05/17] Backport r257442 gcc/lto/ChangeLog: 2018-01-30 Jan Hubicka <hubi...@ucw.cz> * lto.c (register_resolution): Remove forgotten sanity check. --- gcc/lto/lto.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index f3958b5a41b..e6b58ef197a 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -838,7 +838,6 @@ register_resolution (struct lto_file_decl_data *file_data, tree decl, = new hash_map<tree, ld_plugin_symbol_resolution>; ld_plugin_symbol_resolution_t &res = file_data->resolution_map->get_or_insert (decl, &existed); - gcc_assert (!existed || res == resolution); if (!existed || resolution == LDPR_PREVAILING_DEF_IRONLY || resolution == LDPR_PREVAILING_DEF -- 2.16.2
>From cf08b93ce18cbe3434abcf99868860d770b1c661 Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 6 Feb 2018 13:27:04 +0000 Subject: [PATCH 04/17] Backport r257412 gcc/lto/ChangeLog: 2018-01-30 Jan Hubicka <hubi...@ucw.cz> PR lto/81004 * lto.c: Include builtins.h (register_resolution): Merge resolutions in case trees was merged across units. (lto_maybe_register_decl): Break out from ... (lto_read_decls): ... here. (unify_scc): Also register decls here. (read_cgraph_and_symbols): Sanity check that all resolutions was read. --- gcc/lto/lto.c | 57 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index a7d5e450ea0..f3958b5a41b 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "lto-symtab.h" #include "stringpool.h" #include "fold-const.h" +#include "builtins.h" /* Number of parallel tasks to run, -1 if we want to use GNU Make jobserver. */ @@ -829,12 +830,20 @@ static void register_resolution (struct lto_file_decl_data *file_data, tree decl, enum ld_plugin_symbol_resolution resolution) { + bool existed; if (resolution == LDPR_UNKNOWN) return; if (!file_data->resolution_map) file_data->resolution_map = new hash_map<tree, ld_plugin_symbol_resolution>; - file_data->resolution_map->put (decl, resolution); + ld_plugin_symbol_resolution_t &res + = file_data->resolution_map->get_or_insert (decl, &existed); + gcc_assert (!existed || res == resolution); + if (!existed + || resolution == LDPR_PREVAILING_DEF_IRONLY + || resolution == LDPR_PREVAILING_DEF + || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + res = resolution; } /* Register DECL with the global symbol table and change its @@ -877,6 +886,18 @@ lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl, decl, get_resolution (data_in, ix)); } +/* Check if T is a decl and needs register its resolution info. */ + +static void +lto_maybe_register_decl (struct data_in *data_in, tree t, unsigned ix) +{ + if (TREE_CODE (t) == VAR_DECL) + lto_register_var_decl_in_symtab (data_in, t, ix); + else if (TREE_CODE (t) == FUNCTION_DECL + && !DECL_BUILT_IN (t)) + lto_register_function_decl_in_symtab (data_in, t, ix); +} + /* For the type T re-materialize it in the type variant list and the pointer/reference-to chains. */ @@ -1607,7 +1628,10 @@ unify_scc (struct data_in *data_in, unsigned from, /* Fixup the streamer cache with the prevailing nodes according to the tree node mapping computed by compare_tree_sccs. */ if (len == 1) - streamer_tree_cache_replace_tree (cache, pscc->entries[0], from); + { + lto_maybe_register_decl (data_in, pscc->entries[0], from); + streamer_tree_cache_replace_tree (cache, pscc->entries[0], from); + } else { tree *map2 = XALLOCAVEC (tree, 2 * len); @@ -1615,6 +1639,7 @@ unify_scc (struct data_in *data_in, unsigned from, { map2[i*2] = (tree)(uintptr_t)(from + i); map2[i*2+1] = scc->entries[i]; + lto_maybe_register_decl (data_in, scc->entries[i], from + i); } qsort (map2, len, 2 * sizeof (tree), cmp_tree); qsort (map, len, 2 * sizeof (tree), cmp_tree); @@ -1759,13 +1784,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data, } if (!flag_ltrans) { - /* Register variables and functions with the - symbol table. */ - if (TREE_CODE (t) == VAR_DECL) - lto_register_var_decl_in_symtab (data_in, t, from + i); - else if (TREE_CODE (t) == FUNCTION_DECL - && !DECL_BUILT_IN (t)) - lto_register_function_decl_in_symtab (data_in, t, from + i); + lto_maybe_register_decl (data_in, t, from + i); /* Scan the tree for references to global functions or variables and record those for later fixup. */ if (mentions_vars_p (t)) @@ -2858,13 +2877,21 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) /* Store resolutions into the symbol table. */ - ld_plugin_symbol_resolution_t *res; FOR_EACH_SYMBOL (snode) - if (snode->real_symbol_p () - && snode->lto_file_data - && snode->lto_file_data->resolution_map - && (res = snode->lto_file_data->resolution_map->get (snode->decl))) - snode->resolution = *res; + if (snode->externally_visible && snode->real_symbol_p () + && snode->lto_file_data && snode->lto_file_data->resolution_map + && !is_builtin_fn (snode->decl) + && !(VAR_P (snode->decl) && DECL_HARD_REGISTER (snode->decl))) + { + ld_plugin_symbol_resolution_t *res; + + res = snode->lto_file_data->resolution_map->get (snode->decl); + if (!res || *res == LDPR_UNKNOWN) + fatal_error (input_location, "missing resolution data for %s", + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (snode->decl))); + else + snode->resolution = *res; + } for (i = 0; all_file_decl_data[i]; i++) if (all_file_decl_data[i]->resolution_map) { -- 2.16.2
>From 9ddebdc242958549104b96f5f968355c1c92da25 Mon Sep 17 00:00:00 2001 From: ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 2 Feb 2018 18:09:32 +0000 Subject: [PATCH 03/17] Backport r257343 gcc/lto/ChangeLog: 2018-02-02 Eric Botcazou <ebotca...@adacore.com> PR lto/83954 * lto-symtab.c (warn_type_compatibility_p): Do not recurse into the component type of array types with non-aliased component. --- gcc/lto/lto-symtab.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index 802453ea699..5ce5a447b3f 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -287,9 +287,12 @@ warn_type_compatibility_p (tree prevailing_type, tree type, { tree t1 = type, t2 = prevailing_type; - /* Alias sets of arrays are the same as alias sets of the inner - types. */ - while (TREE_CODE (t1) == ARRAY_TYPE && TREE_CODE (t2) == ARRAY_TYPE) + /* Alias sets of arrays with aliased components are the same as alias + sets of the inner types. */ + while (TREE_CODE (t1) == ARRAY_TYPE + && !TYPE_NONALIASED_COMPONENT (t1) + && TREE_CODE (t2) == ARRAY_TYPE + && !TYPE_NONALIASED_COMPONENT (t2)) { t1 = TREE_TYPE (t1); t2 = TREE_TYPE (t2); -- 2.16.2
>From b35581dd06730c60bc3145cbc97304d3fc90956a Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 30 Jan 2018 13:17:40 +0000 Subject: [PATCH 02/17] Backport r257183 gcc/lto/ChangeLog: 2018-01-30 Jan Hubicka <hubi...@ucw.cz> PR lto/83954 * lto-symtab.c (warn_type_compatibility_p): Silence false positive for type match warning on arrays of pointers. gcc/testsuite/ChangeLog: 2018-01-30 Jan Hubicka <hubi...@ucw.cz> PR lto/83954 * gcc.dg/lto/pr83954.h: New testcase. * gcc.dg/lto/pr83954_0.c: New testcase. * gcc.dg/lto/pr83954_1.c: New testcase. --- gcc/lto/lto-symtab.c | 19 +++++++++++++++---- gcc/testsuite/gcc.dg/lto/pr83954.h | 3 +++ gcc/testsuite/gcc.dg/lto/pr83954_0.c | 8 ++++++++ gcc/testsuite/gcc.dg/lto/pr83954_1.c | 7 +++++++ 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lto/pr83954.h create mode 100644 gcc/testsuite/gcc.dg/lto/pr83954_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr83954_1.c diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c index f61b1f80133..802453ea699 100644 --- a/gcc/lto/lto-symtab.c +++ b/gcc/lto/lto-symtab.c @@ -283,11 +283,22 @@ warn_type_compatibility_p (tree prevailing_type, tree type, alias_set_type set1 = get_alias_set (type); alias_set_type set2 = get_alias_set (prevailing_type); - if (set1 && set2 && set1 != set2 - && (!POINTER_TYPE_P (type) || !POINTER_TYPE_P (prevailing_type) + if (set1 && set2 && set1 != set2) + { + tree t1 = type, t2 = prevailing_type; + + /* Alias sets of arrays are the same as alias sets of the inner + types. */ + while (TREE_CODE (t1) == ARRAY_TYPE && TREE_CODE (t2) == ARRAY_TYPE) + { + t1 = TREE_TYPE (t1); + t2 = TREE_TYPE (t2); + } + if ((!POINTER_TYPE_P (t1) || !POINTER_TYPE_P (t2)) || (set1 != TYPE_ALIAS_SET (ptr_type_node) - && set2 != TYPE_ALIAS_SET (ptr_type_node)))) - lev |= 5; + && set2 != TYPE_ALIAS_SET (ptr_type_node))) + lev |= 5; + } } return lev; diff --git a/gcc/testsuite/gcc.dg/lto/pr83954.h b/gcc/testsuite/gcc.dg/lto/pr83954.h new file mode 100644 index 00000000000..e0155402504 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr83954.h @@ -0,0 +1,3 @@ +struct foo; +extern struct foo *FOO_PTR_ARR[1]; + diff --git a/gcc/testsuite/gcc.dg/lto/pr83954_0.c b/gcc/testsuite/gcc.dg/lto/pr83954_0.c new file mode 100644 index 00000000000..065a31dab80 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr83954_0.c @@ -0,0 +1,8 @@ +/* { dg-lto-do link } */ +#include "pr83954.h" + +int main() { + // just to prevent symbol removal + FOO_PTR_ARR[1] = 0; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr83954_1.c b/gcc/testsuite/gcc.dg/lto/pr83954_1.c new file mode 100644 index 00000000000..61b40fc7759 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr83954_1.c @@ -0,0 +1,7 @@ +#include "pr83954.h" + +struct foo { + int x; +}; +struct foo *FOO_PTR_ARR[1] = { 0 }; + -- 2.16.2
>From bd82d3faff59d05a27796cb9b527848564d84ede Mon Sep 17 00:00:00 2001 From: hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Fri, 13 Oct 2017 13:44:05 +0000 Subject: [PATCH 01/17] Backport r253729 gcc/lto/ChangeLog: 2017-10-13 Jan Hubicka <hubi...@ucw.cz> * lto-lang.c (lto_post_options): Clean shlib flag when not doing PIC. --- gcc/lto/lto-lang.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index ca8945e53bb..fdd6ae08a1c 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -840,11 +840,13 @@ lto_post_options (const char **pfilename ATTRIBUTE_UNUSED) flag_pie is 2. */ flag_pie = MAX (flag_pie, flag_pic); flag_pic = flag_pie; + flag_shlib = 0; break; case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */ flag_pic = 0; flag_pie = 0; + flag_shlib = 0; break; case LTO_LINKER_OUTPUT_UNKNOWN: -- 2.16.2