Skip to content

Commit e300b7d

Browse files
committed
Fix friends test (edge case for subroutine conflict detection)
1 parent 405eaa9 commit e300b7d

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

Examples/test-suite/fortran/Makefile.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ C_TEST_CASES = \
3737

3838
FAILING_CPP_TESTS += \
3939
contract \
40-
friends \
4140
global_scope_types \
4241
grouping \
4342
member_funcptr_galore \

Source/Modules/fortran.cxx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,16 @@ bool is_wrapped_enum(Node *n) {
188188
return !GetFlag(n, "enumMissing") && GetFlag(n, "fortran:declared");
189189
}
190190

191+
/* -------------------------------------------------------------------------
192+
* \brief Get the special string value corresponding to whether a function is
193+
* a void return type (subroutine)
194+
*/
195+
String *subroutine_flag_str(bool is_subroutine) {
196+
static String *is_subroutine_flag = NewString("is subroutine");
197+
static String *not_subroutine_flag = NewString("is function");
198+
return is_subroutine ? is_subroutine_flag : not_subroutine_flag;
199+
}
200+
191201
/* -------------------------------------------------------------------------
192202
* \brief Whether an SWIG type can be rendered as TYPE VAR.
193203
*
@@ -1592,14 +1602,10 @@ Wrapper *FORTRAN::proxyfuncWrapper(Node *n) {
15921602
Node *conflicting_subroutine = NULL;
15931603

15941604
Node *overridden = Getattr(n, "fortran:override");
1595-
if (overridden) {
1596-
bool is_parent_subroutine = Getattr(overridden, "fortran:subroutine");
1597-
if (Getattr(n, "fortran:variable") && Getattr(overridden, "fortran:variable")) {
1598-
// Since variables can get wrapped twice (for getters and setters), pretend
1599-
// that the parent procedure is like this one
1600-
is_parent_subroutine = is_fsubroutine;
1601-
}
1602-
if (is_parent_subroutine != is_fsubroutine) {
1605+
if (overridden && !(Getattr(n, "fortran:variable") && Getattr(overridden, "fortran:variable"))) {
1606+
// Overridden, but *not* a variable, which can get wrapped twice (for getters and setters)
1607+
String *is_parent_subroutine = Getattr(overridden, "fortran:subroutine");
1608+
if (is_parent_subroutine != NULL && is_parent_subroutine != subroutine_flag_str(is_fsubroutine)) {
16031609
// The parent procedure's return value conflicts with this one. (Perhaps the
16041610
// conversion feature was applied only to the parent class, or a weird
16051611
// typemap is in play?)
@@ -1608,12 +1614,14 @@ Wrapper *FORTRAN::proxyfuncWrapper(Node *n) {
16081614
}
16091615

16101616
if (Node *overload = Getattr(n, "sym:overloaded")) {
1611-
while (overload && GetFlag(overload, "fortran:ignore")) {
1617+
// Skip ignored overloads or uninstantiated overloads (friend functions implicitly instantiated
1618+
// in a templated struct, see friends.i)
1619+
while (overload && (GetFlag(overload, "fortran:ignore") || !Getattr(overload, "fortran:subroutine"))) {
16121620
overload = Getattr(overload, "sym:nextSibling");
16131621
}
16141622
if (overload && overload != n) {
1615-
bool is_sibling_fsubroutine = Getattr(overload, "fortran:subroutine");
1616-
if (is_sibling_fsubroutine != is_fsubroutine) {
1623+
String *is_sibling_fsubroutine = Getattr(overload, "fortran:subroutine");
1624+
if (!Equal(is_sibling_fsubroutine, subroutine_flag_str(is_fsubroutine))) {
16171625
// The parent procedure's return value conflicts with this one. (Perhaps the
16181626
// conversion feature was applied only to the parent class, or a weird
16191627
// typemap is in play?)
@@ -1628,10 +1636,8 @@ Wrapper *FORTRAN::proxyfuncWrapper(Node *n) {
16281636
// functions.
16291637
is_fsubroutine = (is_fsubroutine || func_to_subroutine) && !conflicting_subroutine;
16301638

1631-
if (is_fsubroutine) {
1632-
// Before possibly returning, save whether we're a subroutine in case of other overloads
1633-
Setattr(n, "fortran:subroutine", n);
1634-
}
1639+
// Before possibly returning, save whether we're a subroutine in case of other overloads
1640+
Setattr(n, "fortran:subroutine", subroutine_flag_str(is_fsubroutine));
16351641

16361642
if (conflicting_subroutine) {
16371643
// An already-wrapped overloaded function already has been declared as

0 commit comments

Comments
 (0)