C++11 single default deleted constructor fix

Fix for when a class has a default deleted constructor and does
not have any other constructors (except implicit or explicit copy
constructors).

Closes #1644
This commit is contained in:
William S Fulton 2023-09-02 13:49:01 +01:00
parent 605e5a1abb
commit fb7e0ef069
4 changed files with 41 additions and 19 deletions

View File

@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.2.0 (in progress)
===========================
2023-09-02: wsfulton
#1644 Fix wrapping types passed by value where the type has a deleted
default constructor.
2023-08-16: shadchin
[Python] #2665 Fix missing-field-initializers warning to provide support
for python-3.12.

View File

@ -69,6 +69,16 @@ struct sometype2 {
static void take(sometype2 s) {}
};
struct sometype3 {
int num;
sometype3() = delete;
static sometype3 make(int n) {
// Note: Can only be constructed via copy constructor, so use C++11 uniform initialization to create
return sometype3 {n};
}
static void take(sometype3 s) {}
};
/* Not working with prerelease of gcc-4.8
struct nonew {
void *operator new(std::size_t) = delete;

View File

@ -19,6 +19,10 @@ public class cpp11_default_delete_runme {
sometype2 st2 = new sometype2(22.2);
sometype2.take(st2);
st2 = sometype2.make(33.3);
sometype3 st3 = sometype3.make(22);
sometype3.take(st3);
st3 = sometype3.make(33);
}
}

View File

@ -765,7 +765,7 @@ Allocate():
if (Getattr(n, "abstracts")) {
Delattr(n, "allocate:default_constructor");
}
if (!Getattr(n, "allocate:default_constructor")) {
if (!Getattr(n, "allocate:default_constructor") && !GetFlag(n, "allocate:deleted_default_constructor")) {
/* Check base classes */
List *bases = Getattr(n, "allbases");
int allows_default = 1;
@ -1201,34 +1201,38 @@ Allocate():
virtual int constructorDeclaration(Node *n) {
if (!inclass)
return SWIG_OK;
if (GetFlag(n, "deleted"))
return SWIG_OK;
Parm *parms = Getattr(n, "parms");
bool deleted_constructor = (GetFlag(n, "deleted"));
bool default_constructor = !ParmList_numrequired(parms);
AccessMode access_mode = accessModeFromString(Getattr(n, "access"));
process_exceptions(n);
if (!extendmode) {
if (!ParmList_numrequired(parms)) {
/* Class does define a default constructor */
/* However, we had better see where it is defined */
if (access_mode == PUBLIC) {
Setattr(inclass, "allocate:default_constructor", "1");
} else if (access_mode == PROTECTED) {
Setattr(inclass, "allocate:default_base_constructor", "1");
if (!deleted_constructor) {
if (!extendmode) {
if (default_constructor) {
/* Class does define a default constructor */
/* However, we had better see where it is defined */
if (access_mode == PUBLIC) {
Setattr(inclass, "allocate:default_constructor", "1");
} else if (access_mode == PROTECTED) {
Setattr(inclass, "allocate:default_base_constructor", "1");
}
}
}
/* Class defines some kind of constructor. May or may not be public */
Setattr(inclass, "allocate:has_constructor", "1");
if (access_mode == PUBLIC) {
/* Class defines some kind of constructor. May or may not be public */
Setattr(inclass, "allocate:has_constructor", "1");
if (access_mode == PUBLIC) {
Setattr(inclass, "allocate:public_constructor", "1");
}
} else {
Setattr(inclass, "allocate:has_constructor", "1");
Setattr(inclass, "allocate:public_constructor", "1");
}
} else {
Setattr(inclass, "allocate:has_constructor", "1");
Setattr(inclass, "allocate:public_constructor", "1");
if (default_constructor && !extendmode)
SetFlag(inclass, "allocate:deleted_default_constructor");
}
/* See if this is a copy constructor */
if (parms && (ParmList_numrequired(parms) == 1)) {
/* Look for a few cases. X(const X &), X(X &), X(X *) */