Skip to content

Commit 0173f51

Browse files
committed
Disambiguate global variables with internal linkage
1 parent 7f4e421 commit 0173f51

45 files changed

Lines changed: 620 additions & 441 deletions

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: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,6 @@ void Converter::ConvertVaListVarDecl(clang::VarDecl *decl) {
393393
StrCat(keyword_mut_, GetNamedDeclAsString(decl), token::kColon, "VaList");
394394
}
395395

396-
static std::string staticVarName(const clang::NamedDecl *decl) {
397-
return "s_" + ReplaceAll(Mapper::ToString(decl), "::", "_");
398-
}
399-
400396
bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
401397
auto qual_type = decl->getType();
402398
auto name = GetNamedDeclAsString(decl);
@@ -407,7 +403,6 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
407403
}
408404

409405
if (decl->isFileVarDecl()) {
410-
name = staticVarName(decl);
411406
if ((decl->isThisDeclarationADefinition() ==
412407
clang::VarDecl::DeclarationOnly &&
413408
!decl->hasInit()) ||
@@ -418,7 +413,6 @@ bool Converter::ConvertVarDeclSkipInit(clang::VarDecl *decl) {
418413
keyword_mut_);
419414
ENSURE(decl_ids_.insert(GetID(decl)).second);
420415
} else if (decl->isStaticLocal()) {
421-
name = staticVarName(decl);
422416
StrCat(keyword::kStatic, keyword_mut_);
423417
} else if (decl->isLocalVarDecl()) {
424418
StrCat(keyword::kLet);
@@ -2383,7 +2377,7 @@ std::string Converter::ConvertDeclRefExpr(clang::DeclRefExpr *expr) {
23832377
}
23842378

23852379
if (IsGlobalVar(expr)) {
2386-
return staticVarName(expr->getDecl());
2380+
return GetNamedDeclAsString(expr->getDecl());
23872381
}
23882382

23892383
return GetNamedDeclAsString(decl);

cpp2rust/converter/converter_lib.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,16 @@ std::string GetID(const clang::Decl *decl) {
369369

370370
static std::unordered_map<std::string, size_t> type_mapping;
371371

372+
static size_t GetDeclId(const clang::NamedDecl *decl, bool internal) {
373+
std::string key =
374+
clang::ASTNameGenerator(decl->getASTContext()).getName(decl) +
375+
GetParamSignature(decl);
376+
if (internal) {
377+
key += GetLocationID(decl);
378+
}
379+
return type_mapping.try_emplace(key, type_mapping.size()).first->second;
380+
}
381+
372382
std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
373383
auto name = decl->getDeclName().isIdentifier() ? decl->getName().str()
374384
: decl->getNameAsString();
@@ -384,19 +394,19 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) {
384394
return std::format("anon_{}", GetAnonIndex(target));
385395
}
386396

397+
std::optional<size_t> id;
387398
if (auto *fn = clang::dyn_cast<clang::FunctionDecl>(decl)) {
388399
if (!clang::isa<clang::CXXMethodDecl>(fn)) {
389-
auto mangled =
390-
clang::ASTNameGenerator(decl->getASTContext()).getName(decl) +
391-
GetParamSignature(decl);
392-
if (fn->getFormalLinkage() == clang::Linkage::Internal) {
393-
mangled += GetLocationID(decl);
394-
}
395-
auto id =
396-
type_mapping.try_emplace(mangled, type_mapping.size()).first->second;
397-
name += '_';
398-
name += std::to_string(id);
400+
id = GetDeclId(decl, fn->getFormalLinkage() == clang::Linkage::Internal);
399401
}
402+
} else if (auto *var = clang::dyn_cast<clang::VarDecl>(decl);
403+
var && (var->isFileVarDecl() || var->isStaticLocal())) {
404+
id = GetDeclId(var->getCanonicalDecl(),
405+
var->getFormalLinkage() != clang::Linkage::External);
406+
}
407+
if (id) {
408+
name += '_';
409+
name += std::to_string(*id);
400410
}
401411

402412
// transform decl names that are rust keywords:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
cmake_minimum_required(VERSION 3.16)
2+
project(static_name_collision LANGUAGES C)
3+
add_executable(app a.c b.c)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include <assert.h>
2+
3+
static int same_name_different_type = 1;
4+
static int same_name_same_type = 5;
5+
6+
int a_foo() { return same_name_different_type; }
7+
int a_bar() { return same_name_same_type; }
8+
9+
float b_foo();
10+
int b_bar();
11+
12+
int main(void) {
13+
assert(a_foo() == 1);
14+
assert(b_foo() == 1.0f);
15+
assert(a_bar() == 5);
16+
assert(b_bar() == 6);
17+
return 0;
18+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
static float same_name_different_type = 1.0f;
2+
static int same_name_same_type = 6;
3+
4+
float b_foo() { return same_name_different_type; }
5+
int b_bar() { return same_name_same_type; }
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
thread_local!(
10+
pub static same_name_different_type_0: Value<i32> = Rc::new(RefCell::new(1));
11+
);
12+
thread_local!(
13+
pub static same_name_same_type_1: Value<i32> = Rc::new(RefCell::new(5));
14+
);
15+
pub fn a_foo_2() -> i32 {
16+
return (*same_name_different_type_0.with(Value::clone).borrow());
17+
}
18+
pub fn a_bar_3() -> i32 {
19+
return (*same_name_same_type_1.with(Value::clone).borrow());
20+
}
21+
pub fn main() {
22+
std::process::exit(main_0());
23+
}
24+
fn main_0() -> i32 {
25+
assert!((((({ a_foo_2() }) == 1) as i32) != 0));
26+
assert!((((({ b_foo_4() }) == 1.0E+0) as i32) != 0));
27+
assert!((((({ a_bar_3() }) == 5) as i32) != 0));
28+
assert!((((({ b_bar_5() }) == 6) as i32) != 0));
29+
return 0;
30+
}
31+
thread_local!(
32+
pub static same_name_different_type_6: Value<f32> = Rc::new(RefCell::new(1.0E+0));
33+
);
34+
thread_local!(
35+
pub static same_name_same_type_7: Value<i32> = Rc::new(RefCell::new(6));
36+
);
37+
pub fn b_foo_4() -> f32 {
38+
return (*same_name_different_type_6.with(Value::clone).borrow());
39+
}
40+
pub fn b_bar_5() -> i32 {
41+
return (*same_name_same_type_7.with(Value::clone).borrow());
42+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
pub static mut same_name_different_type_0: i32 = unsafe { 1 };
10+
pub static mut same_name_same_type_1: i32 = unsafe { 5 };
11+
pub unsafe fn a_foo_2() -> i32 {
12+
return same_name_different_type_0;
13+
}
14+
pub unsafe fn a_bar_3() -> i32 {
15+
return same_name_same_type_1;
16+
}
17+
pub fn main() {
18+
unsafe {
19+
std::process::exit(main_0() as i32);
20+
}
21+
}
22+
unsafe fn main_0() -> i32 {
23+
assert!(((((unsafe { a_foo_2() }) == (1)) as i32) != 0));
24+
assert!(((((unsafe { b_foo_4() }) == (1.0E+0)) as i32) != 0));
25+
assert!(((((unsafe { a_bar_3() }) == (5)) as i32) != 0));
26+
assert!(((((unsafe { b_bar_5() }) == (6)) as i32) != 0));
27+
return 0;
28+
}
29+
pub static mut same_name_different_type_6: f32 = unsafe { 1.0E+0 };
30+
pub static mut same_name_same_type_7: i32 = unsafe { 6 };
31+
pub unsafe fn b_foo_4() -> f32 {
32+
return same_name_different_type_6;
33+
}
34+
pub unsafe fn b_bar_5() -> i32 {
35+
return same_name_same_type_7;
36+
}

tests/unit/out/refcount/addr_of_global.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,75 +42,75 @@ impl Clone for Outer {
4242
}
4343
impl ByteRepr for Outer {}
4444
thread_local!(
45-
pub static s_alpha: Value<Inner> = Rc::new(RefCell::new(Inner {
45+
pub static alpha_0: Value<Inner> = Rc::new(RefCell::new(Inner {
4646
value: Rc::new(RefCell::new(1)),
4747
}));
4848
);
4949
thread_local!(
50-
pub static s_beta: Value<Inner> = Rc::new(RefCell::new(Inner {
50+
pub static beta_1: Value<Inner> = Rc::new(RefCell::new(Inner {
5151
value: Rc::new(RefCell::new(2)),
5252
}));
5353
);
5454
thread_local!(
55-
pub static s_shared: Value<Inner> = Rc::new(RefCell::new(Inner {
55+
pub static shared_2: Value<Inner> = Rc::new(RefCell::new(Inner {
5656
value: Rc::new(RefCell::new(42)),
5757
}));
5858
);
5959
thread_local!(
60-
pub static s_items: Value<Box<[Ptr<Inner>]>> = Rc::new(RefCell::new(Box::new([
61-
(s_alpha.with(Value::clone).as_pointer()),
62-
(s_beta.with(Value::clone).as_pointer()),
60+
pub static items_3: Value<Box<[Ptr<Inner>]>> = Rc::new(RefCell::new(Box::new([
61+
(alpha_0.with(Value::clone).as_pointer()),
62+
(beta_1.with(Value::clone).as_pointer()),
6363
])));
6464
);
6565
thread_local!(
66-
pub static s_obj: Value<Outer> = Rc::new(RefCell::new(Outer {
67-
p: Rc::new(RefCell::new((s_shared.with(Value::clone).as_pointer()))),
66+
pub static obj_4: Value<Outer> = Rc::new(RefCell::new(Outer {
67+
p: Rc::new(RefCell::new((shared_2.with(Value::clone).as_pointer()))),
6868
}));
6969
);
7070
pub fn main() {
7171
std::process::exit(main_0());
7272
}
7373
fn main_0() -> i32 {
7474
assert!(
75-
((*(*(*s_items.with(Value::clone).borrow())[(0) as usize]
75+
((*(*(*items_3.with(Value::clone).borrow())[(0) as usize]
7676
.upgrade()
7777
.deref())
7878
.value
7979
.borrow())
8080
== 1)
8181
);
8282
assert!(
83-
((*(*(*s_items.with(Value::clone).borrow())[(1) as usize]
83+
((*(*(*items_3.with(Value::clone).borrow())[(1) as usize]
8484
.upgrade()
8585
.deref())
8686
.value
8787
.borrow())
8888
== 2)
8989
);
9090
assert!(
91-
((*(*(*(*s_obj.with(Value::clone).borrow()).p.borrow())
91+
((*(*(*(*obj_4.with(Value::clone).borrow()).p.borrow())
9292
.upgrade()
9393
.deref())
9494
.value
9595
.borrow())
9696
== 42)
9797
);
9898
thread_local!(
99-
static s_cache: Value<Box<[Ptr<Inner>]>> = Rc::new(RefCell::new(Box::new([
100-
(s_alpha.with(Value::clone).as_pointer()),
101-
(s_beta.with(Value::clone).as_pointer()),
99+
static cache_5: Value<Box<[Ptr<Inner>]>> = Rc::new(RefCell::new(Box::new([
100+
(alpha_0.with(Value::clone).as_pointer()),
101+
(beta_1.with(Value::clone).as_pointer()),
102102
])));
103103
);
104104
assert!(
105-
((*(*(*s_cache.with(Value::clone).borrow())[(0) as usize]
105+
((*(*(*cache_5.with(Value::clone).borrow())[(0) as usize]
106106
.upgrade()
107107
.deref())
108108
.value
109109
.borrow())
110110
== 1)
111111
);
112112
assert!(
113-
((*(*(*s_cache.with(Value::clone).borrow())[(1) as usize]
113+
((*(*(*cache_5.with(Value::clone).borrow())[(1) as usize]
114114
.upgrade()
115115
.deref())
116116
.value

tests/unit/out/refcount/bool_condition_logical.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@ impl From<i32> for Code {
2525
}
2626
libcc2rs::impl_enum_inc_dec!(Code);
2727
thread_local!(
28-
pub static s_side_effect: Value<i32> = Rc::new(RefCell::new(0));
28+
pub static side_effect_0: Value<i32> = Rc::new(RefCell::new(0));
2929
);
30-
pub fn observe_0(v: i32) -> i32 {
30+
pub fn observe_1(v: i32) -> i32 {
3131
let v: Value<i32> = Rc::new(RefCell::new(v));
32-
(*s_side_effect.with(Value::clone).borrow_mut()).prefix_inc();
32+
(*side_effect_0.with(Value::clone).borrow_mut()).prefix_inc();
3333
return (*v.borrow());
3434
}
35-
pub fn returns_one_1() -> i32 {
35+
pub fn returns_one_2() -> i32 {
3636
return 1;
3737
}
38-
pub fn returns_zero_2() -> i32 {
38+
pub fn returns_zero_3() -> i32 {
3939
return 0;
4040
}
4141
pub fn main() {
@@ -66,25 +66,25 @@ fn main_0() -> i32 {
6666
{
6767
assert!(true);
6868
}
69-
(*s_side_effect.with(Value::clone).borrow_mut()) = 0;
69+
(*side_effect_0.with(Value::clone).borrow_mut()) = 0;
7070
if ((*zero.borrow()) != 0)
7171
&& (({
7272
let _v: i32 = 1;
73-
observe_0(_v)
73+
observe_1(_v)
7474
}) != 0)
7575
{
7676
assert!(false);
7777
}
78-
assert!(((*s_side_effect.with(Value::clone).borrow()) == 0));
78+
assert!(((*side_effect_0.with(Value::clone).borrow()) == 0));
7979
if ((*n.borrow()) != 0)
8080
|| (({
8181
let _v: i32 = 1;
82-
observe_0(_v)
82+
observe_1(_v)
8383
}) != 0)
8484
{
8585
assert!(true);
8686
}
87-
assert!(((*s_side_effect.with(Value::clone).borrow()) == 0));
87+
assert!(((*side_effect_0.with(Value::clone).borrow()) == 0));
8888
let x: Value<i32> = Rc::new(RefCell::new(5));
8989
let y: Value<i32> = Rc::new(RefCell::new(3));
9090
let flags: Value<u32> = Rc::new(RefCell::new(2_u32));
@@ -138,19 +138,19 @@ fn main_0() -> i32 {
138138
if ((*x.borrow()) > (*y.borrow())) && (((*n.borrow()) != 0) && (!(*cp.borrow()).is_null())) {
139139
assert!(true);
140140
}
141-
if ((*x.borrow()) > (*y.borrow())) && (({ returns_one_1() }) != 0) {
141+
if ((*x.borrow()) > (*y.borrow())) && (({ returns_one_2() }) != 0) {
142142
assert!(true);
143143
}
144-
if ((*x.borrow()) > (*y.borrow())) && (!(({ returns_zero_2() }) != 0)) {
144+
if ((*x.borrow()) > (*y.borrow())) && (!(({ returns_zero_3() }) != 0)) {
145145
assert!(true);
146146
}
147-
if ((*x.borrow()) < (*y.borrow())) || (({ returns_one_1() }) != 0) {
147+
if ((*x.borrow()) < (*y.borrow())) || (({ returns_one_2() }) != 0) {
148148
assert!(true);
149149
}
150-
if ((*x.borrow()) < (*y.borrow())) || (!(({ returns_one_1() }) != 0)) {
150+
if ((*x.borrow()) < (*y.borrow())) || (!(({ returns_one_2() }) != 0)) {
151151
assert!(false);
152152
}
153-
if ((!((*p.borrow()).is_null())) && (({ returns_one_1() }) != 0)) && ((*n.borrow()) != 0) {
153+
if ((!((*p.borrow()).is_null())) && (({ returns_one_2() }) != 0)) && ((*n.borrow()) != 0) {
154154
assert!(true);
155155
}
156156
return 0;

0 commit comments

Comments
 (0)