* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
@ 2008-04-25 14:56 ` rguenth at gcc dot gnu dot org
2008-04-25 15:00 ` rguenth at gcc dot gnu dot org
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 14:56 UTC (permalink / raw)
To: gcc-bugs
------- Comment #1 from rguenth at gcc dot gnu dot org 2008-04-25 14:55 -------
Hmm, didn't we fix this? ...
movw $115, (%rax)
movw $122, 2(%rax)
movw $98, 4(%rax)
movq (%rax), %rdi
call print_colour
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |rguenth at gcc dot gnu dot
| |org, matz at gcc dot gnu dot
| |org
Status|UNCONFIRMED |NEW
Ever Confirmed|0 |1
Keywords| |wrong-code
Last reconfirmed|0000-00-00 00:00:00 |2008-04-25 14:55:39
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
2008-04-25 14:56 ` [Bug target/36043] " rguenth at gcc dot gnu dot org
@ 2008-04-25 15:00 ` rguenth at gcc dot gnu dot org
2008-04-25 15:09 ` rguenth at gcc dot gnu dot org
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 15:00 UTC (permalink / raw)
To: gcc-bugs
------- Comment #2 from rguenth at gcc dot gnu dot org 2008-04-25 14:59 -------
Ahm, not exactly a dup of PR31309.
Shorter (non-runtime) testcase:
struct colour
{
unsigned short red;
unsigned short green;
unsigned short blue;
};
void print_colour(struct colour col);
void foo(struct colour *c)
{
print_colour(*c);
}
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
2008-04-25 14:56 ` [Bug target/36043] " rguenth at gcc dot gnu dot org
2008-04-25 15:00 ` rguenth at gcc dot gnu dot org
@ 2008-04-25 15:09 ` rguenth at gcc dot gnu dot org
2008-04-25 15:13 ` matz at gcc dot gnu dot org
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 15:09 UTC (permalink / raw)
To: gcc-bugs
------- Comment #3 from rguenth at gcc dot gnu dot org 2008-04-25 15:08 -------
The problem is that struct colour is laid out like
arg 0 <parm_decl 0x2b4f8506e2d0 c
type <pointer_type 0x2b4f85160780 type <record_type 0x2b4f85160540
colour>
unsigned DI
size <integer_cst 0x2b4f85068b70 constant invariant 64>
unit size <integer_cst 0x2b4f85068ba0 constant invariant 8>
align 64 symtab 0 alias set -1 canonical type 0x2b4f85160780>
used unsigned DI file t.c line 10 col 25 size <integer_cst
0x2b4f85068b70 64> unit size <integer_cst 0x2b4f85068ba0 8>
align 64 context <function_decl 0x2b4f8515fea0 foo> initial
<pointer_type 0x2b4f85160780>
(reg/v/f:DI 58 [ c ]) arg-type <pointer_type 0x2b4f85160780>
incoming-rtl (reg:DI 5 di [ c ])>>
which doesn't match its natural alignment nor size.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (2 preceding siblings ...)
2008-04-25 15:09 ` rguenth at gcc dot gnu dot org
@ 2008-04-25 15:13 ` matz at gcc dot gnu dot org
2008-04-25 15:18 ` rguenth at gcc dot gnu dot org
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: matz at gcc dot gnu dot org @ 2008-04-25 15:13 UTC (permalink / raw)
To: gcc-bugs
------- Comment #4 from matz at gcc dot gnu dot org 2008-04-25 15:12 -------
That's the layout of 'c', a pointer variable. We don't see the layout
of the record_type here.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (3 preceding siblings ...)
2008-04-25 15:13 ` matz at gcc dot gnu dot org
@ 2008-04-25 15:18 ` rguenth at gcc dot gnu dot org
2008-04-25 15:30 ` rguenth at gcc dot gnu dot org
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 15:18 UTC (permalink / raw)
To: gcc-bugs
------- Comment #5 from rguenth at gcc dot gnu dot org 2008-04-25 15:17 -------
Forget that. load_register_parameters converts
(mem/s:BLK (reg/v/f:DI 58 [ c ]) [0 S6 A16])
to
(mem/s:BLK (reg/v/f:DI 58 [ c ]) [0 S6 A16])
here:
else if (partial == 0 || args[i].pass_on_stack)
{
rtx mem = validize_mem (args[i].value);
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (4 preceding siblings ...)
2008-04-25 15:18 ` rguenth at gcc dot gnu dot org
@ 2008-04-25 15:30 ` rguenth at gcc dot gnu dot org
2008-04-25 15:43 ` rguenth at gcc dot gnu dot org
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 15:30 UTC (permalink / raw)
To: gcc-bugs
------- Comment #6 from rguenth at gcc dot gnu dot org 2008-04-25 15:29 -------
Errm. change_address_1 simply builds a DImode mem (with alignment
info properly retained)
#0 0x00000000005e80c2 in adjust_address_1 (memref=0x2b0751d81520,
mode=DImode, offset=0, validate=0, adjust=1)
at /space/rguenther/src/svn/gcc-4_3-branch/gcc/emit-rtl.c:1910
#1 0x00000000005e396c in operand_subword (op=0x2b0751d81520, offset=0,
validate_address=1, mode=BLKmode)
at /space/rguenther/src/svn/gcc-4_3-branch/gcc/emit-rtl.c:1346
#2 0x00000000005e3a28 in operand_subword_force (op=0x2b0751d81520, offset=0,
mode=BLKmode)
at /space/rguenther/src/svn/gcc-4_3-branch/gcc/emit-rtl.c:1374
#3 0x000000000060fd27 in move_block_to_reg (regno=5, x=0x2b0751d81520,
nregs=1, mode=BLKmode)
at /space/rguenther/src/svn/gcc-4_3-branch/gcc/expr.c:1560
#4 0x000000000054f7b9 in load_register_parameters (args=0x7fff59711810,
num_actuals=1, call_fusage=0x7fff597119d0, flags=0, is_sibcall=0,
sibcall_failure=0x7fff597119ac)
at /space/rguenther/src/svn/gcc-4_3-branch/gcc/calls.c:1681
#5 0x00000000005526b4 in expand_call (exp=0x2b075142d460, target=0x0,
ignore=1) at /space/rguenther/src/svn/gcc-4_3-branch/gcc/calls.c:2763
no idea if that is supposed to work (and thus *movdi_1_rex64 shouldn't match)
or if not ...
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (5 preceding siblings ...)
2008-04-25 15:30 ` rguenth at gcc dot gnu dot org
@ 2008-04-25 15:43 ` rguenth at gcc dot gnu dot org
2008-04-25 16:16 ` matz at gcc dot gnu dot org
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 15:43 UTC (permalink / raw)
To: gcc-bugs
------- Comment #7 from rguenth at gcc dot gnu dot org 2008-04-25 15:43 -------
So, the problem is in move_block_to_reg that copies the argument piecewise
to regs like
for (i = 0; i < nregs; i++)
emit_move_insn (gen_rtx_REG (word_mode, regno + i),
operand_subword_force (x, i, mode));
not accounting for the fact that the last reg may be only partially filled
from the memory. But the necessary information to deal with this is also
not available in this function currently.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (6 preceding siblings ...)
2008-04-25 15:43 ` rguenth at gcc dot gnu dot org
@ 2008-04-25 16:16 ` matz at gcc dot gnu dot org
2008-04-25 16:21 ` rguenth at gcc dot gnu dot org
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: matz at gcc dot gnu dot org @ 2008-04-25 16:16 UTC (permalink / raw)
To: gcc-bugs
------- Comment #8 from matz at gcc dot gnu dot org 2008-04-25 16:15 -------
FWIW, I think the error is in the caller of move_block_to_reg.
move_block_to_reg can make use of a load_multiple instruction, which really
loads full regs. I.e. it would be unreasonable to require changes in
move_block_to_reg to handle non-power-of-2 sizes. Hence the caller
(load_register_parameters) needs to handle this. I'm not sure if the
n_aligned_regs thingy could be misused for this, or if one simply should
opencode the special case of the last register being partial.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (7 preceding siblings ...)
2008-04-25 16:16 ` matz at gcc dot gnu dot org
@ 2008-04-25 16:21 ` rguenth at gcc dot gnu dot org
2009-03-17 22:48 ` eric dot rannaud at gmail dot com
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2008-04-25 16:21 UTC (permalink / raw)
To: gcc-bugs
------- Comment #9 from rguenth at gcc dot gnu dot org 2008-04-25 16:20 -------
Index: calls.c
===================================================================
--- calls.c (revision 134659)
+++ calls.c (working copy)
@@ -2708,7 +2708,7 @@ expand_call (tree exp, rtx target, int i
and whose alignment does not permit a direct copy into registers,
make a group of pseudos that correspond to each register that we
will later fill. */
- if (STRICT_ALIGNMENT)
+ if (1 || STRICT_ALIGNMENT)
store_unaligned_arguments_into_pseudos (args, num_actuals);
/* Now store any partially-in-registers parm.
also fixes this.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (8 preceding siblings ...)
2008-04-25 16:21 ` rguenth at gcc dot gnu dot org
@ 2009-03-17 22:48 ` eric dot rannaud at gmail dot com
2009-03-18 9:12 ` rguenth at gcc dot gnu dot org
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: eric dot rannaud at gmail dot com @ 2009-03-17 22:48 UTC (permalink / raw)
To: gcc-bugs
------- Comment #10 from eric dot rannaud at gmail dot com 2009-03-17 22:48 -------
Witnessed in g++ 4.3.2
g++ (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)
--
eric dot rannaud at gmail dot com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |eric dot rannaud at gmail
| |dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (9 preceding siblings ...)
2009-03-17 22:48 ` eric dot rannaud at gmail dot com
@ 2009-03-18 9:12 ` rguenth at gcc dot gnu dot org
2009-09-15 21:25 ` lordhoto at gmail dot com
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2009-03-18 9:12 UTC (permalink / raw)
To: gcc-bugs
------- Comment #11 from rguenth at gcc dot gnu dot org 2009-03-18 09:11 -------
Still broken on the trunk as well.
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Known to fail| |4.1.2 4.3.3 4.4.0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (10 preceding siblings ...)
2009-03-18 9:12 ` rguenth at gcc dot gnu dot org
@ 2009-09-15 21:25 ` lordhoto at gmail dot com
2009-09-15 21:54 ` a dot heider at gmail dot com
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: lordhoto at gmail dot com @ 2009-09-15 21:25 UTC (permalink / raw)
To: gcc-bugs
------- Comment #12 from lordhoto at gmail dot com 2009-09-15 21:24 -------
Happens for me too on Linux/AMD64 with:
gcc (Debian 4.3.4-2) 4.3.4
and
gcc (Debian 4.4.1-4) 4.4.1
It also happens with structs of sizes 3, 5 and 7 for me.
An easy (non-runtime) test case for different struct sizes can be made via:
struct test
{
unsigned char size[TEST_SIZE];
};
void bar(struct test);
void foo(struct test *t)
{
bar(*t);
}
Just define the struct size via "-DTEST_SIZE=size", where "size" is the desired
size of the struct, on the gcc command line.
One can witness that for struct sizes of 1, 2, 4, 8 and everything above 8 it
works just fine.
Here's the assembly output, generated via 4.3.4, for the working struct sizes:
struct size of 1:
movq -8(%rbp), %rax
movzbl (%rax), %edi
call bar
struct size of 2:
movq -8(%rbp), %rax
movzwl (%rax), %edi
call bar
struct size of 4:
movq -8(%rbp), %rax
movl (%rax), %edi
call bar
struct size of 8:
movq -8(%rbp), %rax
movq (%rax), %edi
call bar
For all sizes above 8, it does also generate correct assembly, that means it
will only read the correct number of bytes. Here is an example with a struct
size of 11:
movq -8(%rbp), %rdx
movq (%rdx), %rdi
movzbl 8(%rdx), %ecx
movzbl 9(%rdx), %eax
salq $8, %rax
orq %rax, %rcx
movzbl 10(%rdx), %eax
salq $16, %rax
movq %rax, %rsi
orq %rcx, %rsi
call bar
As you can see it uses one "movq" to read eight bytes at once and then three
"movzbl" to read the remaining three bytes. The assembly for this case was
generated with -O0. It will look differently for other optimization levels, but
is still using the same basic logic.
For struct sizes of 3, 5, 6 or 7 the compiler always generates:
movq -8(%rbp), %rax
movq (%rax), %rdi
call bar
for me, which is the reported incorrect behavior.
--
lordhoto at gmail dot com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |lordhoto at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (11 preceding siblings ...)
2009-09-15 21:25 ` lordhoto at gmail dot com
@ 2009-09-15 21:54 ` a dot heider at gmail dot com
2010-01-03 20:30 ` matt at use dot net
2010-01-03 22:32 ` rguenth at gcc dot gnu dot org
14 siblings, 0 replies; 16+ messages in thread
From: a dot heider at gmail dot com @ 2009-09-15 21:54 UTC (permalink / raw)
To: gcc-bugs
------- Comment #13 from a dot heider at gmail dot com 2009-09-15 21:54 -------
Still present on a recent GCC snapshot:
Johannes' Code compiled with "(Ubuntu 20090912-1ubuntu2) 4.5.0 20090912
(experimental) [trunk revision 151650]" and -O0 -DTEST_SIZE=5:
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq (%rax), %rdi
call bar
--
a dot heider at gmail dot com changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |a dot heider at gmail dot
| |com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (12 preceding siblings ...)
2009-09-15 21:54 ` a dot heider at gmail dot com
@ 2010-01-03 20:30 ` matt at use dot net
2010-01-03 22:32 ` rguenth at gcc dot gnu dot org
14 siblings, 0 replies; 16+ messages in thread
From: matt at use dot net @ 2010-01-03 20:30 UTC (permalink / raw)
To: gcc-bugs
------- Comment #14 from matt at use dot net 2010-01-03 20:30 -------
Still happening on 4.5.0 20091228 (and gcc 4.4.1) on Ubuntu 9.10/amd64). I
found that it goes away in 3 separate instances when turning on
-finline-functions. The last 2 instances of memory corruption I am running into
are functions in vtables, which can't be inlined (and therefore work around
this bug) until de-virtualization is eliminated.
This seems like a pretty serious and common problem; is there any chance it
will be fixed in 4.5?
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Bug target/36043] gcc reads 8 bytes for a struct of size 6 which leads to sigsegv
2008-04-25 9:29 [Bug c/36043] New: gcc reads 8 bytes for a struct of size 6 which leads to sigsegv bartoschek at gmx dot de
` (13 preceding siblings ...)
2010-01-03 20:30 ` matt at use dot net
@ 2010-01-03 22:32 ` rguenth at gcc dot gnu dot org
14 siblings, 0 replies; 16+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2010-01-03 22:32 UTC (permalink / raw)
To: gcc-bugs
------- Comment #15 from rguenth at gcc dot gnu dot org 2010-01-03 22:32 -------
The issue is in a very twisted piece of GCC where the chances to break sth are
bigger that to fix sth ;)
And it isn't a regression, so it's not on too many peoples radar (nor does
it seem to happen in practice and thus affect those who may be able to fix it).
But, let's CC some more people ;)
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |rth at gcc dot gnu dot org
Known to fail|4.1.2 4.3.3 4.4.0 |4.1.2 4.3.3 4.4.0 4.5.0
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043
^ permalink raw reply [flat|nested] 16+ messages in thread