mirror of https://github.com/swig/swig
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:
parent
d4abe14f7e
commit
650aad82ed
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
%}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
Loading…
Reference in New Issue