Fix duplicate const in generated code wrapping templates

Fix duplicate const in generated code when template instantiation type is const
and use of template parameter is also explicitly const, such as:

  template <typename T> struct Conster {
    void cccc1(T const& t) {}
  };
  %template(ConsterInt) Conster<const int>;

Above previously led to generated code:
  (arg1)->cccc1((int const const &)*arg2);
instead of
  (arg1)->cccc1((int const &)*arg2);
This commit is contained in:
William S Fulton 2023-03-08 19:43:26 +00:00
parent a92871d9d1
commit 4a6f6283aa
6 changed files with 79 additions and 2 deletions

View File

@ -7,6 +7,20 @@ 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-03-08: wsfulton
Fix duplicate const in generated code when template instantiation type is const
and use of template parameter is also explicitly const, such as:
template <typename T> struct Conster {
void cccc1(T const& t) {}
};
%template(ConsterInt) Conster<const int>;
Above previously led to generated code:
(arg1)->cccc1((int const const &)*arg2);
instead of
(arg1)->cccc1((int const &)*arg2);
2023-03-01: wsfulton 2023-03-01: wsfulton
Partial template specialization fixes to support default arguments from the primary Partial template specialization fixes to support default arguments from the primary
template's parameter list. template's parameter list.

View File

@ -501,6 +501,7 @@ CPP_TEST_CASES += \
template_tbase_template \ template_tbase_template \
template_template_parameters \ template_template_parameters \
template_template_template_parameters \ template_template_template_parameters \
template_type_collapse \
template_typedef \ template_typedef \
template_typedef_class_template \ template_typedef_class_template \
template_typedef_cplx \ template_typedef_cplx \

View File

@ -0,0 +1,26 @@
import template_type_collapse.*;
public class template_type_collapse_runme {
static {
try {
System.loadLibrary("template_type_collapse");
} 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[]) {
int i = 1234;
ConsterInt ci = new DerivedConsterInt();
ci.cccc1(i);
ci.cccc2(i);
ci.cccc3(i);
ci.cccc4(i);
DerivedConsterInt dci = new DerivedConsterInt();
dci.dddd(i);
}
}

View File

@ -93,7 +93,7 @@ namespace Two {
template <typename T1, typename T2> struct TwoParm<T1 *, T2 *> { void b() {} void bbb(const T2 &t) {} }; template <typename T1, typename T2> struct TwoParm<T1 *, T2 *> { void b() {} void bbb(const T2 &t) {} };
template <typename T1, typename T2> struct TwoParm<T1 *, const T2 *> { void c() {} void ccc(const T2 &t) {} }; template <typename T1, typename T2> struct TwoParm<T1 *, const T2 *> { void c() {} void ccc(const T2 &t) {} };
template <typename T1, typename T2> struct TwoParm<const T1 *, const T2 *> { void d() {} void ddd(const T2 &t) {} }; template <typename T1, typename T2> struct TwoParm<const T1 *, const T2 *> { void d() {} void ddd(const T2 &t) {} };
template <typename T1> struct TwoParm<T1 *, int *> { void e() {} /*void eee(const T1 &t) {} TODO */}; template <typename T1> struct TwoParm<T1 *, int *> { void e() {} void eee(const T1 &t) {} };
template <typename T1> struct TwoParm<T1, int> { void f() {} }; template <typename T1> struct TwoParm<T1, int> { void f() {} };
template <> struct TwoParm<int *, const int *> { void g() {} }; template <> struct TwoParm<int *, const int *> { void g() {} };
} }

View File

@ -0,0 +1,23 @@
%module template_type_collapse
// Not attempted yet: reference collapsing
// Tests merging multiple const when instantiating template types
%inline %{
template <typename T> struct Conster {
const T *constptr;
Conster() : constptr() {}
void cccc1(T const& t) {}
void cccc2(const T& t) {}
void cccc3(const T t) {}
void cccc4(T const t) {}
};
template <typename T> struct DerivedConster : Conster<const T> {
const T& dddd(const T& t) {
return t;
}
};
%}
%template(ConsterInt) Conster<const int>;
%template(DerivedConsterInt) DerivedConster<const int>;

View File

@ -1275,6 +1275,11 @@ String *SwigType_manglestr(const SwigType *s) {
* SwigType_typename_replace() * SwigType_typename_replace()
* *
* Replaces a typename in a type with something else. Needed for templates. * Replaces a typename in a type with something else. Needed for templates.
* Collapses duplicate const into a single const.
* Reference collapsing probably should be implemented here.
* Example:
* t=r.q(const).T pat=T rep=int => r.q(const).int
* t=r.q(const).T pat=T rep=q(const).int => r.q(const).int (duplicate const removed)
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
@ -1297,7 +1302,15 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
if (SwigType_issimple(e)) { if (SwigType_issimple(e)) {
if (Equal(e, pat)) { if (Equal(e, pat)) {
/* Replaces a type of the form 'pat' with 'rep<args>' */ /* Replaces a type of the form 'pat' with 'rep<args>' */
Replace(e, pat, rep, DOH_REPLACE_ANY); if (SwigType_isconst(rep) && i > 0 && SwigType_isconst(Getitem(elem, i - 1))) {
/* Collapse duplicate const into a single const */
SwigType *rep_without_const = Copy(rep);
Delete(SwigType_pop(rep_without_const));
Replace(e, pat, rep_without_const, DOH_REPLACE_ANY);
Delete(rep_without_const);
} else {
Replace(e, pat, rep, DOH_REPLACE_ANY);
}
} else if (SwigType_istemplate(e)) { } else if (SwigType_istemplate(e)) {
/* Replaces a type of the form 'pat<args>' with 'rep' */ /* Replaces a type of the form 'pat<args>' with 'rep' */
{ {