Skip to content

Commit b7f319b

Browse files
committed
Merge branch 'safe-cstring' into inet
2 parents b6f0fd8 + 60cddf0 commit b7f319b

84 files changed

Lines changed: 5654 additions & 218 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.

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,12 @@ add_custom_command(
188188

189189
add_custom_target("preprocess-rust-rules" ALL
190190
DEPENDS ${rust_rules_ir_outputs})
191+
192+
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES
193+
"${PROJECT_SOURCE_DIR}/libcc2rs/target"
194+
"${PROJECT_SOURCE_DIR}/libcc2rs-macros/target"
195+
"${PROJECT_SOURCE_DIR}/libc-dep/target"
196+
"${PROJECT_SOURCE_DIR}/rules/target"
197+
"${PROJECT_SOURCE_DIR}/rule-preprocessor/target"
198+
"${CMAKE_BINARY_DIR}/target_preprocessor"
199+
)

cpp2rust/converter/converter.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,11 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) {
891891
}
892892
}
893893

894+
EmitRustStructOrUnion(decl);
895+
} else if (decl->isUnion()) {
896+
if (!record_decls_.MarkDefined(GetRecordName(decl))) {
897+
return false;
898+
}
894899
EmitRustStructOrUnion(decl);
895900
} else {
896901
// FIXME: improve error handling
@@ -2084,8 +2089,7 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
20842089
bool dest_pointee_const =
20852090
expr->getType()->getPointeeType().isConstQualified();
20862091
Convert(sub_expr);
2087-
if (clang::isa<clang::StringLiteral>(sub_expr) ||
2088-
clang::isa<clang::PredefinedExpr>(sub_expr)) {
2092+
if (IsStringLiteralExpr(sub_expr)) {
20892093
StrCat(".as_ptr()");
20902094
if (!dest_pointee_const) {
20912095
StrCat(".cast_mut()");
@@ -3680,6 +3684,7 @@ void Converter::ConvertPointerOffset(clang::Expr *base, clang::Expr *idx,
36803684
PushParen neg_paren(*this, !is_addition);
36813685
{
36823686
PushParen inner(*this);
3687+
PushExprKind push(*this, ExprKind::RValue);
36833688
Convert(idx);
36843689
}
36853690
StrCat(keyword::kAs, "isize");

cpp2rust/converter/converter.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,13 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
274274
// Option<fn> implements Copy
275275
virtual bool FunctionPointerImplementsCopy() const { return true; }
276276

277+
bool TypeIsCopyable(clang::QualType ty) const {
278+
if (ty->isFunctionPointerType() || ty->isFunctionType()) {
279+
return FunctionPointerImplementsCopy();
280+
}
281+
return ty->isIntegerType();
282+
}
283+
277284
virtual void ConvertPrintf(clang::CallExpr *expr);
278285

279286
void ConvertVAArgCall(clang::CallExpr *expr);

cpp2rust/converter/converter_lib.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ bool IsUnionArrayMember(const clang::Expr *base) {
140140
return false;
141141
}
142142

143+
bool IsStringLiteralExpr(const clang::Expr *expr) {
144+
const auto *stripped = expr->IgnoreParens()->IgnoreImplicit();
145+
return clang::isa<clang::StringLiteral>(stripped) ||
146+
clang::isa<clang::PredefinedExpr>(stripped);
147+
}
148+
143149
bool IsUserDefinedDecl(const clang::Decl *decl) {
144150
const auto &ctx = decl->getASTContext();
145151
const auto &src_mgr = ctx.getSourceManager();
@@ -1104,9 +1110,4 @@ ConstCastType GetConstCastType(clang::QualType to, clang::QualType from) {
11041110
}
11051111
}
11061112

1107-
bool TypeIsCopyable(clang::QualType ty) {
1108-
return ty->isIntegerType() || ty->isFunctionPointerType() ||
1109-
ty->isFunctionType();
1110-
}
1111-
11121113
} // namespace cpp2rust

cpp2rust/converter/converter_lib.h

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

4343
bool IsUnionArrayMember(const clang::Expr *base);
4444

45+
bool IsStringLiteralExpr(const clang::Expr *expr);
46+
4547
bool IsUserDefinedDecl(const clang::Decl *decl);
4648

4749
bool RefersToUserDefinedDecl(const clang::Expr *expr);
@@ -223,6 +225,4 @@ enum class ConstCastType {
223225

224226
ConstCastType GetConstCastType(clang::QualType to, clang::QualType from);
225227

226-
bool TypeIsCopyable(clang::QualType ty);
227-
228228
} // namespace cpp2rust

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 97 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,14 @@ bool ConverterRefCount::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) {
417417
return false;
418418
}
419419

420+
bool ConverterRefCount::VisitOffsetOfExpr(clang::OffsetOfExpr *expr) {
421+
clang::Expr::EvalResult result;
422+
ENSURE(expr->EvaluateAsInt(result, ctx_));
423+
StrCat(std::format("{}_usize", result.Val.getInt().getZExtValue()));
424+
computed_expr_type_ = ComputedExprType::FreshValue;
425+
return false;
426+
}
427+
420428
void ConverterRefCount::ConvertOrdAndPartialOrdTraits(
421429
const clang::CXXRecordDecl *decl, const clang::FunctionDecl *op) {
422430
std::string first_branch, second_branch, first_return, second_return;
@@ -723,10 +731,10 @@ void ConverterRefCount::EmitHoistedInArmAssignment(clang::VarDecl *decl) {
723731
if (!decl->hasInit()) {
724732
return;
725733
}
726-
PushConversionKind push(*this, ConversionKind::Unboxed);
734+
PushConversionKind push(*this, ConversionKind::FullRefCount);
727735
StrCat(token::kStar, GetNamedDeclAsString(decl), ".borrow_mut()",
728736
token::kAssign);
729-
Convert(decl->getInit());
737+
StrCat(ConvertVarInitValue(decl->getType(), decl->getInit()));
730738
StrCat(token::kSemiColon);
731739
}
732740

@@ -1161,6 +1169,9 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
11611169

11621170
if (expr->getCastKind() == clang::CastKind::CK_BitCast) {
11631171
if (expr->getType()->isVoidPointerType()) {
1172+
if (sub_expr->getType()->isVoidPointerType()) {
1173+
return Convert(sub_expr);
1174+
}
11641175
PushConversionKind push(*this, ConversionKind::Unboxed);
11651176
if (sub_expr->getType()->isPointerType() &&
11661177
sub_expr->getType()->getPointeeType()->isArrayType()) {
@@ -1170,11 +1181,20 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
11701181
->getPointeeType()
11711182
->getAsArrayTypeUnsafe()
11721183
->getElementType())));
1184+
} else if (IsStringLiteralExpr(sub_expr)) {
1185+
StrCat(std::format("{}.to_any()", ConvertFreshPointer(sub_expr)));
11731186
} else {
11741187
StrCat(std::format("({} as {}).to_any()", ConvertFreshPointer(sub_expr),
11751188
ToString(sub_expr->getType())));
11761189
}
11771190
computed_expr_type_ = ComputedExprType::FreshPointer;
1191+
} else if (sub_expr->getType()->isVoidPointerType() &&
1192+
expr->getType()->isPointerType()) {
1193+
Convert(sub_expr);
1194+
PushConversionKind push(*this, ConversionKind::Unboxed);
1195+
StrCat(std::format(".reinterpret_cast::<{}>()",
1196+
ConvertPointeeType(expr->getType())));
1197+
computed_expr_type_ = ComputedExprType::FreshPointer;
11781198
} else {
11791199
Convert(sub_expr);
11801200
}
@@ -1202,9 +1222,9 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
12021222
Convert(sub_expr);
12031223
return false;
12041224
}
1205-
if (clang::isa<clang::StringLiteral>(sub_expr) ||
1206-
clang::isa<clang::PredefinedExpr>(sub_expr)) {
1207-
StrCat(std::format("Ptr::from_string_literal({})", ToString(sub_expr)));
1225+
if (IsStringLiteralExpr(sub_expr)) {
1226+
StrCat(std::format("Ptr::from_string_literal({})",
1227+
ToString(sub_expr->IgnoreParens())));
12081228
return false;
12091229
} else {
12101230
// we need to write (var.as_pointer as Ptr<T>) because Rust isn't
@@ -1308,6 +1328,7 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13081328
return false;
13091329
}
13101330
if (expr->getCastKind() == clang::CK_NullToPointer) {
1331+
PushConversionKind push(*this, ConversionKind::Unboxed);
13111332
StrCat(GetDefaultAsString(expr->getType()));
13121333
computed_expr_type_ = ComputedExprType::FreshPointer;
13131334
return false;
@@ -1319,17 +1340,40 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13191340
StrCat(
13201341
std::format("{}.reinterpret_cast::<{}>()", ToString(expr->getSubExpr()),
13211342
GetUnsafeTypeAsString(expr->getType()->getPointeeType())));
1343+
computed_expr_type_ = ComputedExprType::FreshPointer;
13221344
return false;
13231345
case clang::Stmt::CStyleCastExprClass:
13241346
case clang::Stmt::CXXStaticCastExprClass:
1347+
if (expr->getCastKind() == clang::CastKind::CK_PointerToIntegral ||
1348+
expr->getCastKind() == clang::CastKind::CK_IntegralToPointer) {
1349+
std::string dst_type;
1350+
{
1351+
PushConversionKind push(*this, ConversionKind::Unboxed);
1352+
dst_type = ToString(expr->getType());
1353+
}
1354+
if (expr->getCastKind() == clang::CastKind::CK_PointerToIntegral) {
1355+
StrCat(std::format("{}.to_int()", ToString(expr->getSubExpr())));
1356+
computed_expr_type_ = ComputedExprType::FreshValue;
1357+
} else {
1358+
StrCat(std::format("<{}>::from_int({})", dst_type,
1359+
ToString(expr->getSubExpr())));
1360+
computed_expr_type_ = ComputedExprType::FreshPointer;
1361+
}
1362+
return false;
1363+
}
1364+
13251365
if (!VisitFunctionPointerCast(expr)) {
13261366
return false;
1367+
} else if (expr->getSubExpr()->getType()->isVoidPointerType() &&
1368+
expr->getType()->isVoidPointerType()) {
1369+
return Convert(expr->getSubExpr());
13271370
} else if (expr->getSubExpr()->getType()->isVoidPointerType() &&
13281371
expr->getType()->isPointerType()) {
13291372
Convert(expr->getSubExpr());
13301373
PushConversionKind push(*this, ConversionKind::Unboxed);
13311374
StrCat(std::format(".reinterpret_cast::<{}>()",
13321375
ConvertPointeeType(expr->getType())));
1376+
computed_expr_type_ = ComputedExprType::FreshPointer;
13331377
return false;
13341378
} else if (expr->getType()->isVoidPointerType() &&
13351379
expr->getSubExpr()->getType()->isPointerType()) {
@@ -1343,6 +1387,7 @@ bool ConverterRefCount::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
13431387
StrCat(std::format("{}.reinterpret_cast::<{}>()",
13441388
ToString(expr->getSubExpr()),
13451389
ConvertPointeeType(expr->getType())));
1390+
computed_expr_type_ = ComputedExprType::FreshPointer;
13461391
return false;
13471392
}
13481393
return Converter::VisitExplicitCastExpr(expr);
@@ -1549,10 +1594,11 @@ void ConverterRefCount::ConvertUnionMemberAccessor(clang::MemberExpr *expr) {
15491594
"{}.reinterpret_cast::<{}>()", str,
15501595
ToString(
15511596
member->getType()->getAsArrayTypeUnsafe()->getElementType())));
1597+
computed_expr_type_ = ComputedExprType::FreshPointer;
15521598
} else {
15531599
StrCat(str);
1600+
computed_expr_type_ = ComputedExprType::Pointer;
15541601
}
1555-
computed_expr_type_ = ComputedExprType::Pointer;
15561602
return;
15571603
}
15581604

@@ -1875,7 +1921,9 @@ ConverterRefCount::GetArrayDefaultAsString(clang::QualType qual_type) {
18751921
const auto &size = array_type->getSize();
18761922
auto size_as_string = GetNumAsString(size);
18771923
auto element_type = array_type->getElementType();
1878-
PushConversionKind push(*this, ConversionKind::Unboxed);
1924+
PushConversionKind push(*this, element_type->isArrayType()
1925+
? ConversionKind::FullRefCount
1926+
: ConversionKind::Unboxed);
18791927
auto element_type_as_string = ToString(element_type);
18801928
auto default_as_string = GetDefaultAsString(element_type);
18811929
return std::format("(0..{}).map(|_| {}).collect::<Box<[{}]>>()",
@@ -1943,35 +1991,34 @@ ConverterRefCount::GetStructAttributes(const clang::RecordDecl *decl) {
19431991
return attrs;
19441992
}
19451993

1946-
void ConverterRefCount::ConvertVarInit(clang::QualType qual_type,
1947-
clang::Expr *expr) {
1994+
std::string ConverterRefCount::ConvertVarInitValue(clang::QualType qual_type,
1995+
clang::Expr *expr) {
19481996
if (auto lambda = clang::dyn_cast<clang::LambdaExpr>(
19491997
expr->IgnoreUnlessSpelledInSource())) {
1950-
std::string str;
1951-
{
1952-
Buffer buf(*this);
1953-
PushConversionKind push(*this, ConversionKind::Unboxed);
1954-
if (qual_type->isFunctionPointerType() && lambda->capture_size() == 0) {
1955-
StrCat("FnPtr::new(");
1956-
VisitLambdaExpr(lambda);
1957-
StrCat(')');
1958-
} else {
1959-
VisitLambdaExpr(lambda);
1960-
}
1961-
str = std::move(buf).str();
1998+
Buffer buf(*this);
1999+
PushConversionKind push(*this, ConversionKind::Unboxed);
2000+
if (qual_type->isFunctionPointerType() && lambda->capture_size() == 0) {
2001+
StrCat("FnPtr::new(");
2002+
VisitLambdaExpr(lambda);
2003+
StrCat(')');
2004+
} else {
2005+
VisitLambdaExpr(lambda);
19622006
}
1963-
StrCat(BoxValue(std::move(str)));
1964-
return;
2007+
return std::move(buf).str();
19652008
}
19662009

1967-
bool is_ref = qual_type->isReferenceType();
1968-
PushConversionKind push(*this, ConversionKind::Unboxed, is_ref);
19692010
PushInitType init_type(*this, qual_type);
1970-
if (is_ref || qual_type->isFunctionPointerType()) {
1971-
StrCat(BoxValue(ConvertFreshPointer(expr)));
1972-
} else {
1973-
StrCat(BoxValue(ConvertFreshRValue(expr, qual_type)));
2011+
if (qual_type->isReferenceType() || qual_type->isFunctionPointerType()) {
2012+
return ConvertFreshPointer(expr);
19742013
}
2014+
return ConvertFreshRValue(expr, qual_type);
2015+
}
2016+
2017+
void ConverterRefCount::ConvertVarInit(clang::QualType qual_type,
2018+
clang::Expr *expr) {
2019+
bool is_ref = qual_type->isReferenceType();
2020+
PushConversionKind push(*this, ConversionKind::Unboxed, is_ref);
2021+
StrCat(BoxValue(ConvertVarInitValue(qual_type, expr)));
19752022
}
19762023

19772024
void ConverterRefCount::EmitSetOrAssign(clang::Expr *lhs,
@@ -2143,7 +2190,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
21432190
pending_deref_.set(std::format("({} as {}).offset({})",
21442191
ConvertObject(expr->getArg(0)),
21452192
ConvertPtrType(expr->getArg(0)->getType()),
2146-
ConvertRValue(expr->getArg(1))),
2193+
ConvertSubscriptIndex(expr->getArg(1))),
21472194
expr);
21482195
break;
21492196
}
@@ -2163,7 +2210,7 @@ bool ConverterRefCount::ConvertCXXOperatorCallExpr(
21632210
StrCat(std::format("({} as {}).offset({})",
21642211
ConvertObject(expr->getArg(0)),
21652212
ConvertPtrType(expr->getArg(0)->getType()),
2166-
ConvertRValue(expr->getArg(1))));
2213+
ConvertSubscriptIndex(expr->getArg(1))));
21672214

21682215
if (is_inner_boxed) {
21692216
StrCat(GetPointerDerefSuffix(expr->getType()), ".as_pointer()");
@@ -2198,6 +2245,14 @@ void ConverterRefCount::ConvertFunctionParameters(clang::FunctionDecl *decl) {
21982245
}
21992246
}
22002247

2248+
std::string ConverterRefCount::ConvertSubscriptIndex(clang::Expr *idx) {
2249+
auto str = ConvertRValue(idx);
2250+
if (idx->getType()->isEnumeralType()) {
2251+
return std::format("({}) as isize", str);
2252+
}
2253+
return str;
2254+
}
2255+
22012256
void ConverterRefCount::ConvertArraySubscript(clang::Expr *base,
22022257
clang::Expr *idx,
22032258
clang::QualType type) {
@@ -2211,10 +2266,16 @@ void ConverterRefCount::ConvertArraySubscript(clang::Expr *base,
22112266

22122267
{
22132268
PushParen paren(*this, is_inner_boxed);
2214-
StrCat(std::format("({} as {}).offset({})",
2215-
ToString(base->IgnoreImplicit()),
2216-
ConvertPtrType(base->IgnoreImplicit()->getType()),
2217-
ConvertRValue(idx)));
2269+
if (IsStringLiteralExpr(base)) {
2270+
StrCat(std::format("Ptr::from_string_literal({}).offset({})",
2271+
ToString(base->IgnoreParens()->IgnoreImplicit()),
2272+
ConvertSubscriptIndex(idx)));
2273+
} else {
2274+
StrCat(std::format("({} as {}).offset({})",
2275+
ToString(base->IgnoreImplicit()),
2276+
ConvertPtrType(base->IgnoreImplicit()->getType()),
2277+
ConvertSubscriptIndex(idx)));
2278+
}
22182279

22192280
if (is_inner_boxed) {
22202281
StrCat(GetPointerDerefSuffix(type), ".as_pointer()");
@@ -2459,6 +2520,7 @@ std::string ConverterRefCount::ConvertMappedMethodCall(
24592520

24602521
std::string ConverterRefCount::ConvertPointeeType(clang::QualType ptr_type) {
24612522
assert(!ptr_type.isNull() && ptr_type->isPointerType());
2523+
PushConversionKind push(*this, ConversionKind::Unboxed);
24622524
auto pointee = ptr_type->getPointeeType();
24632525
if (!pointee->isRecordType()) {
24642526
return ToString(pointee);

cpp2rust/converter/models/converter_refcount.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class ConverterRefCount final : public Converter {
2828

2929
bool VisitCXXRecordDecl(clang::CXXRecordDecl *decl) override;
3030

31+
bool VisitOffsetOfExpr(clang::OffsetOfExpr *expr) override;
32+
3133
void EmitRustUnion(clang::RecordDecl *decl) override;
3234

3335
bool EmitsReprCForRecords() const override { return false; }
@@ -167,6 +169,8 @@ class ConverterRefCount final : public Converter {
167169

168170
void ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) override;
169171

172+
std::string ConvertVarInitValue(clang::QualType qual_type, clang::Expr *expr);
173+
170174
void ConvertAssignment(clang::Expr *lhs, clang::Expr *rhs,
171175
std::string_view assign_operator) override;
172176

@@ -242,6 +246,8 @@ class ConverterRefCount final : public Converter {
242246
std::string ConvertPtrType(clang::QualType type);
243247
std::string ConvertPointeeType(clang::QualType ptr_type) override;
244248

249+
std::string ConvertSubscriptIndex(clang::Expr *idx);
250+
245251
std::string GetSafeTypeAsString(clang::QualType qual_type) const;
246252

247253
/// The kind of conversion that should be performed.

0 commit comments

Comments
 (0)