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