From 031dc2268627919ff512fa5cbf81d39900790159 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 16 Jun 2024 19:11:11 +0100 Subject: [PATCH] Don't ignore overloaded friend functions that are also declared constexpr Closes #2927 --- CHANGES.current | 4 +++ Examples/test-suite/common.mk | 1 + Examples/test-suite/cpp11_constexpr_friend.i | 35 +++++++++++++++++++ .../csharp/cpp11_constexpr_friend_runme.cs | 20 +++++++++++ Source/CParse/parser.y | 2 +- 5 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 Examples/test-suite/cpp11_constexpr_friend.i create mode 100644 Examples/test-suite/csharp/cpp11_constexpr_friend_runme.cs diff --git a/CHANGES.current b/CHANGES.current index f5f7fa155..2eda2d853 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/ Version 4.3.0 (in progress) =========================== +2024-06-16: wsfulton + #2927 Don't ignore overloaded friend functions that are also declared + constexpr. + 2024-06-15: wsfulton [Python] Removed deprecated pytuplehlp.swg file and t_output_helper. Use SWIG_Python_AppendOutput instead of t_output_helper. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 79f154b25..c380e47de 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -615,6 +615,7 @@ CPP11_TEST_CASES += \ cpp11_auto_variable \ cpp11_brackets_expression \ cpp11_constexpr \ + cpp11_constexpr_friend \ cpp11_copyctor_delete \ cpp11_decltype \ cpp11_default_delete \ diff --git a/Examples/test-suite/cpp11_constexpr_friend.i b/Examples/test-suite/cpp11_constexpr_friend.i new file mode 100644 index 000000000..c1d3872e9 --- /dev/null +++ b/Examples/test-suite/cpp11_constexpr_friend.i @@ -0,0 +1,35 @@ +%module cpp11_constexpr_friend + +%rename("isEqual") operator==(FriendA const& lhs, FriendA const& rhs) noexcept; +%rename("isEqual") operator==(FriendB const& lhs, FriendB const& rhs) noexcept; + +%inline %{ + class FriendA final + { + public: + FriendA(int const v) noexcept : _v(v) + { + } + + constexpr friend bool operator==(FriendA const& lhs, FriendA const& rhs) noexcept + { + return lhs._v == rhs._v; + } + private: + int _v{}; + }; + class FriendB final + { + public: + FriendB(int const v) noexcept : _v(v) + { + } + + constexpr friend bool operator==(FriendB const& lhs, FriendB const& rhs) noexcept + { + return lhs._v == rhs._v; + } + private: + int _v{}; + }; +%} diff --git a/Examples/test-suite/csharp/cpp11_constexpr_friend_runme.cs b/Examples/test-suite/csharp/cpp11_constexpr_friend_runme.cs new file mode 100644 index 000000000..adc6c6dba --- /dev/null +++ b/Examples/test-suite/csharp/cpp11_constexpr_friend_runme.cs @@ -0,0 +1,20 @@ +using System; +using cpp11_constexpr_friendNamespace; + +public class cpp11_constexpr_friend_runme { + public static void Main() { + FriendA fa10 = new FriendA(10); + FriendA fa20 = new FriendA(20); + if (!cpp11_constexpr_friend.isEqual(fa10, fa10)) + throw new Exception("Friend fa10 fa10 fail"); + if (cpp11_constexpr_friend.isEqual(fa10, fa20)) + throw new Exception("Friend fa10 fa20 fail"); + + FriendB fb10 = new FriendB(10); + FriendB fb20 = new FriendB(20); + if (!cpp11_constexpr_friend.isEqual(fb10, fb10)) + throw new Exception("Friend fb10 fb10 fail"); + if (cpp11_constexpr_friend.isEqual(fb10, fb20)) + throw new Exception("Friend fb10 fb20 fail"); + } +} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 1593df2ff..c1e3faa36 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -420,7 +420,7 @@ static void add_symbols(Node *n) { String *symname = 0; String *old_prefix = 0; Symtab *old_scope = 0; - int isfriend = inclass && Checkattr(n, "storage", "friend"); + int isfriend = inclass && Strstr(Getattr(n, "storage"), "friend") != NULL; int iscdecl = Cmp(nodeType(n),"cdecl") == 0; int only_csymbol = 0;