Fix incorrect variable setters being generated when wrapping arrays

A setter is no longer generated if the type of the array members
are non-assignable.
This commit is contained in:
William S Fulton 2023-09-09 19:15:15 +01:00
parent d4abe14f7e
commit 650aad82ed
5 changed files with 112 additions and 8 deletions

View File

@ -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) Version 4.2.0 (in progress)
=========================== ===========================
2023-09-09: wsfulton
https://sourceforge.net/p/swig/bugs/919/
Fix incorrect variable setters being generated when wrapping arrays.
A setter is no longer generated if the type of the array members
are non-assignable.
2023-09-09: wsfulton 2023-09-09: wsfulton
Non-assignable detection fixes when wrapping const member variables. Non-assignable detection fixes when wrapping const member variables.
Const member variables such as the following are non-assignable by Const member variables such as the following are non-assignable by

View File

@ -25,6 +25,13 @@ struct MemberVars {
AssignPrivate MemberPrivate; AssignPrivate MemberPrivate;
}; };
struct MemberArrayVars {
// These will only have getters
AssignPublic ArrayMemberPublic[1];
AssignProtected ArrayMemberProtected[1];
AssignPrivate ArrayMemberPrivate[1];
};
// (2) Test indirectly non-assignable member variables via inheritance // (2) Test indirectly non-assignable member variables via inheritance
struct AssignPublicDerived : AssignPublic {}; struct AssignPublicDerived : AssignPublic {};
struct AssignProtectedDerived : AssignProtected {}; struct AssignProtectedDerived : AssignProtected {};
@ -120,3 +127,46 @@ struct StaticMembersMemberVarsHolder {
}; };
StaticMembersMemberVars GlobalStaticMembersMemberVars; StaticMembersMemberVars GlobalStaticMembersMemberVars;
%} %}
// (4) Test indirectly non-assignable member variables via classes that themselves have non-assignable array member variables
%inline %{
struct MemberPublicArrayVar {
AssignPublic MemberPublic[1];
};
struct MemberProtectedArrayVar {
protected:
AssignProtected MemberProtected[1];
};
struct MemberPrivateArrayVar {
private:
AssignPrivate MemberPrivate[1];
};
struct MembersMemberArrayVars {
// These will only have getters
MemberPublicArrayVar MemberPublic;
MemberProtectedArrayVar MemberProtected;
MemberPrivateArrayVar MemberPrivate;
};
struct StaticMembersMemberArrayVars {
static MemberPublicArrayVar StaticMemberPublic;
static MemberProtectedArrayVar StaticMemberProtected;
static MemberPrivateArrayVar StaticMemberPrivate;
};
MemberPublicArrayVar StaticMembersMemberArrayVars::StaticMemberPublic;
MemberProtectedArrayVar StaticMembersMemberArrayVars::StaticMemberProtected;
MemberPrivateArrayVar StaticMembersMemberArrayVars::StaticMemberPrivate;
MemberPublicArrayVar GlobalArrayMemberPublic;
MemberProtectedArrayVar GlobalArrayMemberProtected;
MemberPrivateArrayVar GlobalArrayMemberPrivate;
// Setters and getters available
struct StaticMembersMemberArrayVarsHolder {
StaticMembersMemberArrayVars Member;
};
StaticMembersMemberArrayVars GlobalStaticMembersMemberArrayVars;
%}

View File

@ -14,6 +14,7 @@ public class cpp11_assign_delete_runme {
public static void main(String argv[]) { public static void main(String argv[]) {
MemberVars mv = new MemberVars(); MemberVars mv = new MemberVars();
MemberArrayVars mav = new MemberArrayVars();
// (1) Test directly non-assignable member variables // (1) Test directly non-assignable member variables
// These will only have getters // These will only have getters
@ -21,6 +22,10 @@ public class cpp11_assign_delete_runme {
AssignProtected a2 = mv.getMemberProtected(); AssignProtected a2 = mv.getMemberProtected();
AssignPrivate a3 = mv.getMemberPrivate(); AssignPrivate a3 = mv.getMemberPrivate();
AssignPublic ma1 = mav.getArrayMemberPublic();
AssignProtected ma2 = mav.getArrayMemberProtected();
AssignPrivate ma3 = mav.getArrayMemberPrivate();
// (2) Test indirectly non-assignable member variables via inheritance // (2) Test indirectly non-assignable member variables via inheritance
InheritedMemberVars imv = new InheritedMemberVars(); InheritedMemberVars imv = new InheritedMemberVars();
// These will only have getters // These will only have getters
@ -59,6 +64,7 @@ public class cpp11_assign_delete_runme {
cpp11_assign_delete.setGlobalPrivateDerivedSettable(ga9); cpp11_assign_delete.setGlobalPrivateDerivedSettable(ga9);
// (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables // (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
{
MembersMemberVars m = new MembersMemberVars(); MembersMemberVars m = new MembersMemberVars();
// These will only have getters // These will only have getters
@ -81,5 +87,32 @@ public class cpp11_assign_delete_runme {
StaticMembersMemberVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberVars(); StaticMembersMemberVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberVars();
cpp11_assign_delete.setGlobalStaticMembersMemberVars(smmv); cpp11_assign_delete.setGlobalStaticMembersMemberVars(smmv);
}
// (4) Test indirectly non-assignable member variables via classes that themselves have non-assignable array member variables
{
MembersMemberArrayVars m = new MembersMemberArrayVars();
// These will only have getters
MemberPublicArrayVar mpv1 = m.getMemberPublic();
MemberProtectedArrayVar mpv2 = m.getMemberProtected();
MemberPrivateArrayVar mpv3 = m.getMemberPrivate();
MemberPublicArrayVar smpv1 = StaticMembersMemberArrayVars.getStaticMemberPublic();
MemberProtectedArrayVar smpv2 = StaticMembersMemberArrayVars.getStaticMemberProtected();
MemberPrivateArrayVar smpv3 = StaticMembersMemberArrayVars.getStaticMemberPrivate();
MemberPublicArrayVar gmpv1 = cpp11_assign_delete.getGlobalArrayMemberPublic();
MemberProtectedArrayVar gmpv2 = cpp11_assign_delete.getGlobalArrayMemberProtected();
MemberPrivateArrayVar gmpv3 = cpp11_assign_delete.getGlobalArrayMemberPrivate();
// Setters and getters available
StaticMembersMemberArrayVarsHolder smmvh = new StaticMembersMemberArrayVarsHolder();
StaticMembersMemberArrayVars member = smmvh.getMember();
smmvh.setMember(member);
StaticMembersMemberArrayVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberArrayVars();
cpp11_assign_delete.setGlobalStaticMembersMemberArrayVars(smmv);
}
} }
} }

View File

@ -57,11 +57,17 @@
%} %}
%inline %{ %inline %{
Foo foo_global;
Foo foo_global_array[1];
Foo foo_global_array_2d[2][2];
struct FooBar : Foo struct FooBar : Foo
{ {
}; };
FooBar bar; FooBar bar;
FooBar bar_array[1];
FooBar bar_array_2d[2][2];
%} %}
// https://sourceforge.net/p/swig/bugs/1006/ // https://sourceforge.net/p/swig/bugs/1006/

View File

@ -667,15 +667,10 @@ class Allocate:public Dispatcher {
} }
} }
bool is_assignable(Node *n, bool &is_reference, bool &is_const) { bool is_assignable_type(const SwigType *type) {
bool assignable = true; bool assignable = true;
SwigType *ty = Copy(Getattr(n, "type")); if (SwigType_type(type) == T_USER) {
SwigType_push(ty, Getattr(n, "decl")); Node *cn = Swig_symbol_clookup(type, 0);
SwigType *ftd = SwigType_typedef_resolve_all(ty);
SwigType *td = SwigType_strip_qualifiers(ftd);
if (SwigType_type(td) == T_USER) {
Node *cn = Swig_symbol_clookup(td, 0);
if (cn) { if (cn) {
if ((Strcmp(nodeType(cn), "class") == 0)) { if ((Strcmp(nodeType(cn), "class") == 0)) {
if (Getattr(cn, "allocate:noassign")) { if (Getattr(cn, "allocate:noassign")) {
@ -683,7 +678,20 @@ class Allocate:public Dispatcher {
} }
} }
} }
} else if (SwigType_isarray(type)) {
SwigType *array_type = SwigType_array_type(type);
assignable = is_assignable_type(array_type);
} }
return assignable;
}
bool is_assignable(Node *n, bool &is_reference, bool &is_const) {
SwigType *ty = Copy(Getattr(n, "type"));
SwigType_push(ty, Getattr(n, "decl"));
SwigType *ftd = SwigType_typedef_resolve_all(ty);
SwigType *td = SwigType_strip_qualifiers(ftd);
bool assignable = is_assignable_type(td);
is_reference = SwigType_isreference(td) || SwigType_isrvalue_reference(td); is_reference = SwigType_isreference(td) || SwigType_isrvalue_reference(td);
is_const = !SwigType_ismutable(ftd); is_const = !SwigType_ismutable(ftd);
if (GetFlag(n, "hasconsttype")) if (GetFlag(n, "hasconsttype"))