Skip to content

Commit af4c1d8

Browse files
committed
Handle both dereference and subscript
1 parent 1281198 commit af4c1d8

5 files changed

Lines changed: 31 additions & 24 deletions

File tree

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,10 +1506,6 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
15061506
ToString(sub_expr->IgnoreParens())));
15071507
computed_expr_type_ = ComputedExprType::FreshPointer;
15081508
return false;
1509-
} else if (auto ptr = ConvertArrayPointerDeref(sub_expr); !ptr.empty()) {
1510-
StrCat(ptr);
1511-
computed_expr_type_ = ComputedExprType::FreshPointer;
1512-
return false;
15131509
} else {
15141510
// we need to write (var.as_pointer as Ptr<T>) because Rust isn't
15151511
// smart enough to pick the right specialization
@@ -2580,9 +2576,6 @@ std::string ConverterRefCount::ConvertVarInitValue(clang::QualType qual_type,
25802576
return std::format("Ptr::<{}>::from_string_literal({})", code_unit,
25812577
ToString(expr->IgnoreParens()->IgnoreImplicit()));
25822578
}
2583-
if (auto ptr = ConvertArrayPointerDeref(expr); !ptr.empty()) {
2584-
return ptr;
2585-
}
25862579
}
25872580
return ConvertFreshPointer(expr, qual_type);
25882581
}
@@ -3046,6 +3039,9 @@ void ConverterRefCount::ConvertPointerSubscript(
30463039
ConvertPointerElem(base, idx);
30473040
} else {
30483041
ConvertPointerOffset(base, idx);
3042+
if (expr->getType()->isArrayType()) {
3043+
StrCat(GetPointerDerefSuffix(expr->getType()), ".as_pointer()");
3044+
}
30493045
}
30503046
if (deref) {
30513047
StrCat(GetPointerDerefSuffix(expr->getType()));
@@ -3127,6 +3123,11 @@ void ConverterRefCount::ConvertDeref(clang::Expr *expr) {
31273123
str = std::move(buf).str();
31283124
}
31293125

3126+
if (isAddrOf() && pointee_type->isArrayType()) {
3127+
str = std::format("({}){}.as_pointer()", std::move(str),
3128+
GetPointerDerefSuffix(pointee_type));
3129+
}
3130+
31303131
if (isObject() && WantsElementPtr() &&
31313132
(IsBoxedType(ctx_, pointee_type) || pointee_type->isArrayType())) {
31323133
StrCat(std::format("Ptr::<{}>::decay(&({}))", ToString(pointee_type),
@@ -3199,18 +3200,6 @@ bool ConverterRefCount::DerefReadsValue(clang::QualType pointee_type) {
31993200
return pointee_type.isPODType(ctx_) && !pointee_type->isRecordType();
32003201
}
32013202

3202-
std::string ConverterRefCount::ConvertArrayPointerDeref(clang::Expr *expr) {
3203-
auto *op =
3204-
clang::dyn_cast<clang::UnaryOperator>(expr->IgnoreParenNoopCasts(ctx_));
3205-
if (!op || op->getOpcode() != clang::UO_Deref ||
3206-
!op->getType()->isArrayType()) {
3207-
return {};
3208-
}
3209-
PushConversionKind push(*this, ConversionKind::Unboxed);
3210-
return std::format("({}{}.as_pointer())", ConvertRValue(op->getSubExpr()),
3211-
GetPointerDerefSuffix(op->getType()));
3212-
}
3213-
32143203
const char *
32153204
ConverterRefCount::GetPointerDerefSuffix(clang::QualType pointee_type) {
32163205
return DerefReadsValue(pointee_type) ? ".read()" : ".upgrade().deref()";

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,6 @@ class ConverterRefCount final : public Converter {
348348
// returns a copy of the pointee, rather than a borrow of it.
349349
bool DerefReadsValue(clang::QualType pointee_type);
350350
const char *GetPointerDerefSuffix(clang::QualType pointee_type);
351-
352-
std::string ConvertArrayPointerDeref(clang::Expr *expr);
353351
// Sets the freshness of the dereference of a pointer to pointee_type: a
354352
// copy read with .read() is fresh.
355353
void SetDerefFreshness(clang::QualType pointee_type);

‎tests/unit/array_reference.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,5 +98,8 @@ int main() {
9898
assert(r[0] == 4);
9999
assert(sum(r) == 15);
100100
assert(sum(*p) == 15);
101+
int (*q)[3] = rows;
102+
assert(sum(q[1]) == 15);
103+
assert(q[1] == &rows[1][0]);
101104
return 0;
102105
}

‎tests/unit/out/refcount/array_reference.rs‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,29 @@ fn main_0() -> i32 {
143143
let mut p: Ptr<Value<Box<[i32]>>> = (rows.as_pointer() as Ptr<Value<Box<[i32]>>>);
144144
p.prefix_inc();
145145
assert!(
146-
({ (p.read().as_pointer()) } == {
146+
({ ((p).read().as_pointer() as Ptr::<i32>).clone() } == {
147147
((((rows.as_pointer() as Ptr<Value<Box<[i32]>>>)
148148
.offset(1)
149149
.read()
150150
.as_pointer()) as Ptr<i32>)
151151
.offset(0))
152152
})
153153
);
154-
let r: Ptr<i32> = (p.read().as_pointer());
154+
let r: Ptr<i32> = ((p).read().as_pointer()).clone();
155155
assert!(((elem!((r), 0).read()) == 4));
156156
assert!((({ sum_2((r).clone(),) }) == 15));
157-
assert!((({ sum_2((p.read().as_pointer()),) }) == 15));
157+
assert!((({ sum_2(((p).read().as_pointer()).clone(),) }) == 15));
158+
let mut q: Ptr<Value<Box<[i32]>>> = (rows.as_pointer() as Ptr<Value<Box<[i32]>>>);
159+
assert!((({ sum_2(q.offset((1) as isize).read().as_pointer(),) }) == 15));
160+
assert!(
161+
({ (q.offset((1) as isize).read().as_pointer() as Ptr::<i32>) } == {
162+
((((rows.as_pointer() as Ptr<Value<Box<[i32]>>>)
163+
.offset(1)
164+
.read()
165+
.as_pointer()) as Ptr<i32>)
166+
.offset(0))
167+
})
168+
);
158169
return 0;
159170
}
160171
pub fn __cpp2rust_init_globals() {}

‎tests/unit/out/unsafe/array_reference.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ unsafe fn main_0() -> i32 {
125125
assert!((((*r)[(0) as usize]) == (4)));
126126
assert!(((unsafe { sum_2(r,) }) == (15)));
127127
assert!(((unsafe { sum_2(&(*p),) }) == (15)));
128+
let mut q: *mut [i32; 3] = rows.as_mut_ptr();
129+
assert!(((unsafe { sum_2(&(*q.offset((1) as isize)),) }) == (15)));
130+
assert!(
131+
(((*q.offset((1) as isize)).as_mut_ptr())
132+
== (&mut rows[(1) as usize][(0) as usize] as *mut i32))
133+
);
128134
return 0;
129135
}
130136
pub unsafe fn __cpp2rust_init_globals() {}

0 commit comments

Comments
 (0)