From 5c5911ee3b9a35ed8785bd0b0a3d97b7d6364ad4 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 19 Sep 2024 19:46:20 +0100 Subject: [PATCH] Assignable fixes for reference member variables Fix incorrect variable setters being generated when wrapping reference member variables. A setter is no longer generated if the type of the reference member variable is non-assignable. Fixes #2866 --- CHANGES.current | 5 ++ Examples/test-suite/cpp11_assign_delete.i | 50 +++++++++++++++++++ .../java/cpp11_assign_delete_runme.java | 26 ++++++++++ Source/Modules/allocate.cxx | 5 ++ 4 files changed, 86 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 42ffb9113..73e11688b 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.3.0 (in progress) =========================== +2024-09-19: wsfulton + #2866 Fix incorrect variable setters being generated when wrapping + reference member variables. A setter is no longer generated if the + type of the reference member variable is non-assignable. + 2024-09-18: olly Fix parse error for a misplaced Doxygen comment which is the only thing in a class/struct. diff --git a/Examples/test-suite/cpp11_assign_delete.i b/Examples/test-suite/cpp11_assign_delete.i index dd2b180e7..3ea9a9094 100644 --- a/Examples/test-suite/cpp11_assign_delete.i +++ b/Examples/test-suite/cpp11_assign_delete.i @@ -170,3 +170,53 @@ struct StaticMembersMemberArrayVarsHolder { }; StaticMembersMemberArrayVars GlobalStaticMembersMemberArrayVars; %} + +// (5) Test indirectly non-assignable member variables via classes that themselves have non-assignable reference member variables +%inline %{ +AssignPublic GlobalAssignPublic; +AssignProtected GlobalAssignProtected; +AssignPrivate GlobalAssignPrivate; + +struct MemberPublicRefVar { + AssignPublic& MemberRefVarPublic; + MemberPublicRefVar() : MemberRefVarPublic(GlobalAssignPublic) {} +}; + +struct MemberProtectedRefVar { + MemberProtectedRefVar() : MemberRefVarProtected(GlobalAssignProtected) {} +protected: + AssignProtected& MemberRefVarProtected; +}; + +struct MemberPrivateRefVar { + MemberPrivateRefVar() : MemberRefVarPrivate(GlobalAssignPrivate) {} +private: + AssignPrivate& MemberRefVarPrivate; +}; + +struct MembersMemberRefVars { + // These will only have getters + MemberPublicRefVar MemberPublic; + MemberProtectedRefVar MemberProtected; + MemberPrivateRefVar MemberPrivate; +}; + +struct StaticMembersMemberRefVars { + static MemberPublicRefVar StaticMemberPublic; + static MemberProtectedRefVar StaticMemberProtected; + static MemberPrivateRefVar StaticMemberPrivate; +}; +MemberPublicRefVar StaticMembersMemberRefVars::StaticMemberPublic; +MemberProtectedRefVar StaticMembersMemberRefVars::StaticMemberProtected; +MemberPrivateRefVar StaticMembersMemberRefVars::StaticMemberPrivate; + +MemberPublicRefVar GlobalRefMemberPublic; +MemberProtectedRefVar GlobalRefMemberProtected; +MemberPrivateRefVar GlobalRefMemberPrivate; + +// Setters and getters available +struct StaticMembersMemberRefVarsHolder { + StaticMembersMemberRefVars Member; +}; +StaticMembersMemberRefVars GlobalStaticMembersMemberRefVars; +%} diff --git a/Examples/test-suite/java/cpp11_assign_delete_runme.java b/Examples/test-suite/java/cpp11_assign_delete_runme.java index c15632457..cbee1bf97 100644 --- a/Examples/test-suite/java/cpp11_assign_delete_runme.java +++ b/Examples/test-suite/java/cpp11_assign_delete_runme.java @@ -114,5 +114,31 @@ public class cpp11_assign_delete_runme { StaticMembersMemberArrayVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberArrayVars(); cpp11_assign_delete.setGlobalStaticMembersMemberArrayVars(smmv); } + + // (5) Test indirectly non-assignable member variables via classes that themselves have non-assignable reference member variables + { + MembersMemberRefVars m = new MembersMemberRefVars(); + + // These will only have getters + MemberPublicRefVar mpv1 = m.getMemberPublic(); + MemberProtectedRefVar mpv2 = m.getMemberProtected(); + MemberPrivateRefVar mpv3 = m.getMemberPrivate(); + + MemberPublicRefVar smpv1 = StaticMembersMemberRefVars.getStaticMemberPublic(); + MemberProtectedRefVar smpv2 = StaticMembersMemberRefVars.getStaticMemberProtected(); + MemberPrivateRefVar smpv3 = StaticMembersMemberRefVars.getStaticMemberPrivate(); + + MemberPublicRefVar gmpv1 = cpp11_assign_delete.getGlobalRefMemberPublic(); + MemberProtectedRefVar gmpv2 = cpp11_assign_delete.getGlobalRefMemberProtected(); + MemberPrivateRefVar gmpv3 = cpp11_assign_delete.getGlobalRefMemberPrivate(); + + // Setters and getters available + StaticMembersMemberRefVarsHolder smmvh = new StaticMembersMemberRefVarsHolder(); + StaticMembersMemberRefVars member = smmvh.getMember(); + smmvh.setMember(member); + + StaticMembersMemberRefVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberRefVars(); + cpp11_assign_delete.setGlobalStaticMembersMemberRefVars(smmv); + } } } diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index bdcef810c..efc57772a 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -692,6 +692,11 @@ class Allocate:public Dispatcher { } else if (SwigType_isarray(type)) { SwigType *array_type = SwigType_array_type(type); assignable = is_assignable_type(array_type); + } else if (SwigType_isreference(type) || SwigType_isrvalue_reference(type)) { + SwigType *base_type = Copy(type); + SwigType_del_element(base_type); + assignable = is_assignable_type(base_type); + Delete(base_type); } return assignable; }