https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80858

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |https://gcc.gnu.org/bugzill
                   |                            |a/show_bug.cgi?id=109551
   Last reconfirmed|2017-05-22 00:00:00         |2023-10-20

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
For the original unordered_map case, deep down inside all that diagnostic
output we have:

/usr/include/c++/7/bits/unordered_map.h:101:11:   required from here

This is pointing to this line:

    class unordered_map


What GCC is trying to say is that the error comes from an implicitly-declared
copy assignment operator, but because there is no location to point to (because
it's not user-declared), it just points to the class head. Which is not
helpful.

For comment 4 we get:

c4.cc:14:7:   required from here


And as Steinar observed, that's the "class B" line.

On IRC nightstrike gave this example:

#include <memory>

struct A;

struct B {
    std::unique_ptr<A> a;
    B();
    //~B(); // Uncomment to fix
};

struct C {
    B b;
    C(): b() {}
};

This gives a static assert inside default_delete, which is nedeed by
~unique_ptr, which is needed by "struct B":

In file included from
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/memory:78,
                 from <source>:1:
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/unique_ptr.h: In
instantiation of 'void std::default_delete<_Tp>::operator()(_Tp*) const [with
_Tp = A]':
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/unique_ptr.h:404:17: 
 required from 'std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp = A; _Dp =
std::default_delete<A>]'
<source>:5:8:   required from here
/opt/compiler-explorer/gcc-13.2.0/include/c++/13.2.0/bits/unique_ptr.h:97:23:
error: invalid application of 'sizeof' to incomplete type 'A'
   97 |         static_assert(sizeof(_Tp)>0,
      |                       ^~~~~~~~~~~

There's no clue that it's needed by the implicit B::~B(). Even if you do know
that GCC is trying to refer to the location of an implicitly-declared special
member (which has no location), you have to guess *which* special member.

I think these cases would be greatly improved if the "required from here"
instead said "required from the implicitly-defined copy assignment operator" or
"required from the implicitly-defined destructor". We could still point to the
unhelpful location of the class head, as that does no real harm. But saying
that the error is triggered by the implicit definition of a particular special
member would make these errors easier to understand.

Somehow highlighting that line so that it's not buried would be nice too.
Because there's no caret diagnostic associated with the "required from here"
line, it's easy to miss among the more verbose lines on either side of it.

Reply via email to