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