<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 - In some circumstances the clang_cl for windows doesn't generate default virtual destructor for the derived class with "/O2" and "/EHsc" flags"
   href="https://bugs.llvm.org/show_bug.cgi?id=41065">41065</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>In some circumstances the clang_cl for windows doesn't generate default virtual destructor for the derived class with "/O2" and "/EHsc"  flags
          </td>
        </tr>

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

        <tr>
          <th>Version</th>
          <td>7.0
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>Windows NT
          </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>Vladimir.konobeev@forcepoint.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>Created <span class=""><a href="attachment.cgi?id=21594" name="attach_21594" title="a simple test program (needs to edit the /libpath!)">attachment 21594</a> <a href="attachment.cgi?id=21594&action=edit" title="a simple test program (needs to edit the /libpath!)">[details]</a></span>
a simple test program (needs to edit the /libpath!)

This bug is specific to Windows version of clang-cl
It is not reproducible on linux or macOS.

clang version 7.0.1 (tags/RELEASE_701/final)
Target: x86_64-pc-windows-msvc
Thread model: posix

When building c++ code on windows and using these two flags together: "/O2" and
"/EHsc"  (code optimization + exception handling)

In some specific cases the clang doesn't generate the default virtual
destructor for the derived class:

lld-link.exe: error: undefined symbol: ??1derived_class@@UEAA@XZ
public: virtual __cdecl derived_class::~derived_class(void) __ptr64

My analysis:
Due to exception handling mechanism the compiler adds the invocation of the  
'~derived_class' virtual destructor  to 'derived2_class' constructor.
but it doesn't implement the destructor due to code optimization

I've attached the source code and the build script (to make it build it needs
to edit the /libpath)

Also adding sources here (the sources needs to be compiled with "/O2 /EHsc")
----------base_class.h-------------
#pragma once 

class base_class
{
public:
    base_class(int n);
    virtual void fn() = 0;
    virtual ~base_class();
};
----------base_class.cpp-----------
#include "base_class.h"

base_class::base_class(int) {}
base_class::~base_class() {}
---------derived_class.h------------
#pragma once
#include "base_class.h"

class derived_class : public base_class
{
public: 
derived_class(int n );
};
---------derived_class.cpp------------
#include "derived_class.h"
derived_class::derived_class(int n) : base_class(n) {}
---------derived2_class.h-------------
#pragma once
#include "derived_class.h"
#include <string>

class derived2_class : public virtual derived_class
{
public:
    derived2_class(const std::string& s);
private:
    std::string m_str;
};
---------derived2_class.cpp-------------
#include "derived2_class.h"
#include <string>
#include <iostream>

derived2_class::derived2_class(const std::string& s) : derived_class(10),
m_str(s) {}

---------topmost_class.h-------------
#pragma once 
#include "derived2_class.h"

class topmost_class : public derived2_class
{
public:
    virtual void fn();
    topmost_class(const std::string& s, int n);
};
---------topmost_class.cpp-------------
#include "topmost_class.h"
#include <string>
#include <iostream>

void topmost_class::fn() { std::cout << "fn" << std::endl; }
topmost_class::topmost_class(const std::string& s, int n) : derived_class(n),
derived2_class(s) {}
------------test.cpp---------------------
#include <string>
#include <iostream>
#include "topmost_class.h"

int main()
{
    std::string ss;
    topmost_class c(ss, 10);
    return 0;
}</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>