Skip to content
Merged
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
13 changes: 8 additions & 5 deletions src/cpyrt/CPPMethod.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,14 @@ int cpyrt::CPPMethod::GetPriority() {
// type:
// interop::TCppType_t type = interop::GetMethodArgType(fMethod, iarg);

if (interop::IsBuiltin(aname)) {
// Not builtin and spelled "const void *", so match the compacted name.
std::string compact = aname;
compact.erase(std::remove(compact.begin(), compact.end(), ' '),
compact.end());

if (compact.find("void*") != std::string::npos) {
priority -= 1000; // void*/void** shouldn't be too greedy
} else if (interop::IsBuiltin(aname)) {
// complex type (note: double penalty: for complex and the template type)
if (strstr(aname.c_str(), "std::complex"))
priority -= 10; // prefer double, float, etc. over conversion
Expand Down Expand Up @@ -557,10 +564,6 @@ int cpyrt::CPPMethod::GetPriority() {
else if (strstr(aname.c_str(), "char") && aname[aname.size() - 1] != '*')
priority += -60; // prefer (const) char* over char

// oddball
else if (strstr(aname.c_str(), "void*"))
priority -= 1000; // void*/void** shouldn't be too greedy

} else {
// This is a user-defined type (class, struct, enum, etc.).

Expand Down
29 changes: 29 additions & 0 deletions test/test_overloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,3 +411,32 @@ def test15_disallow_mutable_pointer_references(self):
ptr = cppjit.gbl.MyClass()

raises(TypeError, cppjit.gbl.changePtr, ptr)

def test16_voidp_does_not_outrank_conversion(self):
"""Verify that a const void* overload does not shadow a converting one."""

import cppjit

cppjit.cppdef("""
namespace VoidPPriority {
struct Handle {
void* data;
Handle() : data(nullptr) {}
Handle(void* p) : data(p) {}
};
struct ConstHandle {
const void* data;
ConstHandle() : data(nullptr) {}
ConstHandle(const void* p) : data(p) {} // declared first on purpose
ConstHandle(Handle h) : data(h.data) {}
};
Handle make_handle() { return Handle((void*)0xABCD1234); }
bool kept_value(ConstHandle c) { return c.data == (const void*)0xABCD1234; }
}""")

ns = cppjit.gbl.VoidPPriority

# taking ConstHandle(const void*) would pass the proxy's address instead
h = ns.make_handle()
assert ns.kept_value(h)
assert ns.kept_value(ns.make_handle())
Loading