https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70440
Bug ID: 70440 Summary: SEGV initializing a VLA with a smaller string Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- The following program crashes with a SEGV when compiled without optimization with the current trunk as well as 5.1.0 and 4.9.3. The program is rejected by 4.5.3 with error: variable-sized object ‘a’ may not be initialized so the bug could be viewed as a regression. The assembly and the tree dump show that the problem is caused by GCC emitting a call to memcpy() to initialize the large VLA from the empty string. $ cat v.c && /build/gcc-trunk-bootstrap/gcc/xgcc -B /build/gcc-trunk-bootstrap/gcc -DN=2413 -Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout -g -xc++ v.c && gdb -batch -q -ex r -ex bt -ex up -ex 'disas g' -ex 'p/x &a' -ex 'p/x $rsi' -ex 'p/x $rdi' -ex 'p $rdx' ./a.out void __attribute__ ((noclone, noinline)) f (void *p) { } void __attribute__ ((noclone, noinline)) g (int n) { char a [n] = ""; f (a); } int main () { g (N); } v.c: In function ‘void f(void*)’: v.c:1:51: warning: unused parameter ‘p’ [-Wunused-parameter] void __attribute__ ((noclone, noinline)) f (void *p) { } ^ v.c: In function ‘void g(int)’: v.c:5:14: warning: ISO C++ forbids variable length array ‘a’ [-Wvla] char a [n] = ""; ^ ;; Function void f(void*) (_Z1fPv, funcdef_no=0, decl_uid=2253, cgraph_uid=0, symbol_order=0) __attribute__((noinline, noclone)) void f(void*) (void * p) { <bb 2>: GIMPLE_NOP return; } ;; Function void g(int) (_Z1gi, funcdef_no=1, decl_uid=2256, cgraph_uid=1, symbol_order=1) __attribute__((noinline, noclone)) void g(int) (int n) { char a[0:D.2264] [value-expr: *a.0]; void * saved_stack.2; char[0:D.2264] * a.1; char[0:D.2264] * a.0; sizetype D.2276; sizetype D.2275; bitsizetype D.2274; bitsizetype D.2273; sizetype D.2272; sizetype D.2271; sizetype D.2270; sizetype D.2269; bitsizetype D.2268; bitsizetype D.2267; sizetype D.2266; sizetype D.2265; sizetype D.2264; ssizetype D.2263; ssizetype D.2262; void * saved_stack.2_3; ssizetype _5; ssizetype _6; sizetype _8; sizetype _9; bitsizetype _10; bitsizetype _11; sizetype _12; sizetype _13; sizetype _14; sizetype _15; bitsizetype _16; bitsizetype _17; sizetype _18; sizetype _19; char[0:D.2264] * a.1_23; <bb 2>: saved_stack.2_3 = __builtin_stack_save (); _5 = (ssizetype) n_4(D); _6 = _5 + -1; _7 = (sizetype) _6; _8 = (sizetype) _6; _9 = _8 + 1; _10 = (bitsizetype) _9; _11 = _10 * 8; _12 = (sizetype) _6; _13 = _12 + 1; _14 = (sizetype) _6; _15 = _14 + 1; _16 = (bitsizetype) _15; _17 = _16 * 8; _18 = (sizetype) _6; _19 = _18 + 1; a.0_21 = __builtin_alloca_with_align (_19, 8); __builtin_memcpy (a.0_21, "", _13); a.1_23 = a.0_21; f (a.1_23); __builtin_stack_restore (saved_stack.2_3); return; } ;; Function int main() (main, funcdef_no=2, decl_uid=2259, cgraph_uid=2, symbol_order=2) int main() () { int D.2280; int _3; <bb 2>: g (2413); _3 = 0; <L0>: return _3; } Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7b63bd6 in __memcpy_avx_unaligned () from /lib64/libc.so.6 #0 0x00007ffff7b63bd6 in __memcpy_avx_unaligned () from /lib64/libc.so.6 #1 0x00000000004005da in g (n=2413) at v.c:5 #2 0x00000000004005fe in main () at v.c:11 #1 0x00000000004005da in g (n=2413) at v.c:5 5 char a [n] = ""; Dump of assembler code for function g(int): 0x0000000000400551 <+0>: push %rbp 0x0000000000400552 <+1>: mov %rsp,%rbp 0x0000000000400555 <+4>: push %rbx 0x0000000000400556 <+5>: sub $0x28,%rsp 0x000000000040055a <+9>: mov %edi,-0x24(%rbp) 0x000000000040055d <+12>: mov %rsp,%rax 0x0000000000400560 <+15>: mov %rax,%rbx 0x0000000000400563 <+18>: mov -0x24(%rbp),%eax 0x0000000000400566 <+21>: cltq 0x0000000000400568 <+23>: sub $0x1,%rax 0x000000000040056c <+27>: mov %rax,-0x18(%rbp) 0x0000000000400570 <+31>: mov %rax,%rdx 0x0000000000400573 <+34>: add $0x1,%rdx 0x0000000000400577 <+38>: mov %rdx,%r10 0x000000000040057a <+41>: mov $0x0,%r11d 0x0000000000400580 <+47>: mov %rax,%rdx 0x0000000000400583 <+50>: lea 0x1(%rdx),%rcx 0x0000000000400587 <+54>: mov %rax,%rdx 0x000000000040058a <+57>: add $0x1,%rdx 0x000000000040058e <+61>: mov %rdx,%r8 0x0000000000400591 <+64>: mov $0x0,%r9d 0x0000000000400597 <+70>: lea 0x1(%rax),%rdx 0x000000000040059b <+74>: mov $0x10,%eax 0x00000000004005a0 <+79>: sub $0x1,%rax 0x00000000004005a4 <+83>: add %rdx,%rax 0x00000000004005a7 <+86>: mov $0x10,%esi 0x00000000004005ac <+91>: mov $0x0,%edx 0x00000000004005b1 <+96>: div %rsi 0x00000000004005b4 <+99>: imul $0x10,%rax,%rax 0x00000000004005b8 <+103>: sub %rax,%rsp 0x00000000004005bb <+106>: mov %rsp,%rax 0x00000000004005be <+109>: add $0x0,%rax 0x00000000004005c2 <+113>: mov %rax,-0x20(%rbp) 0x00000000004005c6 <+117>: mov -0x20(%rbp),%rax 0x00000000004005ca <+121>: mov $0x400694,%esi 0x00000000004005cf <+126>: mov %rcx,%rdx 0x00000000004005d2 <+129>: mov %rax,%rdi 0x00000000004005d5 <+132>: callq 0x400440 <memcpy@plt> => 0x00000000004005da <+137>: mov -0x20(%rbp),%rax 0x00000000004005de <+141>: mov %rax,%rdi 0x00000000004005e1 <+144>: callq 0x400546 <f(void*)> 0x00000000004005e6 <+149>: mov %rbx,%rsp 0x00000000004005e9 <+152>: nop 0x00000000004005ea <+153>: mov -0x8(%rbp),%rbx 0x00000000004005ee <+157>: leaveq 0x00000000004005ef <+158>: retq End of assembler dump. $1 = 0x7fffffffd7e0 $2 = 0x401000 $3 = 0x7fffffffe14c $4 = 2413