| Daniel Sanders | 998c910 | 2015-01-14 12:00:12 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple mips64-linux-gnu -S -o - -emit-llvm %s | FileCheck %s | 
|  | 2 | // | 
|  | 3 | // Transparent unions are passed according to the calling convention rules of | 
|  | 4 | // the first member. In this case, it is as if it were a void pointer so we | 
|  | 5 | // do not have the inreg attribute we would normally have for unions. | 
|  | 6 | // | 
|  | 7 | // This comes up in glibc's wait() function and matters for the big-endian N32 | 
|  | 8 | // case where pointers are promoted to i64 and a non-transparent union would be | 
|  | 9 | // passed in the upper 32-bits of an i64. | 
|  | 10 |  | 
|  | 11 | union either_pointer { | 
|  | 12 | void *void_ptr; | 
|  | 13 | int *int_ptr; | 
|  | 14 | } __attribute__((transparent_union)); | 
|  | 15 |  | 
|  | 16 | extern void foo(union either_pointer p); | 
|  | 17 |  | 
|  | 18 | int data; | 
|  | 19 |  | 
|  | 20 | void bar(void) { | 
|  | 21 | return foo(&data); | 
|  | 22 | } | 
|  | 23 |  | 
|  | 24 | // CHECK-LABEL: define void @bar() | 
|  | 25 | // CHECK:         call void @foo(i8* %{{[0-9]+}}) | 
|  | 26 |  | 
|  | 27 | // CHECK: declare void @foo(i8*) |