New: Missing register load before inline asm in templated function causes SIGSEGV
9 answers - 712 bytes -

I have a templated function which uses inline assembler (with MMX
instructions). Inline assembler is passed pointer to array element.
When this function is instantiated for the first time, code before inline
assembler is generated correctly. When it is instantiated for the second time,
one of registers used in inline assembler is not loaded from stack and causes
segfault when it is dereferenced in inline assembler.
I will attach test case.
g4.0 -v:
Using built-in specs.
Target: i486-linux-gnu
Configured with: /src/configure -v
,c++,java,f95,objc,ada,treelang /usr
/usr/lib
/
i486-linux-gnu
Thread model: posix
gcc version 4.0.2 (Debian 4.0.2-2)
No.1 | | 451 bytes |
| 
Comment #1 from krzysiek-gcc dot gnu dot org at lichota dot net 2005-11-09 19:46
Created an attachment (id=10193)
()
Testcase for the bug
This is the testcase. Compile with:
g4.0 -save-temps -fPIC -ggdb3 -Wno-non-virtual-dtor -pthread
-fkeep-inline-functions testcase10.cpp
When both calls to bar() are instantiated, the segfault occurs.
When only one is instantiated (the other is commented out), it works correctly.
No.2 | | 1042 bytes |
| 
Comment #2 from krzysiek-gcc dot gnu dot org at lichota dot net 2005-11-09 19:49
Created an attachment (id=10195)
()
Assembler code generated from testcase
This is code generated from testcase.
In first instantiation eax register is loaded before inline asm starts:
.loc 1 25 0
movl -16(%ebp), %eax
addl -20(%ebp), %eax
sall $2, %eax
addl 8(%ebp), %eax
movl %eax, -8(%ebp)
.loc 1 41 0
movl -16(%ebp), %eax
addl -24(%ebp), %eax
sall $2, %eax
movl %eax, %edx
addl -12(%ebp), %edx
movl -8(%ebp), %eax
#APP
movq (%edx), %mm0 ;
In the second instantiation, eax is not loaded:
.loc 1 25 0
movl -16(%ebp), %eax
addl -20(%ebp), %eax
sall $2, %eax
addl 8(%ebp), %eax
movl %eax, -8(%ebp)
.loc 1 41 0
movl -16(%ebp), %eax
addl -24(%ebp), %eax
sall $2, %eax
movl %eax, %edx
addl -12(%ebp), %edx
#APP
movq (%edx), %mm0 ;
Then in line:
pxor (%eax), %mm0 ;
eax is dereferenced and segfault occurs.
No.3 | | 284 bytes |
| 
Comment #3 from krzysiek-gcc dot gnu dot org at lichota dot net 2005-11-09 20:00
Created an attachment (id=10196)
()
Correct code generated by g++ 3.4.2
This is the correct code generated by g++ 3.4.2. It loads eax before inline asm
starts in both instantiations.
No.4 | | 247 bytes |
| 
Comment #4 from pinskia at gcc dot gnu dot org 2005-11-09 20:24
Simplified example:
template <int>
int f(int i)
{
asm("%0 %1 " : "+r"(i) );
return i;
}
int main(void)
{
f<0>(0)+ f<1>(0);
}
No.5 | | 289 bytes |
| 
Comment #5 from pinskia at gcc dot gnu dot org 2005-11-09 20:28
For the first time template is instantiated, we get:
__asm__("%0 %1 ":"=r" i:"0" i);
The second time, we get:
__asm__("%0 %1 ":"=r" i:);
Somehow we brought back a bug from 2.95.3 (weird isn't it).
No.6 | | 284 bytes |
| 
--
jakub at gcc dot gnu dot org changed:
What |Removed |Added
AssignedTo|unassigned at gcc dot gnu |jakub at gcc dot gnu dot org
|dot org |
Status|NEW |ASSIGNED
Last reconfirmed|2005-11-09 20:24:19 |2005-11-10 09:03:35
date| |
No.7 | | 457 bytes |
| 
Comment #6 from jakub at gcc dot gnu dot org 2005-11-12 20:42
Subject: Bug 24761
Author: jakub
Date: Sat Nov 12 20:42:23 2005
New Revision: 106831
URL:
Log:
PR c++/24761
* pt.c (tsubst_copy_asm_operands): New function.
(tsubst_expr) <case ASM_EXPR>: Use it.
* gdg/template/asm1.C: New test.
Added:
Modified:
trunk/gcc/cp/ChangeLog
trunk/gcc/cp/pt.c
trunk/gcc/testsuite/ChangeLog
No.8 | | 374 bytes |
| 
Comment #7 from jakub at gcc dot gnu dot org 2005-11-12 20:43
Subject: Bug 24761
Author: jakub
Date: Sat Nov 12 20:43:27 2005
New Revision: 106832
URL:
Log:
PR c++/24761
* pt.c (tsubst_copy_asm_operands): New function.
(tsubst_expr) <case ASM_EXPR>: Use it.
* gdg/template/asm1.C: New test.
Added:
Modified:
No.9 | | 74 bytes |
| 
Comment #8 from pinskia at gcc dot gnu dot org 2005-11-12 22:13
Fixed.