diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2023-03-08 19:43:26 +0000 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2023-03-08 19:45:17 +0000 |
commit | 4a6f6283aa7e0b15427c60988b0940dc0349f14a (patch) | |
tree | 2279eda71872407229b5dd1c3776dc6507187489 | |
parent | a92871d9d12f4aa8e82640f157bb7ffdbf138169 (diff) | |
download | swig-4a6f6283aa7e0b15427c60988b0940dc0349f14a.tar.gz |
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);
-rw-r--r-- | CHANGES.current | 14 | ||||
-rw-r--r-- | Examples/test-suite/common.mk | 1 | ||||
-rw-r--r-- | Examples/test-suite/java/template_type_collapse_runme.java | 26 | ||||
-rw-r--r-- | Examples/test-suite/template_partial_specialization_typedef.i | 2 | ||||
-rw-r--r-- | Examples/test-suite/template_type_collapse.i | 23 | ||||
-rw-r--r-- | Source/Swig/stype.c | 15 |
6 files changed, 79 insertions, 2 deletions
diff --git a/CHANGES.current b/CHANGES.current index f0b916be0..ea3e81022 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -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) =========================== +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 Partial template specialization fixes to support default arguments from the primary template's parameter list. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index ff9b8538f..eb80977f7 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -501,6 +501,7 @@ CPP_TEST_CASES += \ template_tbase_template \ template_template_parameters \ template_template_template_parameters \ + template_type_collapse \ template_typedef \ template_typedef_class_template \ template_typedef_cplx \ diff --git a/Examples/test-suite/java/template_type_collapse_runme.java b/Examples/test-suite/java/template_type_collapse_runme.java new file mode 100644 index 000000000..11c6c8c5e --- /dev/null +++ b/Examples/test-suite/java/template_type_collapse_runme.java @@ -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); + } +} + diff --git a/Examples/test-suite/template_partial_specialization_typedef.i b/Examples/test-suite/template_partial_specialization_typedef.i index 04475da1a..ad3457afe 100644 --- a/Examples/test-suite/template_partial_specialization_typedef.i +++ b/Examples/test-suite/template_partial_specialization_typedef.i @@ -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 *, 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> 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 <> struct TwoParm<int *, const int *> { void g() {} }; } diff --git a/Examples/test-suite/template_type_collapse.i b/Examples/test-suite/template_type_collapse.i new file mode 100644 index 000000000..f6459db36 --- /dev/null +++ b/Examples/test-suite/template_type_collapse.i @@ -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>; + diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index e9cbf7b43..7a7b727a2 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -1275,6 +1275,11 @@ String *SwigType_manglestr(const SwigType *s) { * SwigType_typename_replace() * * 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) { @@ -1297,7 +1302,15 @@ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { if (SwigType_issimple(e)) { if (Equal(e, pat)) { /* 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)) { /* Replaces a type of the form 'pat<args>' with 'rep' */ { |