summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2023-03-08 19:43:26 +0000
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2023-03-08 19:45:17 +0000
commit4a6f6283aa7e0b15427c60988b0940dc0349f14a (patch)
tree2279eda71872407229b5dd1c3776dc6507187489
parenta92871d9d12f4aa8e82640f157bb7ffdbf138169 (diff)
downloadswig-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.current14
-rw-r--r--Examples/test-suite/common.mk1
-rw-r--r--Examples/test-suite/java/template_type_collapse_runme.java26
-rw-r--r--Examples/test-suite/template_partial_specialization_typedef.i2
-rw-r--r--Examples/test-suite/template_type_collapse.i23
-rw-r--r--Source/Swig/stype.c15
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' */
{