Issue 123637
Summary Bad error trace for issue with unique_ptr
Labels new issue
Assignees
Reporter JVApen
    The following is reduced from a build with clang-cl and the MS stl implementation:

````
#include <vector>
#include <memory>
#include <type_traits>

template <class _Ty>
struct ms_default_delete { // default deleter for unique_ptr
    constexpr ms_default_delete() noexcept = default;

    template <class _Ty2, std::enable_if_t<std::is_convertible_v<_Ty2*, _Ty*>, int> = 0>
 ms_default_delete(const ms_default_delete<_Ty2>&) noexcept {}

    void operator()(_Ty* _Ptr) const noexcept /* strengthened */ { // delete a pointer
        static_assert(0 < sizeof(_Ty), "can't delete an incomplete type");
        delete _Ptr;
    }
};
struct FWD;

struct S
{
 ~S() = default;
    std::vector<std::unique_ptr<FWD, ms_default_delete<FWD>>> member;
};


int main(int, char**){
    S s;
}
````
https://compiler-explorer.com/z/6K8ebK3E1

This gives the error:
````
<source>:13:27: error: invalid application of 'sizeof' to an incomplete type 'FWD'
   13 |         static_assert(0 < sizeof(_Ty), "can't delete an incomplete type");
      | ^~~~~~~~~~~
/opt/compiler-explorer/clang-trunk-20250120/bin/../include/c++/v1/__memory/unique_ptr.h:300:7: note: in instantiation of member function 'ms_default_delete<FWD>::operator()' requested here
  300 | __deleter_(__tmp);
      | ^
/opt/compiler-explorer/clang-trunk-20250120/bin/../include/c++/v1/__memory/unique_ptr.h:269:71: note: in instantiation of member function 'std::unique_ptr<FWD, ms_default_delete<FWD>>::reset' requested here
  269 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 ~unique_ptr() { reset(); }
      | ^
/opt/compiler-explorer/clang-trunk-20250120/bin/../include/c++/v1/__memory/construct_at.h:66:11: note: in instantiation of member function 'std::unique_ptr<FWD, ms_default_delete<FWD>>::~unique_ptr' requested here
   66 | __loc->~_Tp();
      |           ^
<source>:17:8: note: forward declaration of 'FWD'
   17 | struct FWD;
      |        ^
1 error generated.
````
In this trace, this mentions the location of the `static_assert`, it mentions the location of the forward declare.
Though what is missing in this trace is the location that started the initialization. (The inline destructor of struct `S`)

This last is especially useful if you have the output of multiple compilations together without explicit mention of the file that was compiled.
(Like a multi-process build via CMake, a CI system that runs clang-tidy on multiple files and puts all results together ...)
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to