Skip to content

Commit 0e33049

Browse files
committed
Use &raw to get address of globals
1 parent 4c52021 commit 0e33049

4 files changed

Lines changed: 190 additions & 0 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,6 +3551,12 @@ void Converter::ConvertAddrOf(clang::Expr *expr, clang::QualType pointer_type) {
35513551
if (IsReferenceType(expr) || pointer_type->isFunctionPointerType()) {
35523552
PushExprKind push(*this, ExprKind::AddrOf);
35533553
Convert(expr);
3554+
} else if (IsGlobalVar(expr)) {
3555+
StrCat("&raw", pointer_type->getPointeeType().isConstQualified()
3556+
? keyword::kConst
3557+
: keyword_mut_);
3558+
Convert(expr);
3559+
ConvertCast(pointer_type);
35543560
} else {
35553561
StrCat(token::kRef);
35563562
if (!pointer_type->getPointeeType().isConstQualified()) {

tests/unit/addr_of_global.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <cassert>
2+
3+
struct Inner {
4+
int value;
5+
};
6+
7+
struct Outer {
8+
Inner *p;
9+
};
10+
11+
Inner alpha = {1};
12+
Inner beta = {2};
13+
Inner shared = {42};
14+
15+
Inner *items[2] = {&alpha, &beta};
16+
Outer obj = {&shared};
17+
18+
int main() {
19+
assert(items[0]->value == 1);
20+
assert(items[1]->value == 2);
21+
assert(obj.p->value == 42);
22+
23+
static Inner *cache[2] = {&alpha, &beta};
24+
assert(cache[0]->value == 1);
25+
assert(cache[1]->value == 2);
26+
return 0;
27+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
extern crate libcc2rs;
2+
use libcc2rs::*;
3+
use std::cell::RefCell;
4+
use std::collections::BTreeMap;
5+
use std::io::prelude::*;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::AsFd;
8+
use std::rc::{Rc, Weak};
9+
#[derive(Default)]
10+
pub struct Inner {
11+
pub value: Value<i32>,
12+
}
13+
impl Clone for Inner {
14+
fn clone(&self) -> Self {
15+
let mut this = Self {
16+
value: Rc::new(RefCell::new((*self.value.borrow()))),
17+
};
18+
this
19+
}
20+
}
21+
impl ByteRepr for Inner {}
22+
#[derive(Default)]
23+
pub struct Outer {
24+
pub p: Value<Ptr<Inner>>,
25+
}
26+
impl Clone for Outer {
27+
fn clone(&self) -> Self {
28+
let mut this = Self {
29+
p: Rc::new(RefCell::new((*self.p.borrow()).clone())),
30+
};
31+
this
32+
}
33+
}
34+
impl ByteRepr for Outer {}
35+
thread_local!(
36+
pub static alpha: Value<Inner> = Rc::new(RefCell::new(Inner {
37+
value: Rc::new(RefCell::new(1)),
38+
}));
39+
);
40+
thread_local!(
41+
pub static beta: Value<Inner> = Rc::new(RefCell::new(Inner {
42+
value: Rc::new(RefCell::new(2)),
43+
}));
44+
);
45+
thread_local!(
46+
pub static shared: Value<Inner> = Rc::new(RefCell::new(Inner {
47+
value: Rc::new(RefCell::new(42)),
48+
}));
49+
);
50+
thread_local!(
51+
pub static items: Value<Box<[Ptr<Inner>]>> = Rc::new(RefCell::new(Box::new([
52+
(alpha.with(Value::clone).as_pointer()),
53+
(beta.with(Value::clone).as_pointer()),
54+
])));
55+
);
56+
thread_local!(
57+
pub static obj: Value<Outer> = Rc::new(RefCell::new(Outer {
58+
p: Rc::new(RefCell::new((shared.with(Value::clone).as_pointer()))),
59+
}));
60+
);
61+
pub fn main() {
62+
std::process::exit(main_0());
63+
}
64+
fn main_0() -> i32 {
65+
assert!(
66+
((*(*(*items.with(Value::clone).borrow())[(0) as usize]
67+
.upgrade()
68+
.deref())
69+
.value
70+
.borrow())
71+
== 1)
72+
);
73+
assert!(
74+
((*(*(*items.with(Value::clone).borrow())[(1) as usize]
75+
.upgrade()
76+
.deref())
77+
.value
78+
.borrow())
79+
== 2)
80+
);
81+
assert!(
82+
((*(*(*(*obj.with(Value::clone).borrow()).p.borrow())
83+
.upgrade()
84+
.deref())
85+
.value
86+
.borrow())
87+
== 42)
88+
);
89+
thread_local!(
90+
static cache: Value<Box<[Ptr<Inner>]>> = Rc::new(RefCell::new(Box::new([
91+
(alpha.with(Value::clone).as_pointer()),
92+
(beta.with(Value::clone).as_pointer()),
93+
])));
94+
);
95+
assert!(
96+
((*(*(*cache.with(Value::clone).borrow())[(0) as usize]
97+
.upgrade()
98+
.deref())
99+
.value
100+
.borrow())
101+
== 1)
102+
);
103+
assert!(
104+
((*(*(*cache.with(Value::clone).borrow())[(1) as usize]
105+
.upgrade()
106+
.deref())
107+
.value
108+
.borrow())
109+
== 2)
110+
);
111+
return 0;
112+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
extern crate libc;
2+
use libc::*;
3+
extern crate libcc2rs;
4+
use libcc2rs::*;
5+
use std::collections::BTreeMap;
6+
use std::io::{Read, Seek, Write};
7+
use std::os::fd::{AsFd, FromRawFd, IntoRawFd};
8+
use std::rc::Rc;
9+
#[repr(C)]
10+
#[derive(Copy, Clone, Default)]
11+
pub struct Inner {
12+
pub value: i32,
13+
}
14+
#[repr(C)]
15+
#[derive(Copy, Clone, Default)]
16+
pub struct Outer {
17+
pub p: *mut Inner,
18+
}
19+
pub static mut alpha: Inner = Inner { value: 1 };
20+
pub static mut beta: Inner = Inner { value: 2 };
21+
pub static mut shared: Inner = Inner { value: 42 };
22+
pub static mut items: [*mut Inner; 2] = [
23+
(&raw mut alpha as *mut Inner),
24+
(&raw mut beta as *mut Inner),
25+
];
26+
pub static mut obj: Outer = Outer {
27+
p: (&raw mut shared as *mut Inner),
28+
};
29+
pub fn main() {
30+
unsafe {
31+
std::process::exit(main_0() as i32);
32+
}
33+
}
34+
unsafe fn main_0() -> i32 {
35+
assert!((((*items[(0) as usize]).value) == (1)));
36+
assert!((((*items[(1) as usize]).value) == (2)));
37+
assert!((((*obj.p).value) == (42)));
38+
static mut cache: [*mut Inner; 2] = [
39+
(&raw mut alpha as *mut Inner),
40+
(&raw mut beta as *mut Inner),
41+
];;
42+
assert!((((*cache[(0) as usize]).value) == (1)));
43+
assert!((((*cache[(1) as usize]).value) == (2)));
44+
return 0;
45+
}

0 commit comments

Comments
 (0)