Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions modules/standard/CTypes.chpl
Original file line number Diff line number Diff line change
Expand Up @@ -1026,6 +1026,16 @@ module CTypes {
return c_pointer_return(x);
}

// Special handling for unmanaged classes to work with wide pointers
// In a wide pointer context, unmanaged class variables are stored as
// narrow pointers, but c_pointer_return would try to take the address
// of the variable itself, treating it incorrectly as a wide pointer.
// Use c_ptrTo instead to get the actual pointer value.
@chpldoc.nodoc
inline proc c_addrOf(const x: ?t): c_ptr(void) where isUnmanagedClass(t) {
return c_ptrTo(x);
}

// Added as unstable for 2.4, can be merged into stable version once we're
// confident in it.
@chpldoc.nodoc
Expand All @@ -1044,6 +1054,12 @@ module CTypes {
return c_pointer_return_const(x);
}

// Special handling for unmanaged classes - see corresponding c_addrOf overload
@chpldoc.nodoc
inline proc c_addrOfConst(const x: ?t): c_ptrConst(void) where isUnmanagedClass(t) {
return c_ptrToConst(x);
}

// See note on corresponding c_addrOf overload
@chpldoc.nodoc
@unstable("using 'c_addrOfConst' with a domain argument is unstable")
Expand Down
20 changes: 20 additions & 0 deletions test-issue-28008.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use CTypes;

class MyClass {
var x: int = 21;
}

proc main() {

var myOwned = new owned MyClass();
var myBorrow = myOwned.borrow();
var myUnmanaged = new unmanaged MyClass();
defer { delete myUnmanaged; }

var addr1 = c_addrOf(myOwned);
var addr2 = c_addrOf(myBorrow);
var addr3 = c_addrOf(myUnmanaged);


writeln(addr1.deref(), addr2.deref(), addr3.deref(), sep =" | "); // addr3.deref() fails
}
25 changes: 25 additions & 0 deletions test/library/standard/CTypes/c_addrOf_unmanaged_class.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Test for issue #28008
// c_addrOf on unmanaged class should work with wide pointers

use CTypes;

class MyClass {
var x: int = 21;
}

proc main() {

var myOwned = new owned MyClass();
var myBorrow = myOwned.borrow();
var myUnmanaged = new unmanaged MyClass();
defer { delete myUnmanaged; }

var addr1 = c_addrOf(myOwned);
var addr2 = c_addrOf(myBorrow);
var addr3 = c_addrOf(myUnmanaged);

writeln(addr1.deref(), " | ", addr2.deref(), " | ", addr3.deref());

// Verify that c_addrOf on unmanaged class returns the same as c_ptrTo
writeln(c_addrOf(myUnmanaged):string == c_ptrTo(myUnmanaged):string);
}
2 changes: 2 additions & 0 deletions test/library/standard/CTypes/c_addrOf_unmanaged_class.good
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{x = 21} | {x = 21} | {x = 21}
true
3 changes: 2 additions & 1 deletion test/types/cptr/c_ptr_class_type.good
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ true
true
true

false
true
5
c_ptr(void)
5