philnik777 wrote:

> This is going to need tests on redeclarations, implicit instantiations, and 
> specializations.

I'll add those if we agree to move forward with the general concept.

> Also, I wonder why this is applying to CXXRecordDecl rather than the primary 
> template.

I'm not quite sure what you mean here. 

> I don't see any code to do instantiation, which is a pretty manual process, 
> so that probably needs attending to.

I'm not quite sure what you're asking for. I've looked at `PreferredName`, and 
that also doesn't handle any instantiations AFAICT.

> As far as the value here, I'm on the fence here. I'd like to see much more 
> justification here for this.

Do you have some idea of what sort of justification you'd like to see?

> I have to be honest, my initial impression is that we should not need this. 
> I'd like to understand when you think the diags are insufficient today, and 
> see if there is something to improve there.

The main motivation for this attribute isn't insufficient diagnostics, but 
missing diagnostics due to some functions happening to not actually requiring a 
complete type currently. The improved diagnostics are just a bonus.

Though, FWIW the diagnostic for this case:
```c++
#include <vector>

struct incomplete;

void func(std::vector<incomplete>& v) {
  v.emplace_back();
}
```

before (modified to contain only relative paths):
```
In file included from <source>:1:
In file included from <vector>:314:
In file included from <__vector/vector.h>:76:
<__vector/layout.h>:425:40: error: arithmetic on a pointer to an incomplete 
type 'incomplete'
  425 |   return static_cast<size_type>(__end_ - __begin_);
      |                                 ~~~~~~ ^
<__vector/vector.h>:395:22: note: in instantiation of member function 
'std::__vector_layout<incomplete, std::allocator<incomplete>>::__size' 
requested here
  395 |     return __layout_.__size();
      |                      ^
<__vector/vector.h>:1081:7: note: in instantiation of member function 
'std::vector<incomplete>::size' requested here
 1081 |       size() != capacity(),
      |       ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
In file included from <__vector/vector.h>:76:
<__vector/layout.h>:431:45: error: arithmetic on a pointer to an incomplete 
type 'incomplete'
  431 |   return static_cast<size_type>(__capacity_ - __begin_);
      |                                 ~~~~~~~~~~~ ^
<__vector/vector.h>:398:22: note: in instantiation of member function 
'std::__vector_layout<incomplete, std::allocator<incomplete>>::__capacity' 
requested here
  398 |     return __layout_.__capacity();
      |                      ^
<__vector/vector.h>:1081:17: note: in instantiation of member function 
'std::vector<incomplete>::capacity' requested here
 1081 |       size() != capacity(),
      |                 ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:754:75: error: arithmetic on a pointer to an incomplete 
type 'incomplete'
  754 |         : __v_(__v), __pos_(__v.__layout_.__end_ptr()), 
__new_end_(__pos_ + __n) {
      |                                                                    
~~~~~~ ^
<__vector/vector.h>:475:27: note: in instantiation of member function 
'std::vector<incomplete>::_ConstructTransaction::_ConstructTransaction' 
requested here
  475 |     _ConstructTransaction __tx(*this, 1);
      |                           ^
<__vector/vector.h>:1083:9: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__emplace_back_assume_capacity<>' 
requested here
 1083 |         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
      |         ^
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:733:69: error: arithmetic on a pointer to an incomplete 
type 'const value_type' (aka 'const incomplete')
  733 |     std::__annotate_contiguous_container<_Allocator>(data(), data() + 
capacity(), __old_mid, __new_mid);
      |                                                              ~~~~~~ ^
<__vector/vector.h>:745:5: note: in instantiation of member function 
'std::vector<incomplete>::__annotate_contiguous_container' requested here
  745 |     __annotate_contiguous_container(data() + size(), data() + size() + 
__n);
      |     ^
<__vector/vector.h>:755:12: note: in instantiation of member function 
'std::vector<incomplete>::__annotate_increase' requested here
  755 |       __v_.__annotate_increase(__n);
      |            ^
<__vector/vector.h>:475:27: note: in instantiation of member function 
'std::vector<incomplete>::_ConstructTransaction::_ConstructTransaction' 
requested here
  475 |     _ConstructTransaction __tx(*this, 1);
      |                           ^
<__vector/vector.h>:1083:9: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__emplace_back_assume_capacity<>' 
requested here
 1083 |         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
      |         ^
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:745:44: error: arithmetic on a pointer to an incomplete 
type 'const value_type' (aka 'const incomplete')
  745 |     __annotate_contiguous_container(data() + size(), data() + size() + 
__n);
      |                                     ~~~~~~ ^
<__vector/vector.h>:755:12: note: in instantiation of member function 
'std::vector<incomplete>::__annotate_increase' requested here
  755 |       __v_.__annotate_increase(__n);
      |            ^
<__vector/vector.h>:475:27: note: in instantiation of member function 
'std::vector<incomplete>::_ConstructTransaction::_ConstructTransaction' 
requested here
  475 |     _ConstructTransaction __tx(*this, 1);
      |                           ^
<__vector/vector.h>:1083:9: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__emplace_back_assume_capacity<>' 
requested here
 1083 |         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
      |         ^
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:761:43: error: arithmetic on a pointer to an incomplete 
type 'const incomplete'
  761 |         __v_.__annotate_shrink(__new_end_ - 
__v_.__layout_.__begin_ptr());
      |                                ~~~~~~~~~~ ^
<__vector/vector.h>:475:27: note: in instantiation of member function 
'std::vector<incomplete>::_ConstructTransaction::~_ConstructTransaction' 
requested here
  475 |     _ConstructTransaction __tx(*this, 1);
      |                           ^
<__vector/vector.h>:1083:9: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__emplace_back_assume_capacity<>' 
requested here
 1083 |         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
      |         ^
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
In file included from <__vector/vector.h>:35:
In file included from 
/home/nikolas/source/llvm-project/libcxx/include/__memory/allocate_at_least.h:14:
/home/nikolas/source/llvm-project/libcxx/include/__memory/allocator_traits.h:362:5:
 error: no matching function for call to '__construct_at'
  362 |     std::__construct_at(__p, std::forward<_Args>(__args)...);
      |     ^~~~~~~~~~~~~~~~~~~
<__vector/vector.h>:476:21: note: in instantiation of function template 
specialization 
'std::allocator_traits<std::allocator<incomplete>>::construct<incomplete, 0>' 
requested here
  476 |     __alloc_traits::construct(
      |                     ^
<__vector/vector.h>:1083:9: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__emplace_back_assume_capacity<>' 
requested here
 1083 |         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
      |         ^
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
/home/nikolas/source/llvm-project/libcxx/include/__memory/construct_at.h:43:58: 
note: candidate template ignored: substitution failure [with _Tp = incomplete, 
_Args = <>]: allocation of incomplete type 'incomplete'
   42 | template <class _Tp, class... _Args, class = 
decltype(::new(std::declval<void*>()) _Tp(std::declval<_Args>()...))>
      |                                                                         
           ~~~
   43 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp* 
__construct_at(_Tp* __location, _Args&&... __args) {
      |                                                          ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:478:5: error: arithmetic on a pointer to an incomplete type 
'incomplete'
  478 |     ++__tx.__pos_;
      |     ^ ~~~~~~~~~~~
<__vector/vector.h>:1083:9: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__emplace_back_assume_capacity<>' 
requested here
 1083 |         __emplace_back_assume_capacity(std::forward<_Args>(__args)...);
      |         ^
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:1084:9: error: arithmetic on a pointer to an incomplete 
type 'incomplete'
 1084 |         ++__end;
      |         ^ ~~~~~
<__vector/vector.h>:1082:11: note: while substituting into a lambda expression 
here
 1082 |       [&] {
      |           ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
<__vector/vector.h>:817:62: error: invalid application of 'alignof' to an 
incomplete type 'incomplete'
  817 |       return static_cast<_Ptr>(__builtin_assume_aligned(__p, 
_LIBCPP_ALIGNOF(decltype(*__p))));
      |                                                              
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/nikolas/source/llvm-project/libcxx/include/__config:111:34: note: 
expanded from macro '_LIBCPP_ALIGNOF'
  111 | #    define _LIBCPP_ALIGNOF(...) alignof(__VA_ARGS__)
      |                                  ^~~~~~~~~~~~~~~~~~~~
<__vector/vector.h>:357:24: note: in instantiation of function template 
specialization 'std::vector<incomplete>::__add_alignment_assumption<incomplete 
*, 0>' requested here
  357 |     return 
__make_iter(__add_alignment_assumption(__layout_.__end_ptr()));
      |                        ^
<__vector/vector.h>:443:12: note: in instantiation of member function 
'std::vector<incomplete>::end' requested here
  443 |     return end()[-1];
      |            ^
<__vector/vector.h>:1090:10: note: in instantiation of member function 
'std::vector<incomplete>::back' requested here
 1090 |   return back();
      |          ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
In file included from <source>:1:
In file included from <vector>:314:
In file included from <__vector/vector.h>:33:
/home/nikolas/source/llvm-project/libcxx/include/__iterator/wrap_iter.h:103:12: 
error: subscript of pointer to incomplete type 'incomplete'
  103 |     return __i_[__n];
      |            ^~~~
<__vector/vector.h>:443:12: note: in instantiation of member function 
'std::__wrap_iter<incomplete *>::operator[]' requested here
  443 |     return end()[-1];
      |            ^
<__vector/vector.h>:1090:10: note: in instantiation of member function 
'std::vector<incomplete>::back' requested here
 1090 |   return back();
      |          ^
<source>:6:5: note: in instantiation of function template specialization 
'std::vector<incomplete>::emplace_back<>' requested here
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
11 errors generated.
```

and after:
```
<source>:6:5: error: 'incomplete' has to be complete when calling a member 
function
    6 |   v.emplace_back();
      |     ^
<source>:3:8: note: forward declaration of 'incomplete'
    3 | struct incomplete;
      |        ^
```

Looking at this, it would be nice to mention `std::vector<incomplete>`. IDK how 
difficult that would be.


https://github.com/llvm/llvm-project/pull/211231
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to