[llvm-bugs] [Bug 41065] New: In some circumstances the clang_cl for windows doesn't generate default virtual destructor for the derived class with "/O2" and "/EHsc" flags

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Mar 14 06:29:10 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=41065

            Bug ID: 41065
           Summary: In some circumstances the clang_cl for windows doesn't
                    generate default virtual destructor for the derived
                    class with "/O2" and "/EHsc"  flags
           Product: clang
           Version: 7.0
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: Vladimir.konobeev at forcepoint.com
                CC: blitzrakete at gmail.com, dgregor at apple.com,
                    erik.pilkington at gmail.com, llvm-bugs at lists.llvm.org,
                    richard-llvm at metafoo.co.uk

Created attachment 21594
  --> https://bugs.llvm.org/attachment.cgi?id=21594&action=edit
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 at 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;
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190314/3c517559/attachment-0001.html>


More information about the llvm-bugs mailing list