swig/swig-Fix-seg-fault-handling-friend-constructor-destructor.patch
2024-01-23 12:50:48 +01:00

106 lines
3.7 KiB
Diff

From c7ab6a01c6582b92db9328e2f3daa67081f05f6e Mon Sep 17 00:00:00 2001
From: William S Fulton <wsf@fultondesigns.co.uk>
Date: Fri, 12 Jan 2024 08:45:26 +0000
Subject: [PATCH] Fix seg fault handling friend constructor/destructor
declarations
Closes #2749
---
CHANGES.current | 3 ++
Examples/test-suite/friends.i | 34 +++++++++++++++++++++++
Examples/test-suite/php/friends_runme.php | 2 +-
Source/CParse/parser.y | 5 +++-
4 files changed, 42 insertions(+), 2 deletions(-)
#diff --git a/CHANGES.current b/CHANGES.current
#index 030aa0b19..f235d9a09 100644
#--- a/CHANGES.current
#+++ b/CHANGES.current
#@@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
# Version 4.2.1 (in progress)
# ===========================
#
#+2024-01-12: wsfulton
#+ #2749 Fix seg fault handling friend constructor/destructor declarations.
#+
# 2024-01-12: olly
# [Ruby,Tcl] #2751 Fix -external-runtime output to define
# SWIG_snprintf (bug introduced in 4.2.0).
diff --git a/Examples/test-suite/friends.i b/Examples/test-suite/friends.i
index a2a5151e0..879f3b3bc 100644
--- a/Examples/test-suite/friends.i
+++ b/Examples/test-suite/friends.i
@@ -148,6 +148,40 @@
}
}
+%inline %{
+ class CModelParameterSpecies;
+ class CModelParameterCompartment {
+ CModelParameterSpecies *species;
+ public:
+ int getSpeciesVal();
+ CModelParameterCompartment();
+ ~CModelParameterCompartment();
+ };
+ class CModelParameterSpecies
+ {
+ int private_val;
+ public:
+ // Friend function-declarations are silently ignored (including constructor and destructor declarations)
+ friend CModelParameterCompartment::~CModelParameterCompartment();
+ friend CModelParameterCompartment::CModelParameterCompartment();
+ friend int CModelParameterCompartment::getSpeciesVal();
+ };
+%}
+
+%{
+CModelParameterCompartment::~CModelParameterCompartment() {
+ species = new CModelParameterSpecies();
+ species->private_val = 1;
+}
+CModelParameterCompartment::CModelParameterCompartment() {
+ species->private_val = 0;
+ delete species;
+}
+int CModelParameterCompartment::getSpeciesVal() {
+ return species->private_val;
+}
+%}
+
// Use this version with extra qualifiers to test SWIG as some compilers accept this
namespace ns1 {
namespace ns2 {
diff --git a/Examples/test-suite/php/friends_runme.php b/Examples/test-suite/php/friends_runme.php
index f0ef5df58..2e5d3b1fd 100644
--- a/Examples/test-suite/php/friends_runme.php
+++ b/Examples/test-suite/php/friends_runme.php
@@ -3,7 +3,7 @@
require "tests.php";
check::functions(array('globalscope','mix','get_val2','get_val3','bas','baz','bar','get_val1','set'));
-check::classes(array('friends','Foo','A','B','D_i','D_d'));
+check::classes(array('friends','Foo','A','B','D_i','D_d','CModelParameterCompartment','CModelParameterSpecies'));
// No new vars
check::globals(array());
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index e5a79f128..edf38c360 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4732,7 +4732,10 @@ cpp_member : cpp_member_no_dox
*/
cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
- if (inclass || extendmode) {
+ /* Cannot be a constructor declaration/definition if parsed as a friend destructor/constructor
+ or a badly declared friend function without return type */
+ int isfriend = Strstr($1, "friend") != NULL;
+ if (!isfriend && (inclass || extendmode)) {
String *name = SwigType_templateprefix($2); /* A constructor can optionally be declared with template parameters before C++20, strip these off */
SwigType *decl = NewStringEmpty();
$$ = new_node("constructor");
--
2.43.0