mirror of https://github.com/swig/swig
Fix %copyctor used on class hierarchies with non-const copy constructor
Previously SWIG always attempted to call a copy constructor taking a const reference parameter instead of a non-const reference parameter.
This commit is contained in:
parent
b87c9fb4d7
commit
74e1deef6b
|
@ -7,6 +7,13 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.2.0 (in progress)
|
||||
===========================
|
||||
|
||||
2023-07-29: wsfulton
|
||||
https://sourceforge.net/p/swig/bugs/678/
|
||||
Fix %copyctor used on class hierarchies with non-const copy
|
||||
constructors. Previously SWIG always attempted to call a copy
|
||||
constructor taking a const reference parameter instead of a
|
||||
non-const reference parameter.
|
||||
|
||||
2023-07-28: wsfulton
|
||||
[#2541] Fix overloading of templated constructors and %copyctor.
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ CPP_TEST_CASES += \
|
|||
constant_pointers \
|
||||
constover \
|
||||
constructor_copy \
|
||||
constructor_copy_non_const \
|
||||
constructor_exception \
|
||||
constructor_explicit \
|
||||
constructor_ignore \
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
%module(ruby_minherit="1") constructor_copy_non_const
|
||||
|
||||
// Tests %copyctor and non-const copy constructors in inheritance chain
|
||||
|
||||
%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
|
||||
SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
|
||||
SWIGWARN_D_MULTIPLE_INHERITANCE,
|
||||
SWIGWARN_PHP_MULTIPLE_INHERITANCE) CCDerived; /* C#, D, Java, PHP multiple inheritance */
|
||||
%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
|
||||
SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
|
||||
SWIGWARN_D_MULTIPLE_INHERITANCE,
|
||||
SWIGWARN_PHP_MULTIPLE_INHERITANCE) CCProtectedDerived; /* C#, D, Java, PHP multiple inheritance */
|
||||
|
||||
%inline %{
|
||||
struct CCBase1 {
|
||||
CCBase1() {}
|
||||
};
|
||||
%}
|
||||
|
||||
%copyctor;
|
||||
|
||||
%inline %{
|
||||
struct CCBase2 {
|
||||
CCBase2() {}
|
||||
CCBase2(CCBase2& other) {} // non-const copyctor
|
||||
};
|
||||
|
||||
struct CCDerived : CCBase1, CCBase2 {
|
||||
CCDerived() {}
|
||||
// implicitly declared non-const copyctor
|
||||
};
|
||||
struct CCMoreDerived : CCDerived {
|
||||
// implicitly declared default ctor
|
||||
// implicitly declared non-const copyctor
|
||||
};
|
||||
struct CCMoreDerived2 : CCDerived {
|
||||
CCMoreDerived2() {}
|
||||
CCMoreDerived2(const CCMoreDerived2& other) {} // const copyctor
|
||||
};
|
||||
struct CCMoreMoreDerived2 : CCMoreDerived2 {
|
||||
// implicitly declared default ctor
|
||||
// implicitly declared const copyctor
|
||||
};
|
||||
%}
|
||||
|
||||
|
||||
// Repeat but with protected non-const copyctor
|
||||
%inline %{
|
||||
struct CCProtectedBase2 {
|
||||
CCProtectedBase2() {}
|
||||
protected:
|
||||
CCProtectedBase2(CCProtectedBase2& other) {} // non-const copyctor
|
||||
};
|
||||
|
||||
struct CCProtectedDerived : CCBase1, CCProtectedBase2 {
|
||||
CCProtectedDerived() {}
|
||||
// implicitly declared non-const copyctor
|
||||
};
|
||||
struct CCProtectedMoreDerived : CCProtectedDerived {
|
||||
// implicitly declared default ctor
|
||||
// implicitly declared non-const copyctor
|
||||
};
|
||||
struct CCProtectedMoreDerived2 : CCProtectedDerived {
|
||||
CCProtectedMoreDerived2() {}
|
||||
CCProtectedMoreDerived2(const CCProtectedMoreDerived2& other) {} // const copyctor
|
||||
};
|
||||
struct CCProtectedMoreMoreDerived2 : CCProtectedMoreDerived2 {
|
||||
// implicitly declared default ctor
|
||||
// implicitly declared const copyctor
|
||||
};
|
||||
%}
|
|
@ -0,0 +1,30 @@
|
|||
import constructor_copy_non_const.*;
|
||||
|
||||
public class constructor_copy_non_const_runme {
|
||||
|
||||
static {
|
||||
try {
|
||||
System.loadLibrary("constructor_copy_non_const");
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
{
|
||||
CCBase2 ccb2 = new CCBase2(new CCBase2());
|
||||
CCDerived ccd = new CCDerived(new CCDerived());
|
||||
CCMoreDerived ccmd = new CCMoreDerived(new CCMoreDerived());
|
||||
CCMoreDerived2 ccmd2 = new CCMoreDerived2(new CCMoreDerived2());
|
||||
CCMoreMoreDerived2 ccmmd2 = new CCMoreMoreDerived2(new CCMoreMoreDerived2());
|
||||
}
|
||||
{
|
||||
// no copy ctor CCProtectedBase2
|
||||
CCProtectedDerived ccd = new CCProtectedDerived(new CCProtectedDerived());
|
||||
CCProtectedMoreDerived ccmd = new CCProtectedMoreDerived(new CCProtectedMoreDerived());
|
||||
CCProtectedMoreDerived2 ccmd2 = new CCProtectedMoreDerived2(new CCProtectedMoreDerived2());
|
||||
CCProtectedMoreMoreDerived2 ccmmd2 = new CCProtectedMoreMoreDerived2(new CCProtectedMoreMoreDerived2());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
from constructor_copy_non_const import *
|
||||
|
||||
ccb2 = CCBase2(CCBase2())
|
||||
ccd = CCDerived(CCDerived())
|
||||
ccmd = CCMoreDerived(CCMoreDerived())
|
||||
ccmd2 = CCMoreDerived2(CCMoreDerived2())
|
||||
ccmmd2 = CCMoreMoreDerived2(CCMoreMoreDerived2())
|
||||
|
||||
# no copy ctor CCProtectedBase2
|
||||
ccd = CCProtectedDerived(CCProtectedDerived())
|
||||
ccmd = CCProtectedMoreDerived(CCProtectedMoreDerived())
|
||||
ccmd2 = CCProtectedMoreDerived2(CCProtectedMoreDerived2())
|
||||
ccmmd2 = CCProtectedMoreMoreDerived2(CCProtectedMoreMoreDerived2())
|
|
@ -651,11 +651,13 @@ Allocate():
|
|||
if (!Getattr(n, "allocate:has_copy_constructor")) {
|
||||
if (Getattr(n, "abstracts")) {
|
||||
Delattr(n, "allocate:copy_constructor");
|
||||
Delattr(n, "allocate:copy_constructor_non_const");
|
||||
}
|
||||
if (!Getattr(n, "allocate:copy_constructor")) {
|
||||
/* Check base classes */
|
||||
List *bases = Getattr(n, "allbases");
|
||||
int allows_copy = 1;
|
||||
int must_be_copy_non_const = 0;
|
||||
|
||||
for (int i = 0; i < Len(bases); i++) {
|
||||
Node *n = Getitem(bases, i);
|
||||
|
@ -663,10 +665,16 @@ Allocate():
|
|||
if (!Getattr(n, "allocate:copy_constructor") && (!Getattr(n, "allocate:copy_base_constructor"))) {
|
||||
allows_copy = 0;
|
||||
}
|
||||
if (Getattr(n, "allocate:copy_constructor_non_const") || (Getattr(n, "allocate:copy_base_constructor_non_const"))) {
|
||||
must_be_copy_non_const = 1;
|
||||
}
|
||||
}
|
||||
if (allows_copy) {
|
||||
Setattr(n, "allocate:copy_constructor", "1");
|
||||
}
|
||||
if (must_be_copy_non_const) {
|
||||
Setattr(n, "allocate:copy_constructor_non_const", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1164,6 +1172,7 @@ Allocate():
|
|||
if (parms && (ParmList_numrequired(parms) == 1)) {
|
||||
/* Look for a few cases. X(const X &), X(X &), X(X *) */
|
||||
int copy_constructor = 0;
|
||||
int copy_constructor_non_const = 0;
|
||||
SwigType *type = Getattr(inclass, "name");
|
||||
String *tn = NewStringf("r.q(const).%s", type);
|
||||
String *cc = SwigType_typedef_resolve_all(tn);
|
||||
|
@ -1183,6 +1192,7 @@ Allocate():
|
|||
cc = NewStringf("r.%s", Getattr(inclass, "name"));
|
||||
if (Strcmp(cc, Getattr(parms, "type")) == 0) {
|
||||
copy_constructor = 1;
|
||||
copy_constructor_non_const = 1;
|
||||
} else {
|
||||
Delete(cc);
|
||||
cc = NewStringf("p.%s", Getattr(inclass, "name"));
|
||||
|
@ -1205,6 +1215,15 @@ Allocate():
|
|||
} else if (access_mode == PROTECTED) {
|
||||
Setattr(inclass, "allocate:copy_base_constructor", "1");
|
||||
}
|
||||
if (copy_constructor_non_const) {
|
||||
Setattr(n, "copy_constructor_non_const", "1");
|
||||
Setattr(inclass, "allocate:has_copy_constructor_non_const", "1");
|
||||
if (access_mode == PUBLIC) {
|
||||
Setattr(inclass, "allocate:copy_constructor_non_const", "1");
|
||||
} else if (access_mode == PROTECTED) {
|
||||
Setattr(inclass, "allocate:copy_base_constructor_non_const", "1");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SWIG_OK;
|
||||
|
@ -1237,11 +1256,12 @@ static void addCopyConstructor(Node *n) {
|
|||
Setfile(cn, Getfile(n));
|
||||
Setline(cn, Getline(n));
|
||||
|
||||
int copy_constructor_non_const = GetFlag(n, "allocate:copy_constructor_non_const");
|
||||
String *cname = Getattr(n, "name");
|
||||
SwigType *type = Copy(cname);
|
||||
String *lastname = Swig_scopename_last(cname);
|
||||
String *name = SwigType_templateprefix(lastname);
|
||||
String *cc = NewStringf("r.q(const).%s", type);
|
||||
String *cc = NewStringf(copy_constructor_non_const ? "r.%s" : "r.q(const).%s", type);
|
||||
String *decl = NewStringf("f(%s).", cc);
|
||||
String *oldname = Getattr(n, "sym:name");
|
||||
|
||||
|
|
Loading…
Reference in New Issue