<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 - wrong code for -O of attribute(const or pure) for overriden virtual base class method"
   href="https://bugs.llvm.org/show_bug.cgi?id=50866">50866</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>wrong code for -O of attribute(const or pure) for overriden virtual base class method
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

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

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

        <tr>
          <th>OS</th>
          <td>Linux
          </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>new bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>jan.kratochvil@redhat.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>#include <iostream>
struct A {
  virtual int c() __attribute__ ((const));
  virtual int p() __attribute__ ((pure ));
};
struct B : public A {
  virtual int c() override;
  virtual int p() override;
};
int A::c() { std::cout << "A::c()\n"; return 0x01; }
int A::p() { std::cout << "A::p()\n"; return 0x04; }
int B::c() { std::cout << "B::c()\n"; return 0x10; }
int B::p() { std::cout << "B::p()\n"; return 0x40; }
int main() {
  B b;
  A &a(b);
  return a.c() + a.c() + a.p() + a.p(); // 160==0xa0==0x10+0x10+0x40+0x40
}
-------------------------------------------------------------------------
for i in g++ clang++;do $i -o virtone virtone.C -Wall -g -O;./virtone;echo
$?;done
-------------------------------------------------------------------------
PASS: gcc-11.1.1-3.fc34.x86_64
B::c()
B::c()
B::p()
B::p()
160
-------------------------------------------------------------------------
FAIL: clang-12.0.0-2.fc34.x86_64
FAIL: clang version 13.0.0 91053e327ccd27cb1ee66a7d4954d456ceeed5f6
      Target: x86_64-unknown-linux-gnu
B::c()
B::p()
160
-------------------------------------------------------------------------
It is discussed here but I see no conclusion there:
  <a href="https://stackoverflow.com/a/18394716/2995591">https://stackoverflow.com/a/18394716/2995591</a>
The GCC behavior looks more useful to me.
The clang behavior is dangerous. One must make any 'const' or 'pure' virtual
methods also 'final' to be safe for future. If they cannot be 'final' one must
not use 'const'/'pure' for the base class method even despite it could be
useful.</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>