[llvm-bugs] [Bug 46699] New: Clang not emitting referenced destructors (leading to link errors)

via llvm-bugs llvm-bugs at lists.llvm.org
Sun Jul 12 20:47:00 PDT 2020


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

            Bug ID: 46699
           Summary: Clang not emitting referenced destructors (leading to
                    link errors)
           Product: clang
           Version: trunk
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: smeenai at fb.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, rjmccall at apple.com,
                    rnk at google.com

Consider the following code:

template <class T> T &&declval() noexcept;

template <class _Functor> struct invoke_result {
  template <class _Fn> static decltype(declval<_Fn>()(0)) s_test();
  typedef decltype(s_test<_Functor>()) type;
};

template <class T> struct Core {
  Core() {}
  virtual ~Core() {}
};

template <class FF> auto run(FF &&ff) {
  auto lambda = [ff](auto) { return ff(0); };
  using T = typename invoke_result<decltype(lambda)>::type;
  return lambda(0);
}

class Trivial {};

Core<Trivial> *f() {
  return run([](auto) -> Core<Trivial> * { return new Core<Trivial>(); });
}

If I build this with clang, it emits a vtable for Core<Trivial> that references
the complete object and deleting destructors for Core<Trivial>, but it doesn't
actually emit those destructors, which later leads to a link error. As best as
I can tell, it should be emitting the destructors; all the relevant types are
complete, and there's no key functions. https://godbolt.org/z/czGEzT shows that
GCC does emit the destructors (-O2 and -fno-rtti are just to clean up the
assembly, and if you remove the filtering for directives you'll see that GCC is
aliasing the complete object destructor to the base object destructor).

The reduction is very sensitive. Removing the explicit return type from the
lambda in f, removing the parameters from the lambdas (so as to make them
non-generic lambdas), using FF instead of decltype(lambda) in run, and making
s_test in invoke_result use _Functor instead of having its own _Fn template
type all make the destructors be emitted. (invoke_result and declval are
reduced from libstdc++; I'm not fully confident about the validity of my
reduction, but GCC is still able to emit the destructors.)

-- 
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/20200713/116579ec/attachment-0001.html>


More information about the llvm-bugs mailing list