Skip to content

Commit e77de9d

Browse files
committed
Add test for global initialization with non-const expression
1 parent bd5f41a commit e77de9d

3 files changed

Lines changed: 412 additions & 0 deletions

File tree

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#include <cassert>
2+
#include <cstdint>
3+
#include <string>
4+
5+
int next() {
6+
static int counter = 0;
7+
return ++counter;
8+
}
9+
10+
// constexpr function call
11+
constexpr uint8_t marker(uint8_t tag) { return (tag << 3) | 2; }
12+
const uint8_t signature[3] = {marker(1), 0x04, 'B'};
13+
static uint8_t single = marker(2);
14+
15+
// non-constexpr function call
16+
static int from_call = next();
17+
static int depends_on_call = from_call + 1;
18+
19+
// constructors
20+
struct Ctor {
21+
int v;
22+
Ctor() : v(next()) {}
23+
explicit Ctor(int x) : v(x) {}
24+
};
25+
static Ctor default_ctor;
26+
static Ctor arg_ctor(7);
27+
28+
// std::string
29+
std::string str = "abc";
30+
31+
// static data members
32+
struct Holder {
33+
static int member;
34+
static inline Ctor inline_member{5};
35+
};
36+
int Holder::member = next();
37+
38+
// static locals
39+
int local_static() {
40+
static int once = next();
41+
static Ctor local_ctor(3);
42+
return once + local_ctor.v;
43+
}
44+
45+
// singleton via function local static
46+
struct Singleton {
47+
int hits;
48+
Singleton() : hits(0) {}
49+
static Singleton &instance() {
50+
static Singleton s;
51+
return s;
52+
}
53+
};
54+
55+
int main() {
56+
assert(signature[0] == 10);
57+
assert(signature[1] == 0x04);
58+
assert(single == 18);
59+
60+
assert(from_call == 1);
61+
assert(depends_on_call == 2);
62+
63+
assert(default_ctor.v == 2);
64+
assert(arg_ctor.v == 7);
65+
66+
assert(str == "abc");
67+
68+
assert(Holder::member == 3);
69+
assert(Holder::inline_member.v == 5);
70+
71+
assert(local_static() == 7);
72+
assert(local_static() == 7);
73+
74+
Singleton::instance().hits++;
75+
Singleton::instance().hits++;
76+
assert(Singleton::instance().hits == 2);
77+
assert(&Singleton::instance() == &Singleton::instance());
78+
return 0;
79+
}
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
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+
pub fn next_0() -> i32 {
10+
thread_local!(
11+
static counter_1: Value<i32> = Rc::new(RefCell::new(0));
12+
);
13+
return (*counter_1.with(Value::clone).borrow_mut()).prefix_inc();
14+
}
15+
pub fn marker_2(tag: u8) -> u8 {
16+
let tag: Value<u8> = Rc::new(RefCell::new(tag));
17+
return (((((*tag.borrow()) as i32) << 3) | 2) as u8);
18+
}
19+
thread_local!(
20+
pub static signature_3: Value<Box<[u8]>> = Rc::new(RefCell::new(Box::new([
21+
({ marker_2(1_u8) }),
22+
4_u8,
23+
('B' as u8),
24+
])));
25+
);
26+
thread_local!(
27+
pub static single_4: Value<u8> = Rc::new(RefCell::new(({ marker_2(2_u8) })));
28+
);
29+
thread_local!(
30+
pub static from_call_5: Value<i32> = Rc::new(RefCell::new(({ next_0() })));
31+
);
32+
thread_local!(
33+
pub static depends_on_call_6: Value<i32> = Rc::new(RefCell::new(
34+
((*from_call_5.with(Value::clone).borrow()) + 1),
35+
));
36+
);
37+
#[derive()]
38+
pub struct Ctor {
39+
pub v: Value<i32>,
40+
}
41+
impl Ctor {
42+
pub fn Ctor1() -> Self {
43+
let __this: Value<Ctor> = Rc::new(RefCell::new(Self {
44+
v: Rc::new(RefCell::new(({ next_0() }))),
45+
}));
46+
let this: Ptr<Ctor> = __this.as_pointer();
47+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
48+
}
49+
pub fn Ctor2(x: i32) -> Self {
50+
let x: Value<i32> = Rc::new(RefCell::new(x));
51+
let __this: Value<Ctor> = Rc::new(RefCell::new(Self {
52+
v: Rc::new(RefCell::new((*x.borrow()))),
53+
}));
54+
let this: Ptr<Ctor> = __this.as_pointer();
55+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
56+
}
57+
}
58+
impl Clone for Ctor {
59+
fn clone(&self) -> Self {
60+
let __this: Value<Ctor> = Rc::new(RefCell::new(Self {
61+
v: Rc::new(RefCell::new((*self.v.borrow()))),
62+
}));
63+
let this: Ptr<Ctor> = __this.as_pointer();
64+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
65+
}
66+
}
67+
impl Default for Ctor {
68+
fn default() -> Self {
69+
{ Ctor::Ctor1() }
70+
}
71+
}
72+
impl ByteRepr for Ctor {
73+
fn byte_size() -> usize {
74+
4
75+
}
76+
fn to_bytes(&self, buf: &mut [u8]) {
77+
(*self.v.borrow()).to_bytes(&mut buf[0..4]);
78+
}
79+
fn from_bytes(buf: &[u8]) -> Self {
80+
Self {
81+
v: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
82+
}
83+
}
84+
}
85+
thread_local!(
86+
pub static default_ctor_7: Value<Ctor> = Rc::new(RefCell::new(Ctor::Ctor1()));
87+
);
88+
thread_local!(
89+
pub static arg_ctor_8: Value<Ctor> = Rc::new(RefCell::new(Ctor::Ctor2({ 7 })));
90+
);
91+
thread_local!(
92+
pub static str_9: Value<Vec<u8>> = Rc::new(RefCell::new(
93+
Ptr::from_string_literal(b"abc")
94+
.to_c_string_iterator()
95+
.chain(std::iter::once(0))
96+
.collect::<Vec<u8>>(),
97+
));
98+
);
99+
thread_local!();
100+
thread_local!(
101+
pub static inline_member_11: Value<Ctor> = Rc::new(RefCell::new(Ctor::Ctor2({ 5 })));
102+
);
103+
#[derive(Default)]
104+
pub struct Holder {}
105+
impl Clone for Holder {
106+
fn clone(&self) -> Self {
107+
let __this: Value<Holder> = Rc::new(RefCell::new(Self {}));
108+
let this: Ptr<Holder> = __this.as_pointer();
109+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
110+
}
111+
}
112+
impl ByteRepr for Holder {
113+
fn byte_size() -> usize {
114+
1
115+
}
116+
fn to_bytes(&self, buf: &mut [u8]) {}
117+
fn from_bytes(buf: &[u8]) -> Self {
118+
Self {}
119+
}
120+
}
121+
thread_local!(
122+
pub static member_10: Value<i32> = Rc::new(RefCell::new(({ next_0() })));
123+
);
124+
pub fn local_static_12() -> i32 {
125+
thread_local!(
126+
static once_13: Value<i32> = Rc::new(RefCell::new(({ next_0() })));
127+
);
128+
thread_local!(
129+
static local_ctor_14: Value<Ctor> = Rc::new(RefCell::new(Ctor::Ctor2({ 3 })));
130+
);
131+
return ((*once_13.with(Value::clone).borrow())
132+
+ (*(*local_ctor_14.with(Value::clone).borrow()).v.borrow()));
133+
}
134+
#[derive()]
135+
pub struct Singleton {
136+
pub hits: Value<i32>,
137+
}
138+
impl Singleton {
139+
pub fn Singleton() -> Self {
140+
let __this: Value<Singleton> = Rc::new(RefCell::new(Self {
141+
hits: Rc::new(RefCell::new(0)),
142+
}));
143+
let this: Ptr<Singleton> = __this.as_pointer();
144+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
145+
}
146+
pub fn instance() -> Ptr<Singleton> {
147+
thread_local!(
148+
static s_15: Value<Singleton> = Rc::new(RefCell::new(Singleton::Singleton()));
149+
);
150+
return s_15.with(Value::clone).as_pointer();
151+
}
152+
}
153+
impl Clone for Singleton {
154+
fn clone(&self) -> Self {
155+
let __this: Value<Singleton> = Rc::new(RefCell::new(Self {
156+
hits: Rc::new(RefCell::new((*self.hits.borrow()))),
157+
}));
158+
let this: Ptr<Singleton> = __this.as_pointer();
159+
Rc::try_unwrap(__this).ok().unwrap().into_inner()
160+
}
161+
}
162+
impl Default for Singleton {
163+
fn default() -> Self {
164+
{ Singleton::Singleton() }
165+
}
166+
}
167+
impl ByteRepr for Singleton {
168+
fn byte_size() -> usize {
169+
4
170+
}
171+
fn to_bytes(&self, buf: &mut [u8]) {
172+
(*self.hits.borrow()).to_bytes(&mut buf[0..4]);
173+
}
174+
fn from_bytes(buf: &[u8]) -> Self {
175+
Self {
176+
hits: Rc::new(RefCell::new(<i32>::from_bytes(&buf[0..4]))),
177+
}
178+
}
179+
}
180+
pub fn main() {
181+
std::process::exit(main_0());
182+
}
183+
fn main_0() -> i32 {
184+
assert!((((*signature_3.with(Value::clone).borrow())[(0) as usize] as i32) == 10));
185+
assert!((((*signature_3.with(Value::clone).borrow())[(1) as usize] as i32) == 4));
186+
assert!((((*single_4.with(Value::clone).borrow()) as i32) == 18));
187+
assert!(((*from_call_5.with(Value::clone).borrow()) == 1));
188+
assert!(((*depends_on_call_6.with(Value::clone).borrow()) == 2));
189+
assert!(((*(*default_ctor_7.with(Value::clone).borrow()).v.borrow()) == 2));
190+
assert!(((*(*arg_ctor_8.with(Value::clone).borrow()).v.borrow()) == 7));
191+
assert!(
192+
(*str_9.with(Value::clone).borrow())
193+
.iter()
194+
.copied()
195+
.take((*str_9.with(Value::clone).borrow()).len().saturating_sub(1))
196+
.eq(Ptr::from_string_literal(b"abc").to_c_string_iterator())
197+
);
198+
assert!(((*member_10.with(Value::clone).borrow()) == 3));
199+
assert!(((*(*inline_member_11.with(Value::clone).borrow()).v.borrow()) == 5));
200+
assert!((({ local_static_12() }) == 7));
201+
assert!((({ local_static_12() }) == 7));
202+
(*(*({ Singleton::instance() }).upgrade().deref())
203+
.hits
204+
.borrow_mut())
205+
.postfix_inc();
206+
(*(*({ Singleton::instance() }).upgrade().deref())
207+
.hits
208+
.borrow_mut())
209+
.postfix_inc();
210+
assert!(
211+
((*(*({ Singleton::instance() }).upgrade().deref())
212+
.hits
213+
.borrow())
214+
== 2)
215+
);
216+
assert!((({ Singleton::instance() }) == ({ Singleton::instance() })));
217+
return 0;
218+
}

0 commit comments

Comments
 (0)