[llvm-bugs] [Bug 50570] New: Clang either crashes or choose wrong destructor when using multiple destructors using C++20 constraints

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Jun 3 06:00:57 PDT 2021


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

            Bug ID: 50570
           Summary: Clang either crashes or choose wrong destructor when
                    using multiple destructors using C++20 constraints
           Product: clang
           Version: trunk
          Hardware: All
                OS: All
            Status: NEW
          Severity: release blocker
          Priority: P
         Component: C++2a
          Assignee: unassignedclangbugs at nondot.org
          Reporter: kashishnagpal0007 at gmail.com
                CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
                    llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk

Created attachment 24905
  --> https://bugs.llvm.org/attachment.cgi?id=24905&action=edit
1 of the program which i described above (also have links to godbolt)

Overview: When we use multiple destructor (1 default and 1 constraint 1) ,
using just a simple constraint, then 1 of 2 things happen:




A.) If we define the constraint destructor first, and then define default
destructor:

https://godbolt.org/z/PWbfzscs4


#include <iostream>
#include <concepts>

template <typename T>
concept hasReleaseMethod = requires(T t)
{
        t.release();
};

template <typename T>
class ComWrapper
{
        T t;

  public:
        ~ComWrapper() requires requires(T t) { t.release(); }
        {
                std::cout << "destructor";
                t.release();
        }

        ~ComWrapper() = default;
};

struct hasRelease
{
        int a = 23;
        void release()
        {
                std::cout << "in release method:\n"
                                  << a;
        }
        void method()
        {
        }
};

struct notHadRelease
{
};

int main()
{
        ComWrapper<hasRelease> Ob;
        ComWrapper<notHadRelease> ob2;
};

Actual result: the compiler crashed (you can see the error through the cooler l
compiler explorer (godbolt)).

Expected result: the clang should choose the constraint destructor on ob1
(hasRelease) and default destructor on ob2. The GCC produce the expected output



The program works on GCC and didn't work on clang, where we declared the
constraint destructor first and then default destructor (GCC compiler &
executor on the upper window and Clang on the lower)
https://godbolt.org/z/PWbfzscs4

You can check on godbolt through the above link





B.) When we declared the default destructor first, & then the constraint
destructor

//The program is same as above except the default destructor is declared first


#include <iostream>
#include <concepts>

template <typename T>
concept hasReleaseMethod = requires(T t)
{
        t.release();
};

template <typename T>
class ComWrapper
{
        T t;

  public:
        ~ComWrapper() = default;

        ~ComWrapper() requires requires(T t) { t.release(); }
        {
                std::cout << "destructor";
                t.release();
        }
};

struct hasRelease
{
        int a = 23;
        void release()
        {
                std::cout << "in release method:\n"
                                  << a;
        }
        void method()
        {
        }
};

struct notHadRelease
{
};

int main()
{
        ComWrapper<hasRelease> Ob;
        ComWrapper<notHadRelease> ob2;
};

https://godbolt.org/z/ss11d5cdd

When we declared the default destructor first, & then the constraint destructor
, the Clang compiles, but the default destructor is called & the constraint
destructor is discarded every time(see the executor and assembly in clang). 
Whereas, GCC executes correctly.

-- 
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/20210603/468a688f/attachment.html>


More information about the llvm-bugs mailing list