Skip to content

Commit 46c52c4

Browse files
committed
String literals are mutable in C
1 parent 7e01ac7 commit 46c52c4

3 files changed

Lines changed: 47 additions & 22 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,10 @@ std::string Converter::GetEscapedStringLiteral(clang::Expr *expr,
17031703

17041704
bool Converter::VisitStringLiteral(clang::StringLiteral *expr) {
17051705
StrCat(std::format("b{}.as_ptr()", GetEscapedStringLiteral(expr, true)));
1706+
// In C, string literals are char[], in C++ they are const char[]
1707+
if (!expr->getType().isConstQualified()) {
1708+
StrCat(".cast_mut()");
1709+
}
17061710
return false;
17071711
}
17081712

@@ -1722,27 +1726,27 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
17221726
SetValueFreshness(type);
17231727
break;
17241728
}
1725-
case clang::CastKind::CK_ArrayToPointerDecay:
1726-
if (clang::isa<clang::StringLiteral>(sub_expr) ||
1727-
clang::isa<clang::PredefinedExpr>(sub_expr)) {
1728-
Convert(sub_expr);
1729-
if (IsConversionFromStringLiteralToCharPtr(expr)) {
1730-
StrCat(".cast_mut()");
1731-
}
1732-
return false;
1733-
}
1729+
case clang::CastKind::CK_ArrayToPointerDecay: {
17341730
// __va_list_tag [1] decays to __va_list_tag *. Just pass through by value
17351731
if (IsVaListType(sub_expr->getType())) {
17361732
Convert(sub_expr);
17371733
break;
17381734
}
17391735
Convert(sub_expr);
1740-
if (sub_expr->getType().isConstQualified()) {
1741-
StrCat(keyword_ptr_decay_const_);
1742-
} else {
1743-
StrCat(keyword_ptr_decay_);
1736+
switch (GetConstCastType(
1737+
expr->getType()->getPointeeType(),
1738+
sub_expr->getType()->getAsArrayTypeUnsafe()->getElementType())) {
1739+
case ConstCastType::MutableToConst:
1740+
StrCat(".cast_const()");
1741+
break;
1742+
case ConstCastType::ConstToMutable:
1743+
StrCat(".cast_mut()");
1744+
break;
1745+
default:
1746+
break;
17441747
}
17451748
break;
1749+
}
17461750
case clang::CastKind::CK_BitCast: {
17471751
PushParen paren(*this);
17481752
Convert(sub_expr);
@@ -1756,8 +1760,19 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
17561760
}
17571761
case clang::CastKind::CK_NoOp: {
17581762
Convert(sub_expr);
1759-
if (IsConversionFromStringLiteralToCharPtr(expr)) {
1760-
StrCat(".cast_mut()");
1763+
if (expr->getType()->isPointerType() &&
1764+
sub_expr->getType()->isPointerType()) {
1765+
switch (GetConstCastType(expr->getType()->getPointeeType(),
1766+
sub_expr->getType()->getPointeeType())) {
1767+
case ConstCastType::MutableToConst:
1768+
StrCat(".cast_const()");
1769+
break;
1770+
case ConstCastType::ConstToMutable:
1771+
StrCat(".cast_mut()");
1772+
break;
1773+
default:
1774+
break;
1775+
}
17611776
}
17621777
break;
17631778
}

cpp2rust/converter/converter_lib.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -763,13 +763,16 @@ void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix) {
763763
}
764764
}
765765

766-
bool IsConversionFromStringLiteralToCharPtr(clang::Expr *expr) {
767-
if (clang::isa<clang::StringLiteral>(expr->IgnoreImplicit()) &&
768-
expr->getType()->isPointerType()) {
769-
auto pointee = expr->getType()->getPointeeType();
770-
return pointee->isCharType() && !pointee.isConstQualified();
766+
ConstCastType GetConstCastType(clang::QualType to, clang::QualType from) {
767+
if (to.isConstQualified() && from.isConstQualified()) {
768+
return ConstCastType::ConstToConst;
769+
} else if (!to.isConstQualified() && from.isConstQualified()) {
770+
return ConstCastType::ConstToMutable;
771+
} else if (to.isConstQualified() && !from.isConstQualified()) {
772+
return ConstCastType::MutableToConst;
773+
} else {
774+
return ConstCastType::MutableToMutable;
771775
}
772-
return false;
773776
}
774777

775778
} // namespace cpp2rust

cpp2rust/converter/converter_lib.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ std::vector<clang::Stmt *> GetSwitchCaseBody(clang::CompoundStmt *body,
167167

168168
void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix);
169169

170-
bool IsConversionFromStringLiteralToCharPtr(clang::Expr *expr);
170+
enum class ConstCastType {
171+
ConstToConst,
172+
ConstToMutable,
173+
MutableToConst,
174+
MutableToMutable,
175+
};
176+
177+
ConstCastType GetConstCastType(clang::QualType to, clang::QualType from);
171178

172179
} // namespace cpp2rust

0 commit comments

Comments
 (0)