]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/testsuite/gcc.target/x86_64/abi/test_struct_returning.c
test_struct_returning.c: Adjust as return slot is not merged if address escapes.
[gcc.git] / gcc / testsuite / gcc.target / x86_64 / abi / test_struct_returning.c
index 09fe710ca6cf8f02636b439a1ec2cb762dfa2338..ef8d32904837a4639a35c11a2df7291679ceec1d 100644 (file)
@@ -137,7 +137,7 @@ void check_400 (void)
 /* Structures which should be returned in MEM.  */
 void *struct_addr;
 #define D(I,MEMBERS) struct S_ ## I { MEMBERS ; }; Type class_ ## I = MEM; \
-struct S_ ## I f_ ## I (void) { struct S_ ## I s; memset (&s, 0, sizeof(s)); s.m1[0] = 42; return s; }
+struct S_ ## I f_ ## I (void) { union {unsigned char c; struct S_ ## I s;} u; memset (&u.s, 0, sizeof(u.s)); u.c = 42; return u.s; }
 
 /* Too large.  */
 D(500,char m1[17])
@@ -184,7 +184,16 @@ void check_all (Type class, unsigned long size)
     case X87: assert (x87_regs[0]._ldouble == 42); break;
     case INT_SSE: check_300(); break;
     case SSE_INT: check_400(); break;
-    case MEM: assert (rax == (unsigned long)struct_addr && rdi == rax); break;
+    /* Ideally we would like to check that rax == struct_addr.
+       Unfortunately the address of the target struct escapes (for setting
+       struct_addr), so the return struct is a temporary one whose address
+       is given to the f_* functions, otherwise a conforming program
+       could notice the struct changing already before the function returns.
+       This temporary struct could be anywhere.  For GCC it will be on
+       stack, but noone is forbidding that it could be a static variable
+       if there's no threading or proper locking.  Nobody in his right mind
+       will not use the stack for that.  */
+    case MEM: assert (*(unsigned char*)struct_addr == 42 && rdi == rax); break;
   }
 }
 
This page took 0.027705 seconds and 5 git commands to generate.