Subject: 'gcc-strmov-store-file-names.patch' causes GCC segfaults

From: [email-masked] (Ludovic Courtès)
Date: Mon, 04 Jun 2018 11:36:20 +0200

Hello,

On current ‘core-updates’, we have:

--8<---------------cut here---------------start------------->8---
$ readlink -f $(type -P gcc)
/gnu/store/zrhwhlqqk51qslbddk4cip2z2p3fpvxd-gcc-5.5.0/bin/gcc
ludo@ribbon /home/ludo/src/guix/+core-updates$ cat strmov-ice.c
#define _GNU_SOURCE
#include <string.h>

void foo (char *x)
{
  static const char buf[12];
  memcpy (x, buf, 12);
}
$ gcc -dH -O2 -Wall -c strmov-ice.c
strmov-ice.c: In function ‘foo’:
strmov-ice.c:7:3: internal compiler error: Segmentation fault
   memcpy (x, buf, 12);
   ^
gcc: internal compiler error: Aborted (program cc1)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
$ gdb /gnu/store/zrhwhlqqk51qslbddk4cip2z2p3fpvxd-gcc-5.5.0/libexec/gcc/x86_64-unknown-linux-gnu/5.5.0/cc1 core 
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /gnu/store/zrhwhlqqk51qslbddk4cip2z2p3fpvxd-gcc-5.5.0/libexec/gcc/x86_64-unknown-linux-gnu/5.5.0/cc1...(no debugging symbols found)...done.
[New LWP 1694]
Core was generated by `/gnu/store/zrhwhlqqk51qslbddk4cip2z2p3fpvxd-gcc-5.5.0/libexec/gcc/x86_64-unknow'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007fc415d8ba50 in raise () from /gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib/libc.so.6
(gdb) bt
#0  0x00007fc415d8ba50 in raise () from /gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib/libc.so.6
#1  0x00007fc415d8cc31 in abort () from /gnu/store/l4lr0f5cjd0nbsaaf8b5dmcw1a1yypr3-glibc-2.27/lib/libc.so.6
#2  0x0000000000f947ab in diagnostic_action_after_output(diagnostic_context*, diagnostic_t) ()
#3  0x0000000000f94a60 in diagnostic_report_diagnostic(diagnostic_context*, diagnostic_info*) ()
#4  0x0000000000f95a88 in internal_error(char const*, ...) ()
#5  0x00000000009e9b40 in crash_signal(int) ()
#6  <signal handler called>
#7  0x00000000006b3404 in store_reference_p(tree_node*) ()
#8  0x00000000007f4880 in gimple_fold_builtin_memory_op(gimple_stmt_iterator*, tree_node*, tree_node*, int) ()
#9  0x00000000007f643e in gimple_fold_builtin(gimple_stmt_iterator*) ()
#10 0x00000000007f8cf4 in fold_stmt_1(gimple_stmt_iterator*, bool, tree_node* (*)(tree_node*)) ()
#11 0x0000000000843c68 in gimplify_call_expr(tree_node**, gimple_statement_base**, bool) ()
#12 0x000000000083f5c8 in gimplify_expr(tree_node**, gimple_statement_base**, gimple_statement_base**, bool (*)(tree_node*), int) ()
#13 0x0000000000840ad7 in gimplify_stmt(tree_node**, gimple_statement_base**) ()
#14 0x000000000083effc in gimplify_expr(tree_node**, gimple_statement_base**, gimple_statement_base**, bool (*)(tree_node*), int) ()
#15 0x0000000000840ad7 in gimplify_stmt(tree_node**, gimple_statement_base**) ()
#16 0x00000000008412de in gimplify_bind_expr(tree_node**, gimple_statement_base**) ()
#17 0x000000000083f5aa in gimplify_expr(tree_node**, gimple_statement_base**, gimple_statement_base**, bool (*)(tree_node*), int) ()
#18 0x0000000000840ad7 in gimplify_stmt(tree_node**, gimple_statement_base**) ()
#19 0x0000000000841982 in gimplify_body(tree_node*, bool) ()
#20 0x0000000000841ca8 in gimplify_function_tree(tree_node*) ()
#21 0x00000000006fa268 in cgraph_node::analyze() ()
#22 0x00000000006fc870 in analyze_functions() ()
#23 0x00000000006fccb8 in symbol_table::finalize_compilation_unit() ()
#24 0x0000000000611183 in c_write_global_declarations() ()
#25 0x00000000009e9bd3 in compile_file() ()
#26 0x00000000005f0214 in toplev::main(int, char**) ()
#27 0x00000000005f0f7e in main ()
--8<---------------cut here---------------end--------------->8---

This is because DECL_INITIAL returns NULL_TREE for ‘buf’, but
‘store_reference_p’ doesn’t check whether we got NULL_TREE.

The fix is very simple (adding a NULL_TREE check), but in the meantime
we need to work around it.

A simple workaround is to pass an initializer to the static const array:

--8<---------------cut here---------------start------------->8---
$ cat strmov-ice.c
#define _GNU_SOURCE
#include <string.h>

void foo (char *x)
{
  static const char buf[12] = { 0, };
  memcpy (x, buf, 12);
}
$ gcc -dH -O2 -Wall -c strmov-ice.c
$ echo $?
0
--8<---------------cut here---------------end--------------->8---

The meaning of the program is unchanged but the bug is not triggered.

“Apologies for the inconvenience and thank you for your understanding”
as they say.

Ludo’.