Skip to content

Commit 0c299e5

Browse files
authored
Handle char array initialization through { string literal } (#175)
`const char var[] = {"string literal"}` is a valid initialization. Add support for it in codegen.
1 parent 8fca8f9 commit 0c299e5

10 files changed

Lines changed: 52 additions & 0 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,6 +2758,10 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) {
27582758
StrCat(token::kComma);
27592759
}
27602760
} else {
2761+
if (IsInitExprOfStringLiteral(expr)) {
2762+
Convert(expr->getInit(0)->IgnoreParenImpCasts());
2763+
return false;
2764+
}
27612765
PushBracket bracket(*this);
27622766
for (auto *init : expr->inits()) {
27632767
ConvertVarInit(init->getType(), init);

cpp2rust/converter/converter_lib.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,14 @@ bool IsAsciiStringLiteral(const clang::StringLiteral *str) {
255255
return true;
256256
}
257257

258+
bool IsInitExprOfStringLiteral(const clang::InitListExpr *expr) {
259+
auto type = expr->getType();
260+
return expr->getNumInits() == 1 && type->isArrayType() &&
261+
type->getArrayElementTypeNoTypeQual()->isCharType() &&
262+
clang::isa<clang::StringLiteral>(
263+
expr->getInit(0)->IgnoreParenImpCasts());
264+
}
265+
258266
std::vector<clang::CXXConstructorDecl *>
259267
GetTemplateInstantiatedCtors(clang::CXXRecordDecl *decl) {
260268
std::vector<clang::CXXConstructorDecl *> out;

cpp2rust/converter/converter_lib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ bool IsCallToOstream(clang::CallExpr *expr);
6767

6868
bool IsAsciiStringLiteral(const clang::StringLiteral *str);
6969

70+
bool IsInitExprOfStringLiteral(const clang::InitListExpr *expr);
71+
7072
std::vector<clang::CXXConstructorDecl *>
7173
GetTemplateInstantiatedCtors(clang::CXXRecordDecl *decl);
7274

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,6 +1397,12 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) {
13971397
return false;
13981398
}
13991399

1400+
if (IsInitExprOfStringLiteral(expr)) {
1401+
Convert(expr->getInit(0)->IgnoreParenImpCasts());
1402+
computed_expr_type_ = ComputedExprType::FreshValue;
1403+
return false;
1404+
}
1405+
14001406
auto conv = getConversionKind();
14011407
// 2D arrays are FullRefCount'ed on the second level as well.
14021408
PushConversionKind push(

tests/unit/out/refcount/string_literals.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,12 @@ fn main_0() -> i32 {
6060
let _str: Ptr<u8> = (immutable_empty_arr.as_pointer() as Ptr<u8>);
6161
foo_const_1(_str)
6262
});
63+
let inited_through_init_list: Value<Box<[u8]>> = Rc::new(RefCell::new(Box::<[u8]>::from(
64+
b"papanasi cu smantana\0".as_slice(),
65+
)));
66+
({
67+
let _str: Ptr<u8> = (inited_through_init_list.as_pointer() as Ptr<u8>);
68+
foo_const_1(_str)
69+
});
6370
return 0;
6471
}

tests/unit/out/refcount/string_literals_c.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,12 @@ fn main_0() -> i32 {
9191
let _str: Ptr<u8> = (immutable_empty_arr.as_pointer() as Ptr<u8>);
9292
foo_const_1(_str)
9393
});
94+
let inited_through_init_list: Value<Box<[u8]>> = Rc::new(RefCell::new(Box::<[u8]>::from(
95+
b"papanasi cu smantana\0".as_slice(),
96+
)));
97+
({
98+
let _str: Ptr<u8> = (inited_through_init_list.as_pointer() as Ptr<u8>);
99+
foo_const_1(_str)
100+
});
94101
return 0;
95102
}

tests/unit/out/unsafe/string_literals.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,10 @@ unsafe fn main_0() -> i32 {
4949
let _str: *const u8 = immutable_empty_arr.as_ptr();
5050
foo_const_1(_str)
5151
});
52+
let inited_through_init_list: [u8; 21] = *b"papanasi cu smantana\0";
53+
(unsafe {
54+
let _str: *const u8 = inited_through_init_list.as_ptr();
55+
foo_const_1(_str)
56+
});
5257
return 0;
5358
}

tests/unit/out/unsafe/string_literals_c.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,10 @@ unsafe fn main_0() -> i32 {
8484
let _str: *const u8 = immutable_empty_arr.as_ptr();
8585
foo_const_1(_str)
8686
});
87+
let inited_through_init_list: [u8; 21] = *b"papanasi cu smantana\0";
88+
(unsafe {
89+
let _str: *const u8 = inited_through_init_list.as_ptr();
90+
foo_const_1(_str)
91+
});
8792
return 0;
8893
}

tests/unit/string_literals.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@ int main() {
2222
foo_const("");
2323
foo_const(immutable_empty);
2424
foo_const(immutable_empty_arr);
25+
26+
const char inited_through_init_list[] = {"papanasi cu smantana"};
27+
foo_const(inited_through_init_list);
28+
2529
return 0;
2630
}

tests/unit/string_literals_c.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,9 @@ int main() {
3131
foo_const(immutable_empty);
3232
foo_const(mutable_empty_arr);
3333
foo_const(immutable_empty_arr);
34+
35+
const char inited_through_init_list[] = {"papanasi cu smantana"};
36+
foo_const(inited_through_init_list);
37+
3438
return 0;
3539
}

0 commit comments

Comments
 (0)