The following test illustrates a problem I discovered while re-writing
/ extending the existing test suite for Inline::CPP.  In this case the
test is part of the Inline::CPP::grammar test lineup.

It seems that when a class uses multiple inheritance there is a bug
wherein the wrong inherited member function binds to the wrong name.
The bug is sensitive to the order in which parent classes are listed
in the inheritance declaration.  ...strange stuff...

# 11minhrt.t

use Test::More;

use Inline CPP;

# Test 1.
is(
    Parent1->new->do_something, 51,
    "Multiple inheritance: Parent1 instantiated, own member function called."
);

# Test 2.
is(
    Parent2->new->do_another, 17,
    "Multiple inheritance: Parent2 instantiated, own member function called."
);

# Test 3.
is(
    Child->new->yet_another, 3,
    "Child inheriting from Parent1, Parent2: instantiate and call own member."
);

# Test 4.
is(
    Child->new->do_something, 51,
    "Child inherited do_something() member function from Parent1"
);

# Test 5.
is(
    Child2->new->some_other, 4,
    "Child2 instantiated and calls own member function some_other()"
);

# Test 6.
is(
    Child2->new->do_another, 17,
    "Child2 inherits do_another() member function from Parent2"
);

TODO: {

    local $TODO = "Inherited method call resolution finding wrong method.";
# Test 7.
    is(
        Child->new->do_another(), 17,
        "Child inherited member function do_another() from Parent2"
    );

# Test 8.
    is(
        Child2->new->do_something(), 51,
        "Child inherited member function do_something() from Parent1"
    );
}

done_testing();

__END__
__CPP__

class Parent1 {
  public:
    Parent1() { }
    ~Parent1() { }

    virtual int do_something() { return 51; }
};

class Parent2 {
  public:
    Parent2();
    ~Parent2();

    virtual int do_another();
};

Parent2::Parent2() { }
Parent2::~Parent2() { }
int Parent2::do_another() { return 17; }

class Child : public Parent1, public Parent2 {
  public:
    Child() { }
    ~Child() { }

    int yet_another() { return 3; }
};

class Child2 : public Parent2, public Parent1 {
  public:
    Child2() { }
    ~Child2() { }

    int some_other() { return 4; }
};

*** And the output ***

ok 1 - Multiple inheritance: Parent1 instantiated, own member function called.
ok 2 - Multiple inheritance: Parent2 instantiated, own member function called.
ok 3 - Child inheriting from Parent1, Parent2: instantiate and call own member.
ok 4 - Child inherited do_something() member function from Parent1
ok 5 - Child2 instantiated and calls own member function some_other()
ok 6 - Child2 inherits do_another() member function from Parent2
not ok 7 - Child inherited member function do_another() from Parent2 #
TODO Inherited method call resolution finding wrong method.
#   Failed (TODO) test 'Child inherited member function do_another()
from Parent2'
#   at grammar/t/11minhrt.t line 48.
#          got: '51'
#     expected: '17'
not ok 8 - Child inherited member function do_something() from Parent1
# TODO Inherited method call resolution finding wrong method.
#   Failed (TODO) test 'Child inherited member function do_something()
from Parent1'
#   at grammar/t/11minhrt.t line 54.
#          got: '17'
#     expected: '51'
1..8

I'm just beginning to come to terms with how the Parse::RecDescent
grammar works, and I'm not "there yet" on understanding how it deals
with multiple inheritance.  If anyone has any ideas on this I'd be
much obliged.

This test is included in the "tests" branch of my Inline::CPP github
repo: g...@github.com:daoswald/Inline-CPP.git

I'm using the 'tests' branch to explore building a more robust test
suite.  ...and apparently it's paying off as it led me to discover
this issue.

Neil: I'm CC'ing you out of a long-shot hope that you might remember
enough about how grammar.pm deals with multiple inheritance to spot
the problem.

Dave

-- 

David Oswald
daosw...@gmail.com

Reply via email to