auto merge of #14121 : luqmana/rust/option-ffi, r=alexcrichton

This slightly adjusts the NullablePointer representation for some enums in the case where the non-nullable variant has a single field (the ptr field) to be just that, the pointer. This is in contrast to the current behaviour where we'd wrap that single pointer in a LLVM struct.

Fixes #11040 & #11303.
This commit is contained in:
bors 2014-05-18 01:16:27 -07:00
commit bf8648dbda
5 changed files with 158 additions and 59 deletions

View file

@ -16,10 +16,10 @@
// gdb-command:finish
// gdb-command:print some
// gdb-check:$1 = {0x12345678}
// gdb-check:$1 = (u32 *) 0x12345678
// gdb-command:print none
// gdb-check:$2 = {0x0}
// gdb-check:$2 = (u32 *) 0x0
// gdb-command:print full
// gdb-check:$3 = {454545, 0x87654321, 9988}
@ -41,6 +41,8 @@
// contains a non-nullable pointer, then this value is used as the discriminator.
// The test cases in this file make sure that something readable is generated for
// this kind of types.
// If the non-empty variant contains a single non-nullable pointer than the whole
// item is represented as just a pointer and not wrapped in a struct.
// Unfortunately (for these test cases) the content of the non-discriminant fields
// in the null-case is not defined. So we just read the discriminator field in
// this case (by casting the value to a memory-equivalent struct).

View file

@ -20,53 +20,53 @@
// gdb-command:print stack_unique.value
// gdb-check:$1 = 0
// gdb-command:print stack_unique.next.val->value
// gdb-command:print stack_unique.next->value
// gdb-check:$2 = 1
// gdb-command:print unique_unique->value
// gdb-check:$3 = 2
// gdb-command:print unique_unique->next.val->value
// gdb-command:print unique_unique->next->value
// gdb-check:$4 = 3
// gdb-command:print box_unique->val.value
// gdb-check:$5 = 4
// gdb-command:print box_unique->val.next.val->value
// gdb-command:print box_unique->val.next->value
// gdb-check:$6 = 5
// gdb-command:print vec_unique[0].value
// gdb-check:$7 = 6.5
// gdb-command:print vec_unique[0].next.val->value
// gdb-command:print vec_unique[0].next->value
// gdb-check:$8 = 7.5
// gdb-command:print borrowed_unique->value
// gdb-check:$9 = 8.5
// gdb-command:print borrowed_unique->next.val->value
// gdb-command:print borrowed_unique->next->value
// gdb-check:$10 = 9.5
// MANAGED
// gdb-command:print stack_managed.value
// gdb-check:$11 = 10
// gdb-command:print stack_managed.next.val->val.value
// gdb-command:print stack_managed.next.val->value
// gdb-check:$12 = 11
// gdb-command:print unique_managed->value
// gdb-check:$13 = 12
// gdb-command:print unique_managed->next.val->val.value
// gdb-command:print unique_managed->next.val->value
// gdb-check:$14 = 13
// gdb-command:print box_managed->val.value
// gdb-command:print box_managed.val->value
// gdb-check:$15 = 14
// gdb-command:print box_managed->val.next.val->val.value
// gdb-command:print box_managed->val->next.val->value
// gdb-check:$16 = 15
// gdb-command:print vec_managed[0].value
// gdb-check:$17 = 16.5
// gdb-command:print vec_managed[0].next.val->val.value
// gdb-command:print vec_managed[0].next.val->value
// gdb-check:$18 = 17.5
// gdb-command:print borrowed_managed->value
// gdb-check:$19 = 18.5
// gdb-command:print borrowed_managed->next.val->val.value
// gdb-command:print borrowed_managed->next.val->value
// gdb-check:$20 = 19.5
// LONG CYCLE
@ -97,7 +97,7 @@
// gdb-command:print (*****long_cycle_w_anonymous_types).value
// gdb-check:$31 = 30
// gdb-command:print (*****((*****long_cycle_w_anonymous_types).next.val)).value
// gdb-command:print (*****((*****long_cycle_w_anonymous_types).next)).value
// gdb-check:$32 = 31
// gdb-command:continue

View file

@ -0,0 +1,35 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// #11303, #11040:
// This would previously crash on i686 linux due to abi differences
// between returning an Option<T> and T, where T is a non nullable
// pointer.
// If we have an enum with two variants such that one is zero sized
// and the other contains a nonnullable pointer, we don't use a
// separate discriminant. Instead we use that pointer field to differentiate
// between the 2 cases.
// Also, if the variant with the nonnullable pointer has no other fields
// then we simply express the enum as just a pointer and not wrap it
// in a struct.
use std::mem;
#[inline(never)]
extern "C" fn foo<'a>(x: &'a int) -> Option<&'a int> { Some(x) }
static FOO: int = 0xDEADBEE;
pub fn main() {
unsafe {
let f: extern "C" fn<'a>(&'a int) -> &'a int = mem::transmute(foo);
assert_eq!(*f(&FOO), FOO);
}
}