Fix duplicate sym:overname values using %copyctor

The sym:overname attribute was not being updated when templates were
included in the list of overloaded methods/constructors, leading to
duplicate target language symbols in some language like java/csharp.

Closes #2541
This commit is contained in:
William S Fulton 2023-07-29 00:05:58 +01:00
parent 705d5b875a
commit 5e1a37c6c5
8 changed files with 96 additions and 13 deletions

View File

@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.2.0 (in progress)
===========================
2023-07-28: wsfulton
[#2541] Fix overloading of templated constructors and %copyctor.
2023-07-21: wsfulton
Don't generate a default constructor wrapper when a class has a
templated constructor, as there isn't actually an implied default

View File

@ -160,6 +160,7 @@ CPP_TEST_CASES += \
conversion_namespace \
conversion_ns_template \
conversion_operators \
copyctor \
cplusplus_throw \
cpp_basic \
cpp_enum \

View File

@ -0,0 +1,22 @@
%module copyctor
%copyctor;
%inline %{
struct Bar {};
struct Car {};
struct Foo {
Foo() {}
template <class T> Foo(const T* p) {}
Foo(const Bar& other) {}
};
struct Hoo {
Hoo() {}
template <class T> Hoo(const T* p) {}
Hoo(const Bar& other) {}
};
%}
%template(Hoo) Hoo::Hoo<Car>;

View File

@ -0,0 +1,27 @@
import copyctor.*;
public class copyctor_runme {
static {
try {
System.loadLibrary("copyctor");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
Bar bar = new Bar();
bar = new Bar(bar);
Foo foo = new Foo();
foo = new Foo(bar);
Car car = new Car();
Hoo hoo = new Hoo();
hoo = new Hoo(bar);
hoo = new Hoo(car);
}
}

View File

@ -0,0 +1,13 @@
from copyctor import *
bar = Bar()
bar = Bar(bar)
foo = Foo()
foo = Foo(bar)
car = Car()
hoo = Hoo()
hoo = Hoo(bar)
hoo = Hoo(car)

View File

@ -66,7 +66,11 @@ int is_non_virtual_protected_access(Node *n) {
return result;
}
/* Clean overloaded list. Removes templates, ignored, and errors */
/* -----------------------------------------------------------------------------
* clean_overloaded()
*
* Clean overloaded list. Removes templates, ignored, and errors.
* ----------------------------------------------------------------------------- */
void clean_overloaded(Node *n) {
Node *nn = Getattr(n, "sym:overloaded");
@ -89,6 +93,7 @@ void clean_overloaded(Node *n) {
Delattr(nn, "sym:previousSibling");
Delattr(nn, "sym:nextSibling");
Delattr(nn, "sym:overloaded");
Delattr(nn, "sym:overname");
nn = ns;
continue;
} else {
@ -102,6 +107,8 @@ void clean_overloaded(Node *n) {
if (Getattr(n, "sym:overloaded"))
Delattr(n, "sym:overloaded");
}
// Swig_symbol_fix_overname(Getattr(n, "sym:overloaded"));
}
/* -----------------------------------------------------------------------------

View File

@ -230,18 +230,19 @@ extern "C" {
extern Symtab *Swig_symbol_global_scope(void);
extern Symtab *Swig_symbol_current(void);
extern Symtab *Swig_symbol_popscope(void);
extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node);
extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n);
extern void Swig_symbol_conflict_warn(Node *n, Node *c, const String *symname, int inclass);
extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node);
extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *n);
extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n);
extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
extern String *Swig_symbol_qualified(Node *node);
extern Node *Swig_symbol_isoverloaded(Node *node);
extern void Swig_symbol_remove(Node *node);
extern String *Swig_symbol_qualified(Node *n);
extern Node *Swig_symbol_isoverloaded(Node *n);
extern void Swig_symbol_remove(Node *n);
extern void Swig_symbol_fix_overname(Node *n);
extern void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *tab);
extern void Swig_symbol_inherit(Symtab *tab);
extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab);

View File

@ -1475,7 +1475,6 @@ Symtab *Swig_symbol_cscope(const_String_or_char_ptr name, Symtab *symtab) {
void Swig_symbol_remove(Node *n) {
Symtab *symtab;
String *symname;
String *overname;
Node *symprev;
Node *symnext;
Node *fixovername = 0;
@ -1517,11 +1516,22 @@ void Swig_symbol_remove(Node *n) {
Delattr(n, "sym:overname");
Delattr(n, "csym:previousSibling");
Delattr(n, "sym:overloaded");
n = 0;
if (fixovername) {
Node *nn = fixovername;
Node *head = fixovername;
Swig_symbol_fix_overname(fixovername);
}
/* -----------------------------------------------------------------------------
* Swig_symbol_fix_overname()
*
* Fix/update the sym:overname attribute for all the overloaded names.
* The sym:overname attributes are changed to start from zero, eg __SWIG_0.
* Call this when the linked lists for overloaded methods are modified.
* ----------------------------------------------------------------------------- */
void Swig_symbol_fix_overname(Node *n) {
if (n) {
Node *nn = n;
Node *head = n;
int pn = 0;
/* find head of linked list */
@ -1533,9 +1543,8 @@ void Swig_symbol_remove(Node *n) {
/* adjust all the sym:overname strings to start from 0 and increment by one */
nn = head;
while (nn) {
assert(Getattr(nn, "sym:overname"));
String *overname = NewStringf("__SWIG_%d", pn);
Delattr(nn, "sym:overname");
overname = NewStringf("__SWIG_%d", pn);
Setattr(nn, "sym:overname", overname);
Delete(overname);
pn++;