<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - using declaration on method with multiple inheritance disables virtual call to overridden method"
   href="https://bugs.llvm.org/show_bug.cgi?id=42211">42211</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>using declaration on method with multiple inheritance disables virtual call to overridden method
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>michalbreiter@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Following test case produces different result for clang and other compilers
that I tested. I believe it's bug in clang.

// start
#include <iostream>

struct A {
    virtual void foo() {
        std::cout << "A\n";
    }
};

struct B : virtual A {};

struct C : virtual A {
    void foo() override {
        std::cout << "C\n";
    }   
};

struct D : B, C {
    using A::foo;
};

int main() {
    D d;
    d.foo();

    A &a = d;
    a.foo();

    return 0;
}
// end

On clang (4.0 - 8.0 and trunk on godbolt) output is:
<span class="quote">> A
> C</span >

gcc (versions 4.8.1 - 9.1), icc (versions 16, 17, 19), Visual Studio 2017
15.4.0 Preview 1.0, Visual Studio 2013 12.0.31101.00 Update 4, clang (versions
3.4.1 - 3.9.1)
all give following output, which is what I expect:
<span class="quote">> C
> C</span >

It seems that only for first derived class (B in this example) foo is called
using virtual call. Base method is used only if called through D object. When
called through reference to A, method from C is used.
If I derive from more classes than B and C, it will behave the same for them as
for C - method from A will be called.

If 'using A::foo' is removed, both calls are made to C::foo.

Fix for this is very important for me because it's hard to identify where such
construction is used in real code and I have to and want to use gcc and clang
for project I'm working on. Only way that I can think of, to find if similar
construction is in more places in codebase is writing AST matcher and writing
some workaround for found cases.


Discussion with bigger example on stackoverflow:
<a href="https://stackoverflow.com/questions/56452518/virtual-function-overloading-in-diamond-hierarchy-produces-different-results-in">https://stackoverflow.com/questions/56452518/virtual-function-overloading-in-diamond-hierarchy-produces-different-results-in</a></pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>