Fix using declaration in derived class bugs

Problem when all the base class's overloaded methods were
overridden in the derived class - fixes "multiply defined" errors.

Linked lists of the overloaded methods were not set up correctly
when handling the using declaration.

Closes #2244
This commit is contained in:
William S Fulton 2022-03-24 20:52:58 +00:00
parent a343b7e254
commit 469f694ae6
3 changed files with 83 additions and 27 deletions

View File

@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.1.0 (in progress)
===========================
2022-03-24: wsfulton
#2244 Fix using declaration in derived class bugs when all the base
class's overloaded methods were overridden in the derived class -
fixes "multiply defined" errors.
2022-03-23: wsfulton
[Python] #1779 The -py3 option is deprecated and now has no effect on the
code generated. Use of this option results in a deprecated warning.

View File

@ -29,3 +29,57 @@ typedef not working yet
*/
}
%}
%inline %{
// Test using declaration in various positions before and after overloaded methods
// Testing where the derived class overrides all the base class methods (and more)
namespace Bites
{
struct Base
{
virtual ~Base() {}
virtual void grab() {}
virtual void grab(int i) {}
};
struct Derived1 : public Base
{
using Base::grab;
virtual void grab() {}
virtual void grab(int i) {}
};
struct Derived2 : public Base
{
using Base::grab;
virtual void grab() {}
virtual void grab(int i) {}
virtual void grab(int i, double d) {}
};
struct Derived3 : public Base
{
virtual void grab() {}
using Base::grab;
virtual void grab(int i) {}
};
struct Derived4 : public Base
{
virtual void grab() {}
using Base::grab;
virtual void grab(int i) {}
virtual void grab(int i, double d) {}
};
struct Derived5 : public Base
{
virtual void grab() {}
virtual void grab(int i) {}
using Base::grab;
};
struct Derived6 : public Base
{
virtual void grab() {}
virtual void grab(int i) {}
virtual void grab(int i, double d) {}
using Base::grab;
};
}
%}

View File

@ -1159,14 +1159,30 @@ class TypePass:private Dispatcher {
* which is hacked. */
if (Getattr(n, "sym:overloaded")) {
int cnt = 0;
Node *ps = Getattr(n, "sym:previousSibling");
Node *ns = Getattr(n, "sym:nextSibling");
Node *fc = firstChild(n);
Node *firstoverloaded = Getattr(n, "sym:overloaded");
#ifdef DEBUG_OVERLOADED
Node *debugnode = n;
show_overloaded(n);
show_overloaded(firstoverloaded);
#endif
if (!firstChild(n)) {
if (firstoverloaded == n) {
// This 'using' node we are cutting out was the first node in the overloaded list.
// Change the first node in the list
Delattr(firstoverloaded, "sym:overloaded");
firstoverloaded = fc ? fc : ns;
// Correct all the sibling overloaded methods (before adding in new methods)
Node *nnn = ns;
while (nnn) {
Setattr(nnn, "sym:overloaded", firstoverloaded);
nnn = Getattr(nnn, "sym:nextSibling");
}
}
if (!fc) {
// Remove from overloaded list ('using' node does not actually end up adding in any methods)
Node *ps = Getattr(n, "sym:previousSibling");
Node *ns = Getattr(n, "sym:nextSibling");
if (ps) {
Setattr(ps, "sym:nextSibling", ns);
}
@ -1174,24 +1190,8 @@ class TypePass:private Dispatcher {
Setattr(ns, "sym:previousSibling", ps);
}
} else {
// The 'using' node results in methods being added in - slot in the these methods here
Node *ps = Getattr(n, "sym:previousSibling");
Node *ns = Getattr(n, "sym:nextSibling");
Node *fc = firstChild(n);
// The 'using' node results in methods being added in - slot in these methods here
Node *pp = fc;
Node *firstoverloaded = Getattr(n, "sym:overloaded");
if (firstoverloaded == n) {
// This 'using' node we are cutting out was the first node in the overloaded list.
// Change the first node in the list to its first sibling
Delattr(firstoverloaded, "sym:overloaded");
Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
firstoverloaded = fc;
while (nnn) {
Setattr(nnn, "sym:overloaded", firstoverloaded);
nnn = Getattr(nnn, "sym:nextSibling");
}
}
while (pp) {
Node *ppn = Getattr(pp, "sym:nextSibling");
Setattr(pp, "sym:overloaded", firstoverloaded);
@ -1209,18 +1209,15 @@ class TypePass:private Dispatcher {
Setattr(ns, "sym:previousSibling", pp);
Setattr(pp, "sym:nextSibling", ns);
}
#ifdef DEBUG_OVERLOADED
debugnode = firstoverloaded;
#endif
}
Delattr(n, "sym:previousSibling");
Delattr(n, "sym:nextSibling");
Delattr(n, "sym:overloaded");
Delattr(n, "sym:overname");
clean_overloaded(firstoverloaded);
#ifdef DEBUG_OVERLOADED
show_overloaded(debugnode);
show_overloaded(firstoverloaded);
#endif
clean_overloaded(n); // Needed?
}
Delete(n_decl_list);
}