Skip to content

Commit 442e534

Browse files
committed
Initialize global variables before starting main
1 parent e5731d9 commit 442e534

927 files changed

Lines changed: 2103 additions & 6 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎cpp2rust/converter/converter.cpp‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace cpp2rust {
2626
std::unordered_map<std::string, std::string> Converter::inner_structs_;
2727
std::unordered_set<std::string> Converter::decl_ids_;
2828
std::unordered_set<std::string> Converter::globals_;
29+
std::vector<std::string> Converter::global_inits_;
2930
std::unordered_set<std::string> Converter::abstract_structs_;
3031
Converter::RecordIndex Converter::record_decls_;
3132
std::map<std::string, Converter::MethodsOnPtr> Converter::methods_on_ptr_;
@@ -74,6 +75,23 @@ std::string Converter::EmitMethodsOnPtr() {
7475
return out;
7576
}
7677

78+
std::string Converter::ForceGlobalInit(const clang::VarDecl *decl) {
79+
return std::format("std::cell::LazyCell::force(&*&raw const {});",
80+
GetNamedDeclAsString(decl));
81+
}
82+
83+
std::string Converter::EmitGlobalInits(Model model) {
84+
std::string out = model == Model::kUnsafe
85+
? "pub unsafe fn __cpp2rust_init_globals() {\n"
86+
: "pub fn __cpp2rust_init_globals() {\n";
87+
for (const auto &line : global_inits_) {
88+
out += line;
89+
out += '\n';
90+
}
91+
out += "}\n";
92+
return out;
93+
}
94+
7795
std::string Converter::EmitOpaqueRecords() {
7896
std::string out;
7997
record_decls_.ForEachUndefined([&](const std::string &name) {
@@ -512,6 +530,7 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
512530
StrCat(AccessSpecifierAsString(decl->getAccess()), keyword::kStatic,
513531
keyword_mut_);
514532
ENSURE(decl_ids_.insert(GetID(decl)).second);
533+
global_inits_.push_back(ForceGlobalInit(decl));
515534
} else if (decl->isStaticLocal()) {
516535
StrCat(keyword::kStatic, keyword_mut_);
517536
} else if (decl->isLocalVarDecl()) {
@@ -4180,14 +4199,15 @@ pub fn main() {{
41804199
let mut argv: Vec<*mut libc::c_char> = args.iter().map(|arg| arg.as_ptr() as *mut libc::c_char).collect();
41814200
argv.push(::std::ptr::null_mut());
41824201
unsafe {{
4202+
__cpp2rust_init_globals();
41834203
::std::process::exit(main_0((argv.len() - 1) as i32, argv.as_mut_ptr()) as i32)
41844204
}}
41854205
}})",
41864206
main_function_name));
41874207
} else {
4188-
StrCat(std::format(
4189-
"pub fn main() {{ unsafe {{ std::process::exit({}() as i32); }} }}",
4190-
main_function_name));
4208+
StrCat(std::format("pub fn main() {{ unsafe {{ __cpp2rust_init_globals(); "
4209+
"std::process::exit({}() as i32); }} }}",
4210+
main_function_name));
41914211
}
41924212
}
41934213

‎cpp2rust/converter/converter.h‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <vector>
1919

2020
#include "converter/converter_lib.h"
21+
#include "converter/factory.h"
2122
#include "converter/lex.h"
2223
#include "converter/translation_rule.h"
2324
#include "logging.h"
@@ -52,6 +53,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
5253
virtual void EmitFilePreamble();
5354

5455
static std::string EmitOpaqueRecords();
56+
static std::string EmitGlobalInits(Model model);
5557

5658
static std::string EmitMethodsOnPtr();
5759

@@ -99,6 +101,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
99101

100102
virtual bool VisitVarDecl(clang::VarDecl *decl);
101103
virtual bool LazyStaticInit() const { return true; }
104+
virtual std::string ForceGlobalInit(const clang::VarDecl *decl);
102105

103106
void ConvertVarDecl(clang::VarDecl *decl);
104107

@@ -1016,6 +1019,7 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
10161019
std::vector<ExprKind> curr_expr_kind_;
10171020
static std::unordered_map<std::string, std::string> inner_structs_;
10181021
static std::unordered_set<std::string> globals_;
1022+
static std::vector<std::string> global_inits_;
10191023
clang::Sema *sema_ = nullptr;
10201024
};
10211025
} // namespace cpp2rust

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2410,6 +2410,12 @@ void ConverterRefCount::ConvertPointerSubscript(
24102410
}
24112411
}
24122412

2413+
std::string ConverterRefCount::ForceGlobalInit(const clang::VarDecl *decl) {
2414+
const auto *clone =
2415+
decl->getType()->isReferenceType() ? "Ptr::clone" : "Value::clone";
2416+
return std::format("let _ = {}.with({});", GetNamedDeclAsString(decl), clone);
2417+
}
2418+
24132419
void ConverterRefCount::ConvertFunctionMain(
24142420
const clang::FunctionDecl *decl,
24152421
const std::string_view main_function_name) {
@@ -2423,12 +2429,14 @@ pub fn main() {{
24232429
argv.iter().map(|x| {{ x.borrow_mut().push(0); x.as_pointer() }}).collect(),
24242430
));
24252431
(*argv.borrow_mut()).push(Ptr::null());
2432+
__cpp2rust_init_globals();
24262433
::std::process::exit({}(::std::env::args().len() as i32,
24272434
argv.as_pointer()));
24282435
}})",
24292436
main_function_name));
24302437
} else {
2431-
StrCat(std::format("pub fn main() {{ std::process::exit({}()); }}",
2438+
StrCat(std::format("pub fn main() {{ __cpp2rust_init_globals(); "
2439+
"std::process::exit({}()); }}",
24322440
main_function_name));
24332441
}
24342442
}

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class ConverterRefCount final : public Converter {
8080

8181
bool VisitVarDecl(clang::VarDecl *decl) override;
8282
bool LazyStaticInit() const override { return false; }
83+
std::string ForceGlobalInit(const clang::VarDecl *decl) override;
8384

8485
void ConvertGlobalVarDecl(clang::VarDecl *decl) override;
8586

‎cpp2rust/cpp2rust_lib.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ std::string TranspileSrc(std::string_view cc_code, Model model,
3232
filename.ends_with(".c") ? CLANG_C_COMPILER : CLANG_CXX_COMPILER);
3333
rs_code += Converter::EmitOpaqueRecords();
3434
rs_code += Converter::EmitMethodsOnPtr();
35+
rs_code += Converter::EmitGlobalInits(model);
3536
return rs_code;
3637
}
3738

@@ -73,6 +74,7 @@ std::string TranspileDir(std::string_view build_dir, Model model,
7374
Tool.run(&factory);
7475
rs_code += Converter::EmitOpaqueRecords();
7576
rs_code += Converter::EmitMethodsOnPtr();
77+
rs_code += Converter::EmitGlobalInits(model);
7678
return rs_code;
7779
}
7880
} // namespace cpp2rust

‎tests/multi-file/cross_tu_anon_enum_collision/out/refcount/cross_tu_anon_enum_collision.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub fn a_value_1() -> i32 {
1414
return (*x.borrow());
1515
}
1616
pub fn main() {
17+
__cpp2rust_init_globals();
1718
std::process::exit(main_0());
1819
}
1920
fn main_0() -> i32 {
@@ -28,3 +29,4 @@ pub fn b_value_2() -> i32 {
2829
(*x.borrow_mut()) |= (anon_3_BETA as i32);
2930
return (*x.borrow());
3031
}
32+
pub fn __cpp2rust_init_globals() {}

‎tests/multi-file/cross_tu_anon_enum_collision/out/unsafe/cross_tu_anon_enum_collision.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub unsafe fn a_value_1() -> i32 {
1515
}
1616
pub fn main() {
1717
unsafe {
18+
__cpp2rust_init_globals();
1819
std::process::exit(main_0() as i32);
1920
}
2021
}
@@ -30,3 +31,4 @@ pub unsafe fn b_value_2() -> i32 {
3031
x |= (anon_3_BETA as i32);
3132
return x;
3233
}
34+
pub unsafe fn __cpp2rust_init_globals() {}

‎tests/multi-file/cross_tu_tag_collision/out/refcount/cross_tu_tag_collision.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub fn a_value_0() -> i32 {
3636
return (*(*w.borrow()).id.borrow());
3737
}
3838
pub fn main() {
39+
__cpp2rust_init_globals();
3940
std::process::exit(main_0());
4041
}
4142
fn main_0() -> i32 {
@@ -51,3 +52,4 @@ pub fn b_value_1() -> i32 {
5152
let w: Value<widget_enum> = Rc::new(RefCell::new(widget_enum_WIDGET_C));
5253
return ((*w.borrow()) as i32);
5354
}
55+
pub fn __cpp2rust_init_globals() {}

‎tests/multi-file/cross_tu_tag_collision/out/unsafe/cross_tu_tag_collision.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub unsafe fn a_value_0() -> i32 {
1818
}
1919
pub fn main() {
2020
unsafe {
21+
__cpp2rust_init_globals();
2122
std::process::exit(main_0() as i32);
2223
}
2324
}
@@ -34,3 +35,4 @@ pub unsafe fn b_value_1() -> i32 {
3435
let mut w: widget_enum = widget_enum_WIDGET_C;
3536
return (w as i32);
3637
}
38+
pub unsafe fn __cpp2rust_init_globals() {}

‎tests/multi-file/extern_functions/out/refcount/extern_functions.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::io::{Read, Seek, Write};
77
use std::os::fd::AsFd;
88
use std::rc::{Rc, Weak};
99
pub fn main() {
10+
__cpp2rust_init_globals();
1011
std::process::exit(main_0());
1112
}
1213
fn main_0() -> i32 {
@@ -29,3 +30,4 @@ pub fn helper_0(x: i32) -> i32 {
2930
&({ unrelated3_3() });
3031
return ((*x.borrow()) + 1);
3132
}
33+
pub fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)