Skip to content

Commit c889b9a

Browse files
committed
Fix array to pointer decay for libc members
1 parent a7cb1cf commit c889b9a

3 files changed

Lines changed: 22 additions & 1 deletion

File tree

cpp2rust/converter/converter.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1942,9 +1942,18 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
19421942
Convert(sub_expr);
19431943
break;
19441944
}
1945-
Convert(sub_expr);
19461945
bool dest_pointee_const =
19471946
expr->getType()->getPointeeType().isConstQualified();
1947+
if (const auto *member = clang::dyn_cast<clang::MemberExpr>(
1948+
sub_expr->IgnoreParenImpCasts());
1949+
member && IsCharArrayFieldFromLibc(member->getMemberDecl())) {
1950+
PushParen paren(*this);
1951+
Convert(sub_expr);
1952+
StrCat(dest_pointee_const ? ".as_ptr()" : ".as_mut_ptr()");
1953+
StrCat(keyword::kAs, dest_pointee_const ? "*const u8" : "*mut u8");
1954+
break;
1955+
}
1956+
Convert(sub_expr);
19481957
if (clang::isa<clang::StringLiteral>(sub_expr) ||
19491958
clang::isa<clang::PredefinedExpr>(sub_expr)) {
19501959
StrCat(".as_ptr()");

cpp2rust/converter/converter_lib.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,16 @@ bool IsCharPointerFieldFromLibc(const clang::ValueDecl *decl) {
139139
field->getParent()->getLocation());
140140
}
141141

142+
bool IsCharArrayFieldFromLibc(const clang::ValueDecl *decl) {
143+
auto field = clang::dyn_cast<clang::FieldDecl>(decl);
144+
if (!field || !field->getType()->isArrayType() ||
145+
!field->getType()->getArrayElementTypeNoTypeQual()->isCharType()) {
146+
return false;
147+
}
148+
return field->getASTContext().getSourceManager().isInSystemHeader(
149+
field->getParent()->getLocation());
150+
}
151+
142152
bool IsUserDefinedDecl(const clang::Decl *decl) {
143153
const auto &ctx = decl->getASTContext();
144154
const auto &src_mgr = ctx.getSourceManager();

cpp2rust/converter/converter_lib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ bool IsInMainFile(const clang::Decl *decl);
4141

4242
bool IsCharPointerFieldFromLibc(const clang::ValueDecl *decl);
4343

44+
bool IsCharArrayFieldFromLibc(const clang::ValueDecl *decl);
45+
4446
bool IsUserDefinedDecl(const clang::Decl *decl);
4547

4648
bool RefersToUserDefinedDecl(const clang::Expr *expr);

0 commit comments

Comments
 (0)