Skip to content

Commit 20681da

Browse files
committed
Fix const_cast for references
1 parent 2bb3063 commit 20681da

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎cpp2rust/converter/converter.cpp‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2767,7 +2767,28 @@ bool Converter::VisitExplicitCastExpr(clang::ExplicitCastExpr *expr) {
27672767
}
27682768
// A cast to a reference type only rebinds the operand, it converts nothing
27692769
if (type->isReferenceType()) {
2770-
Convert(sub_expr);
2770+
const char *suffix = nullptr;
2771+
if (isAddrOf()) {
2772+
switch (
2773+
GetConstCastType(type.getNonReferenceType(), sub_expr->getType())) {
2774+
case ConstCastType::MutableToConst:
2775+
suffix = ".cast_const()";
2776+
break;
2777+
case ConstCastType::ConstToMutable:
2778+
suffix = ".cast_mut()";
2779+
break;
2780+
default:
2781+
break;
2782+
}
2783+
}
2784+
{
2785+
PushParen paren(*this, suffix);
2786+
Convert(sub_expr);
2787+
}
2788+
if (suffix) {
2789+
StrCat(suffix);
2790+
computed_expr_type_ = ComputedExprType::FreshPointer;
2791+
}
27712792
return false;
27722793
}
27732794
switch (expr->getStmtClass()) {

‎tests/unit/unconst.cpp‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,22 @@
44

55
#define UNCONST(p) ((void *)(uintptr_t)(const void *)(p))
66

7+
void set(int &r) { r = 7; }
8+
9+
template <typename T> void set_through(const T &v) { set(const_cast<T &>(v)); }
10+
711
int main() {
812
const int a = 1;
913
const int *p = &a;
1014
auto q = static_cast<int *>(UNCONST(p));
1115
assert(p == q);
16+
17+
int v = 1;
18+
const int &cr = v;
19+
set(const_cast<int &>(cr));
20+
assert(v == 7);
21+
v = 0;
22+
set_through(v);
23+
assert(v == 7);
1224
return 0;
1325
}

0 commit comments

Comments
 (0)