Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warnings due to std::reverse_iterator using the deprecated std::iterator #75057

Closed
JohelEGP opened this issue Dec 11, 2023 · 37 comments
Closed
Assignees
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules confirmed Verified by a second party libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Comments

@JohelEGP
Copy link

In module 'cpp2.util' imported from /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:12:
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' is deprecated [-Wdeprecated-declarations]
   53 |     : public iterator<typename iterator_traits<_Iter>::iterator_category,
      |              ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:542:40: note: in instantiation of template class 'std::__1::reverse_iterator<jegp::command *>' requested here
  542 |     std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_));
      |                                        ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>::operator()' requested here
   86 |       __rollback_();
      |       ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>::~__exception_guard_exceptions' requested here
  137 |   return __exception_guard<_Rollback>(std::move(__rollback));
      |          ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:560:12: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>' requested here
  560 |       std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2));
      |            ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:603:26: note: in instantiation of function template specialization 'std::__uninitialized_allocator_copy_impl<std::__1::allocator<jegp::command>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, jegp::command *>' requested here
  603 |     auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2));
      |                          ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/vector:1145:22: note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
 1145 |   __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_);
      |                      ^
/home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:57: note: in instantiation of function template specialization 'std::__1::ranges::to<std::__1::vector, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here
  100 |     return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make));  }
      |                                                         ^
/home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:42: note: in instantiation of requirement here
  100 |     return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make));  }
      |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:72: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE'
  373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...)          CPP2_UFCS_(&,QUALID,template,__VA_ARGS__)
      |                                                           ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:39: note: expanded from macro 'CPP2_UFCS_'
  363 |     requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:35: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG'
  345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); }
      |               ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:306:34: note: expanded from macro 'CPP2_UFCS_REMPARENS'
  306 | #define CPP2_UFCS_REMPARENS(...) __VA_ARGS__
      |                                  ^
/home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:12: note: while substituting template arguments into constraint expression here
  100 |     return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make));  }
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:59: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE'
  373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...)          CPP2_UFCS_(&,QUALID,template,__VA_ARGS__)
      |                                                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:14: note: expanded from macro 'CPP2_UFCS_'
  363 |     requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:4: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG'
  345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); }
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: while checking constraint satisfaction for template 'operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' required here
  100 |     return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make));  }
      |                                                                         ^
/home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: in instantiation of function template specialization 'jegp::command::range_from_array_arguments(std::vector<std::string>)::(anonymous class)::operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/iterator.h:24:29: note: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' has been explicitly marked deprecated here
   24 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator
      |                             ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:941:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
  941 | #    define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
      |                                         ^
/home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:914:49: note: expanded from macro '_LIBCPP_DEPRECATED'
  914 | #      define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
      |                                                 ^
@EugeneZelenko EugeneZelenko added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. and removed new issue labels Dec 11, 2023
@ravilpatel
Copy link

The warning you're seeing is related to the use of std::iterator in the std::reverse_iterator class, and it indicates that iterator <std::random_access_iterator_tag, jegp::command> is deprecated.

This warning is likely triggered by your use of the std::reverse_iterator in combination with certain algorithms or constructs in your code.

@JohelEGP
Copy link
Author

Yes, a very indirect use, by using std::ranges::to<std::vector>.

@mordante
Copy link
Member

@var-const has this been introduced by your ranges to patch?

@ldionne
Copy link
Member

ldionne commented Dec 12, 2023

@JohelEGP Can you please share how and what you're building in a reproducer? Ideally a godbolt link would make it really easy for us to see what's wrong.

@JohelEGP
Copy link
Author

I build Libc++ according to https://libcxx.llvm.org/Modules.html#using-in-external-projects.
Then building this simple program reproduces:

import std;

int main() {
  std::vector<int> v;
  v.reserve(0);
}

@ldionne
Copy link
Member

ldionne commented Jan 16, 2024

This doesn't happen if we're not building with modules: https://godbolt.org/z/vxYPabq5h

@mordante Do you think you could have a first look?

@mordante
Copy link
Member

As far as I can see we properly push and pop the deprecated diagnostic status. @cor3ntin could this be related to aafad2d?

It looks like pushing and popping the diagnostics state for deprecated messages is not working properly when using modules.

@cor3ntin
Copy link
Contributor

cor3ntin commented Feb 1, 2024

It appears we do not currently have a way to identify "system modules", amd all modules are considered user code, I think.
II have no idea how hard it would be to add that though. @ChuanqiXu9 ?

@cor3ntin cor3ntin added clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules labels Feb 1, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 1, 2024

@llvm/issue-subscribers-clang-modules

Author: Johel Ernesto Guerrero Peña (JohelEGP)

```output In module 'cpp2.util' imported from /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:12: /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' is deprecated [-Wdeprecated-declarations] 53 | : public iterator<typename iterator_traits<_Iter>::iterator_category, | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:542:40: note: in instantiation of template class 'std::__1::reverse_iterator<jegp::command *>' requested here 542 | std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>::operator()' requested here 86 | __rollback_(); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>::~__exception_guard_exceptions' requested here 137 | return __exception_guard<_Rollback>(std::move(__rollback)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:560:12: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>' requested here 560 | std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:603:26: note: in instantiation of function template specialization 'std::__uninitialized_allocator_copy_impl<std::__1::allocator<jegp::command>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, jegp::command *>' requested here 603 | auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/vector:1145:22: note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) 1145 | __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:57: note: in instantiation of function template specialization 'std::__1::ranges::to<std::__1::vector, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:42: note: in instantiation of requirement here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:72: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE' 373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:39: note: expanded from macro 'CPP2_UFCS_' 363 | requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:35: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG' 345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:306:34: note: expanded from macro 'CPP2_UFCS_REMPARENS' 306 | #define CPP2_UFCS_REMPARENS(...) __VA_ARGS__ | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:12: note: while substituting template arguments into constraint expression here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:59: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE' 373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:14: note: expanded from macro 'CPP2_UFCS_' 363 | requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:4: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG' 345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: while checking constraint satisfaction for template 'operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' required here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: in instantiation of function template specialization 'jegp::command::range_from_array_arguments(std::vector<std::string>)::(anonymous class)::operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/iterator.h:24:29: note: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' has been explicitly marked deprecated here 24 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:941:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 941 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:914:49: note: expanded from macro '_LIBCPP_DEPRECATED' 914 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ ```

@llvmbot
Copy link
Collaborator

llvmbot commented Feb 1, 2024

@llvm/issue-subscribers-clang-frontend

Author: Johel Ernesto Guerrero Peña (JohelEGP)

```output In module 'cpp2.util' imported from /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:12: /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' is deprecated [-Wdeprecated-declarations] 53 | : public iterator<typename iterator_traits<_Iter>::iterator_category, | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:542:40: note: in instantiation of template class 'std::__1::reverse_iterator<jegp::command *>' requested here 542 | std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>::operator()' requested here 86 | __rollback_(); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>::~__exception_guard_exceptions' requested here 137 | return __exception_guard<_Rollback>(std::move(__rollback)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:560:12: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>' requested here 560 | std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:603:26: note: in instantiation of function template specialization 'std::__uninitialized_allocator_copy_impl<std::__1::allocator<jegp::command>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, jegp::command *>' requested here 603 | auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/vector:1145:22: note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) 1145 | __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:57: note: in instantiation of function template specialization 'std::__1::ranges::to<std::__1::vector, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:42: note: in instantiation of requirement here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:72: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE' 373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:39: note: expanded from macro 'CPP2_UFCS_' 363 | requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:35: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG' 345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:306:34: note: expanded from macro 'CPP2_UFCS_REMPARENS' 306 | #define CPP2_UFCS_REMPARENS(...) __VA_ARGS__ | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:12: note: while substituting template arguments into constraint expression here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:59: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE' 373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:14: note: expanded from macro 'CPP2_UFCS_' 363 | requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:4: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG' 345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: while checking constraint satisfaction for template 'operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' required here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: in instantiation of function template specialization 'jegp::command::range_from_array_arguments(std::vector<std::string>)::(anonymous class)::operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/iterator.h:24:29: note: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' has been explicitly marked deprecated here 24 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:941:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 941 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:914:49: note: expanded from macro '_LIBCPP_DEPRECATED' 914 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ ```

@Endilll Endilll added confirmed Verified by a second party c++20 labels Feb 1, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 1, 2024

@llvm/issue-subscribers-c-20

Author: Johel Ernesto Guerrero Peña (JohelEGP)

```output In module 'cpp2.util' imported from /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:12: /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' is deprecated [-Wdeprecated-declarations] 53 | : public iterator<typename iterator_traits<_Iter>::iterator_category, | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:542:40: note: in instantiation of template class 'std::__1::reverse_iterator<jegp::command *>' requested here 542 | std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>::operator()' requested here 86 | __rollback_(); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>::~__exception_guard_exceptions' requested here 137 | return __exception_guard<_Rollback>(std::move(__rollback)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:560:12: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<jegp::command>, jegp::command *>>' requested here 560 | std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Iter2>(__alloc, __destruct_first, __first2)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__memory/uninitialized_algorithms.h:603:26: note: in instantiation of function template specialization 'std::__uninitialized_allocator_copy_impl<std::__1::allocator<jegp::command>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>::__iterator<false>, jegp::command *>' requested here 603 | auto __result = std::__uninitialized_allocator_copy_impl(__alloc, __unwrapped_range.first, __unwrapped_range.second, std::__unwrap_iter(__first2)); | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/vector:1145:22: note: (skipping 5 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all) 1145 | __tx.__pos_ = std::__uninitialized_allocator_copy(__alloc(), __first, __last, __tx.__pos_); | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:57: note: in instantiation of function template specialization 'std::__1::ranges::to<std::__1::vector, std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:42: note: in instantiation of requirement here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:72: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE' 373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) | ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:39: note: expanded from macro 'CPP2_UFCS_' 363 | requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:35: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG' 345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:306:34: note: expanded from macro 'CPP2_UFCS_REMPARENS' 306 | #define CPP2_UFCS_REMPARENS(...) __VA_ARGS__ | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:12: note: while substituting template arguments into constraint expression here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:373:59: note: expanded from macro 'CPP2_UFCS_QUALIFIED_TEMPLATE' 373 | #define CPP2_UFCS_QUALIFIED_TEMPLATE(QUALID,...) CPP2_UFCS_(&,QUALID,template,__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:363:14: note: expanded from macro 'CPP2_UFCS_' 363 | requires CPP2_UFCS_CONSTRAINT_ARG(QUALID,TEMPKW,__VA_ARGS__) { \ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/Documents/C++/Forks/hsutter/waarudo/include/cpp2util_pre.h:345:4: note: expanded from macro 'CPP2_UFCS_CONSTRAINT_ARG' 345 | || requires { CPP2_UFCS_REMPARENS QUALID __VA_ARGS__(CPP2_FORWARD(obj), CPP2_FORWARD(params)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: while checking constraint satisfaction for template 'operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' required here 100 | return CPP2_UFCS_QUALIFIED_TEMPLATE((std::ranges::),to<std::vector>)(CPP2_UFCS(std::views::transform)(std::move(v), command::make)); } | ^ /home/johel/build/Waarudo/ClangRelease/sources/jegp/algorithms/algorithms.cpp:100:73: note: in instantiation of function template specialization 'jegp::command::range_from_array_arguments(std::vector<std::string>)::(anonymous class)::operator()<std::__1::ranges::transform_view<std::__1::ranges::owning_view<std::__1::vector<std::__1::basic_string<char>>>, jegp::command (*)(std::__1::basic_string<char>)>>' requested here /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__iterator/iterator.h:24:29: note: 'iterator<std::__1::random_access_iterator_tag, jegp::command>' has been explicitly marked deprecated here 24 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:941:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17' 941 | # define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED | ^ /home/johel/Documents/C++/Forks/llvm/libcxx-std-modules/include/c++/v1/__config:914:49: note: expanded from macro '_LIBCPP_DEPRECATED' 914 | # define _LIBCPP_DEPRECATED __attribute__((__deprecated__)) | ^ ```

@ChuanqiXu9
Copy link
Member

It appears we do not currently have a way to identify "system modules", amd all modules are considered user code, I think. II have no idea how hard it would be to add that though. @ChuanqiXu9 ?

Oh, I missed this some how.

Yes, we don't treat std modules specially now. We can make it by adding another bit in clang::Module. I'll try to handle that.

ChuanqiXu9 added a commit to alibaba/async_simple that referenced this issue Mar 11, 2024
Note that we removed `-Werror` to `-Wno-deprecated-declarations` due to
a bug in clang:llvm/llvm-project#75057
@ChuanqiXu9
Copy link
Member

It appears we do not currently have a way to identify "system modules", amd all modules are considered user code, I think. II have no idea how hard it would be to add that though. @ChuanqiXu9 ?

I got confused after I look into aafad2d.

For the reproducer:

import std;

int main() {
  std::vector<int> v;
  v.reserve(0);
}

I dumped the InstantiationLoc in the above patch and it shows it is

<mylocal-path>/main.cpp:4:5

then it looks... somewhat correct... the instantiation loc is indeed not in system headers or modules. And in fact, I feel like the original patch "looks" correct for modules since currently the std modules are basically wrappers for headers.

Also the original reproducer from the thread and the duplicated reproducer in #79734 shows that the instantiation location lives in the users code... so I feel more confused...

@cor3ntin
Copy link
Contributor

@ChuanqiXu9 in DoEmitAvailabilityWarning we do emit some warnings for user code instantiated from within system headers.

This uses S.getSourceManager().isInSystemHeader(InstantiationLoc), which returns false (incorrectly) if InstantiationLoc is in a module.

Does that make sense?

@ChuanqiXu9
Copy link
Member

@ChuanqiXu9 in DoEmitAvailabilityWarning we do emit some warnings for user code instantiated from within system headers.

This uses S.getSourceManager().isInSystemHeader(InstantiationLoc), which returns false (incorrectly) if InstantiationLoc is in a module.

But my problem is, the dumpped InstantiationLoc (<mylocal-path>/main.cpp:4:5) is not in the module. It is in the user's code. So S.getSourceManager().isInSystemHeader(InstantiationLoc) should return false here in my mind.

Does that make sense?

@cor3ntin
Copy link
Contributor

@cor3ntin
Copy link
Contributor

@ChuanqiXu9
Copy link
Member

ChuanqiXu9 commented Mar 11, 2024

@ChuanqiXu9 a good start might be to create a module version of this test https://github.com/llvm/llvm-project/blob/main/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp

Yeah, I made it. And it looks like it works perfectly...

// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/mod.cppm -emit-module-interface -o %t/mod.pcm
// RUN: %clang_cc1 -std=c++20 %t/test.cc -fprebuilt-module-path=%t -fsyntax-only -verify

//--- header.h
#pragma clang system_header

template <typename T>
struct traits;

template <>
struct [[deprecated]] traits<int> {};

template<typename T, typename Trait = traits<T>>
struct basic_string {};

using __do_what_i_say_not_what_i_do  = traits<int> ;

template<typename T, typename Trait = traits<double>>
struct should_not_warn {};

//--- mod.cppm
module;
#include "header.h"
export module mod;
export using ::basic_string;
export using ::should_not_warn;

//--- test.cc
import mod;
basic_string<int> test1; // expected-note {{in instantiation of default argument for 'basic_string<int>' required here}}
// expected-note@header.h:7 {{'traits<int>' has been explicitly marked deprecated here}}
// expected-warning@header.h:9 {{'traits<int>' is deprecated}}
should_not_warn<int> test2;

(Note that header.h is in a differrent TU of test.cc. So we can't put expected there).

Given this looks good. I'd like to commit the test directly to increase the test coverage.


And I am not sure if you misunderstand my point. My point is that the behavior of S.getSourceManager().isInSystemHeader(InstantiationLoc) is correct there. In the reduced example, the dumpped InstantiationLoc is test.cc so it returns false as expected. Also in the example reported from users, all the dumpped InstantiationLoc is in the user's code, so the return value of S.getSourceManager().isInSystemHeader(InstantiationLoc) is correct.

@cor3ntin
Copy link
Contributor

@ChuanqiXu9 Yes, I'm a bit confused, sorry. Can we agree that isInSystemHeader returns false for locations in the std module, and that this is wrong?

I haven't found any logic in clang to handle system (standard) module.

@ChuanqiXu9
Copy link
Member

@ChuanqiXu9 Yes, I'm a bit confused, sorry. Can we agree that isInSystemHeader returns false for locations in the std module, and that this is wrong?

Yes, it should be wrong. But my confusion point is, I didn't see the isInSystemHeader return false for locations in the std module.

For example, if I insert the following code into aafad2d#diff-e32ebf7695e8361164e8f353f15548838d994990b08f29778bc6aced8f2ecb01R547

if (ShouldAllowWarningInSystemHeader) {
    llvm::errs() << "Instantiation Loc:";
    InstantiationLoc.print(llvm::errs(), S.getSourceManager());
    llvm::errs() << "\n";
  }

and compile the reproducer (https://godbolt.org/z/4rz4rehcz) locally, I'll see:

Instantiation Loc:/home/chuanqi.xcq/std_modules_testing/main.cpp:4:5
In module 'std' imported from /home/chuanqi.xcq/std_modules_testing/main.cpp:1:
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, int>' is deprecated [-Wdeprecated-declarations]
   53 |     : public iterator<typename iterator_traits<_Iter>::iterator_category,
      |              ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__memory/uninitialized_algorithms.h:531:40: note: in instantiation of template class 'std::__1::reverse_iterator<int *>' requested here
  531 |     std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_));
      |                                        ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>::operator()' requested here
   86 |       __rollback_();
      |       ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>>::~__exception_guard_exceptions' requested here
  137 |   return __exception_guard<_Rollback>(std::move(__rollback));
      |          ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__memory/uninitialized_algorithms.h:633:14: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>>' requested here
  633 |         std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Tp*>(__alloc, __destruct_first, __result));
      |              ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/vector:994:8: note: in instantiation of function template specialization 'std::__uninitialized_allocator_relocate<std::__1::allocator<int>, int>' requested here
  994 |   std::__uninitialized_allocator_relocate(
      |        ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/vector:1444:5: note: in instantiation of member function 'std::__1::vector<int>::__swap_out_circular_buffer' requested here
 1444 |     __swap_out_circular_buffer(__v);
      |     ^
/home/chuanqi.xcq/std_modules_testing/main.cpp:4:5: note: in instantiation of member function 'std::__1::vector<int>::reserve' requested here
    4 |   v.reserve(0);
      |     ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__iterator/iterator.h:23:29: note: 'iterator<std::__1::random_access_iterator_tag, int>' has been explicitly marked deprecated here
   23 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator {
      |                             ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__config:970:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
  970 | #    define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
      |                                         ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__config:943:49: note: expanded from macro '_LIBCPP_DEPRECATED'
  943 | #      define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
      |                                                 ^
1 warning generated.

And from the log I see the only location that makes isInSystemHeader return false is the location in the main.cpp. It is not related the modules. Or in another world, from the dumpped location, I see no locations in the std module.

So I am wondering if the change of patch itself is good but something bad happens in other places of the code path. But that patch triggers it.

I haven't found any logic in clang to handle system (standard) module.

Yes, there isn't such one. Since our previous consensus it try to avoid treating std modules special as much as possible.

For playing locally, you can use Decl::getOwningModule() to get the module. And use Module::getTopLevelModuleName() to get the module's name and judge if its name starts with std. It is not efficiency. But it should be good enough to test locally.

And I don't know there is a map from location to modules. But I feel it may not be an issue. Since we implement std module by including headers:

module;
#include <__config>
// The headers of Table 24: C++ library headers [tab:headers.cpp]
// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c]
#include <algorithm>
#include <any>
#include <array>
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
#endif
#if !defined(_LIBCPP_HAS_NO_THREADS)
# include <barrier>
#endif
#include <bit>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfenv>
#include <cfloat>
#include <charconv>
#include <chrono>
#include <cinttypes>
#include <climits>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <clocale>
#endif
#include <cmath>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <codecvt>
#endif
#include <compare>
#include <complex>
#include <concepts>
#include <condition_variable>
#include <coroutine>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
and the std.cppm itself is almost empty now. Maybe we can introduce something like #pragma clang system_modules in the future, but I think it should be fine now.

@ChuanqiXu9
Copy link
Member

@cor3ntin gentle ping

@ChuanqiXu9
Copy link
Member

BTW, @mordante do you think if this is a good example that we need more tests about import std;? I just noticed that this is brought into clang18 and I feel it may make people confusing...

(I know there are some practical issues in testing std module more in libc++. I just want to know if it is still on the plan)

@mordante
Copy link
Member

mordante commented Apr 7, 2024

I still like to have more libc++ tests using import std;. I have not really brought it up again with the libc++ developers. At the moment I'm quite busy with some other work in libc++ so this is a bit lower on my priority list.

@rnikander
Copy link

I've hit this too. Using import std was working okay until I upgraded Clang and got this.

It's made more painful because Emacs is highlighting some of the "In module 'std' imported" lines as errors, so I'd need to work on Emacs config if I want to be able to scroll through my build output for errors without being swamped with is stuff.

@ChuanqiXu9
Copy link
Member

@cor3ntin may you take a look at this?

@cor3ntin
Copy link
Contributor

@ChuanqiXu9 I am afraid i don't really have time to look at that at the moment (and it's unclear to me how to implement "isIsStdModule" for a given source location)

@ChuanqiXu9
Copy link
Member

@ChuanqiXu9 Yes, I'm a bit confused, sorry. Can we agree that isInSystemHeader returns false for locations in the std module, and that this is wrong?

Yes, it should be wrong. But my confusion point is, I didn't see the isInSystemHeader return false for locations in the std module.

For example, if I insert the following code into aafad2d#diff-e32ebf7695e8361164e8f353f15548838d994990b08f29778bc6aced8f2ecb01R547

if (ShouldAllowWarningInSystemHeader) {
    llvm::errs() << "Instantiation Loc:";
    InstantiationLoc.print(llvm::errs(), S.getSourceManager());
    llvm::errs() << "\n";
  }

and compile the reproducer (https://godbolt.org/z/4rz4rehcz) locally, I'll see:

Instantiation Loc:/home/chuanqi.xcq/std_modules_testing/main.cpp:4:5
In module 'std' imported from /home/chuanqi.xcq/std_modules_testing/main.cpp:1:
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, int>' is deprecated [-Wdeprecated-declarations]
   53 |     : public iterator<typename iterator_traits<_Iter>::iterator_category,
      |              ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__memory/uninitialized_algorithms.h:531:40: note: in instantiation of template class 'std::__1::reverse_iterator<int *>' requested here
  531 |     std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_));
      |                                        ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>::operator()' requested here
   86 |       __rollback_();
      |       ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>>::~__exception_guard_exceptions' requested here
  137 |   return __exception_guard<_Rollback>(std::move(__rollback));
      |          ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__memory/uninitialized_algorithms.h:633:14: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>>' requested here
  633 |         std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Tp*>(__alloc, __destruct_first, __result));
      |              ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/vector:994:8: note: in instantiation of function template specialization 'std::__uninitialized_allocator_relocate<std::__1::allocator<int>, int>' requested here
  994 |   std::__uninitialized_allocator_relocate(
      |        ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/vector:1444:5: note: in instantiation of member function 'std::__1::vector<int>::__swap_out_circular_buffer' requested here
 1444 |     __swap_out_circular_buffer(__v);
      |     ^
/home/chuanqi.xcq/std_modules_testing/main.cpp:4:5: note: in instantiation of member function 'std::__1::vector<int>::reserve' requested here
    4 |   v.reserve(0);
      |     ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__iterator/iterator.h:23:29: note: 'iterator<std::__1::random_access_iterator_tag, int>' has been explicitly marked deprecated here
   23 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator {
      |                             ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__config:970:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
  970 | #    define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
      |                                         ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__config:943:49: note: expanded from macro '_LIBCPP_DEPRECATED'
  943 | #      define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
      |                                                 ^
1 warning generated.

And from the log I see the only location that makes isInSystemHeader return false is the location in the main.cpp. It is not related the modules. Or in another world, from the dumpped location, I see no locations in the std module.

So I am wondering if the change of patch itself is good but something bad happens in other places of the code path. But that patch triggers it.

I haven't found any logic in clang to handle system (standard) module.

Yes, there isn't such one. Since our previous consensus it try to avoid treating std modules special as much as possible.

For playing locally, you can use Decl::getOwningModule() to get the module. And use Module::getTopLevelModuleName() to get the module's name and judge if its name starts with std. It is not efficiency. But it should be good enough to test locally.

And I don't know there is a map from location to modules. But I feel it may not be an issue. Since we implement std module by including headers:

module;
#include <__config>
// The headers of Table 24: C++ library headers [tab:headers.cpp]
// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c]
#include <algorithm>
#include <any>
#include <array>
#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
# include <atomic>
#endif
#if !defined(_LIBCPP_HAS_NO_THREADS)
# include <barrier>
#endif
#include <bit>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfenv>
#include <cfloat>
#include <charconv>
#include <chrono>
#include <cinttypes>
#include <climits>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <clocale>
#endif
#include <cmath>
#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
# include <codecvt>
#endif
#include <compare>
#include <complex>
#include <concepts>
#include <condition_variable>
#include <coroutine>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>

and the std.cppm itself is almost empty now. Maybe we can introduce something like #pragma clang system_modules in the future, but I think it should be fine now.

@cor3ntin oh, I am not asking you to implement isStdModuleSourceLocation or anything. I want to say, the problem looks not related to isInSystemHeader doesn't work correctly. See my above comments, from my dumpped result, all the result from isInSystemHeader looks good. So I don't think we need to isStdModuleSourceLocation.

If you don't have time, how do you think about reverting aafad2d temporarily?

@cor3ntin
Copy link
Contributor

If you don't have time, how do you think about reverting aafad2d temporarily?

I don't think this is a good option, we rely on this mechanism to display deprecation warnings in libc++.
It would be nice to have a reduced reproducer (and I do not know how to reduce module code)

@ChuanqiXu9
Copy link
Member

@cor3ntin I found a reproducer, but I am not sure if the base line is correct.

// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// Treat the behavior of using headers as baseline.
// RUN: %clang_cc1 -std=c++20 %t/use-header.cc -fsyntax-only -verify
//
// RUNX: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
// RUNX: %clang_cc1 -std=c++20 %t/use-module.cc -fmodule-file=a=%t/a.pcm -fsyntax-only -verify

//--- sys.h
#pragma clang system_header

template <class C>
struct [[deprecated]] iterator {};

template <class T>
class C {
public:
    void i() {
        iterator<T> i;
    }
};

//--- use-header.cc
// expected-no-diagnostics
// However, we see unexpected warnings
#include "sys.h"

void use() {
    C<int>().i();
}

//--- a.cppm
module;
#include "sys.h"
export module a;
export using ::iterator;
export using ::C;

//--- use-module.cc
// expected-no-diagnostics
import a;

void use() {
    C<int>().i();
}

Here I thought I got a reproducer. But I suddenly find the baseline of the reproducer (which only uses headers) will fail too. Is this behavior expected or not? @mordante

Then I am wondering the original reproducer, where the message shows the deprecated iterator is actually instantiated, then I am not sure where is the line to discard or not.

@mordante
Copy link
Member

The only main difference I see is your header has no include guards and we use #pragma GCC system_header. I think these should not make a difference.

@cor3ntin
Copy link
Contributor

The behavior of the warning in the header case is consistent with the intent of aafad2d

iterator<int> is instantiated from use(), which is in user code, therefore a warning is emitted.
If libc++ folks think this is too aggressive, we need to refine the set of circumstances in which we emit depreciation warning for specializations.
But that reproduction doesn't seem consistent with the bug initially reported.

@ChuanqiXu9
Copy link
Member

Yeah, maybe we need to look at the instantiation trace at: https://godbolt.org/z/K94xYPhPG since it looks like the root of the instantiation started from user's code too. We need to make sure if the instantiation path different in modules and in headers mode. @mordante

@ChuanqiXu9
Copy link
Member

Some update for this, I inserted

if (ShouldAllowWarningInSystemHeader) {
    llvm::errs() << "Loc:" << Loc.printToString(S.getSourceManager()) << "\n";
    llvm::errs() << "Expansioned Loc: " 
                 << S.getSourceManager().getExpansionLoc(Loc).printToString(S.getSourceManager())
                 << "\n";
    llvm::errs() << "Is it in system header: "
                 << S.getSourceManager().isInSystemHeader(S.getSourceManager().getExpansionLoc(Loc))
                 << "\n";
    llvm::errs() << "InstantiationLoc: "
                 << InstantiationLoc.printToString(S.getSourceManager())
                 << "\n";
    llvm::errs() << "Is instantiation in system header: "
                 << S.getSourceManager().isInSystemHeader(InstantiationLoc)
                 << "\n";
    ReferringDecl->dump();
  }

to https://github.com/llvm/llvm-project/blob/main/clang/lib/Sema/SemaAvailability.cpp#L547

and I tried to compile the following code with libc++

#include <vector>
int main() {
        std::vector<int> v;
        v.reserve(0);
}

And I see ShouldAllowWarningInSystemHeader turns to be true and I can see the instantiation location in the user's code. The code in

S.Diag(Loc, diag) << ReferringDecl << FixIts;
get executed too. I just don't get why it doesn't emit warnings actually.

I suspect it just works due to some surprising matches in diagnostic engines and it just didn't match with modules. I need to debug more.

@cor3ntin would you like to check it? I feel the original implementation has some problems which got covered by other places.

@ChuanqiXu9
Copy link
Member

ChuanqiXu9 commented Apr 29, 2024

Now I located https://github.com/llvm/llvm-project/blob/a19a4113df3e9a3ca3747075da6de21901796524/clang/lib/Basic/DiagnosticIDs.cpp#L519-L523C7

with headers version, the value of Mapping.getSeverity() is Ignored and with modules versions, the value of Mapping.getSeverity() is Warning. In both version, the dumpped Loc is include/c++/v1/__iterator/reverse_iterator.h:53:14. So we can see DiagnosticsEngine::SuppressSystemWarnings didn't get involved here. Something heppens earlier masked the change of @cor3ntin 's patch. So, if I don't make a mistake, it is a false negative diagnostic for the reproducer in the header's version.

@mordante can you take a look at the instantiation path to make sure if it is fine or problematic actually?

Here is the path in my environment:

In module 'std' imported from /home/chuanqi.xcq/std_modules_testing/main.cpp:1:
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__iterator/reverse_iterator.h:53:14: warning: 'iterator<std::__1::random_access_iterator_tag, int>' is deprecated [-Wdeprecated-declarations]
   53 |     : public iterator<typename iterator_traits<_Iter>::iterator_category,
      |              ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__memory/uninitialized_algorithms.h:529:40: note: in instantiation of template class 'std::__1::reverse_iterator<int *>' requested here
  529 |     std::__allocator_destroy(__alloc_, std::reverse_iterator<_Iter>(__last_), std::reverse_iterator<_Iter>(__first_));
      |                                        ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__utility/exception_guard.h:86:7: note: in instantiation of member function 'std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>::operator()' requested here
   86 |       __rollback_();
      |       ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__utility/exception_guard.h:137:10: note: in instantiation of member function 'std::__exception_guard_exceptions<std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>>::~__exception_guard_exceptions' requested here
  137 |   return __exception_guard<_Rollback>(std::move(__rollback));
      |          ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__memory/uninitialized_algorithms.h:631:14: note: in instantiation of function template specialization 'std::__make_exception_guard<std::_AllocatorDestroyRangeReverse<std::__1::allocator<int>, int *>>' requested here
  631 |         std::__make_exception_guard(_AllocatorDestroyRangeReverse<_Alloc, _Tp*>(__alloc, __destruct_first, __result));
      |              ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/vector:987:8: note: in instantiation of function template specialization 'std::__uninitialized_allocator_relocate<std::__1::allocator<int>, int>' requested here
  987 |   std::__uninitialized_allocator_relocate(
      |        ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/vector:1437:5: note: in instantiation of member function 'std::__1::vector<int>::__swap_out_circular_buffer' requested here
 1437 |     __swap_out_circular_buffer(__v);
      |     ^
/home/chuanqi.xcq/std_modules_testing/main.cpp:4:5: note: in instantiation of member function 'std::__1::vector<int>::reserve' requested here
    4 |   v.reserve(0);
      |     ^
Diagnosted.
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__iterator/iterator.h:23:29: note: 'iterator<std::__1::random_access_iterator_tag, int>' has been explicitly marked deprecated here
   23 | struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator {
      |                             ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__config:969:41: note: expanded from macro '_LIBCPP_DEPRECATED_IN_CXX17'
  969 | #    define _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_DEPRECATED
      |                                         ^
/home/chuanqi.xcq/llvm-project-for-work/build_libcxx/include/c++/v1/__config:934:49: note: expanded from macro '_LIBCPP_DEPRECATED'
  934 | #      define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
      |

@ChuanqiXu9
Copy link
Member

Oh, I finally got a reproducer:

// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// Treat the behavior of using headers as baseline.
// RUN: %clang_cc1 -std=c++20 %t/use-header.cc -isystem %t -fsyntax-only -verify
//
// RUN: %clang_cc1 -std=c++20 %t/a.cppm -isystem %t -emit-module-interface -o %t/a.pcm
// RUN: %clang_cc1 -std=c++20 %t/use-module.cc -isystem %t -fmodule-file=a=%t/a.pcm -fsyntax-only -verify

//--- reverse_iterator.h
#ifndef REVERSE_ITERATOR_H
#define REVERSE_ITERATOR_H

#pragma GCC system_header

template <class C>
struct [[deprecated]] iterator {};

_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wdeprecated\"")                         
_Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")

template <class C>
struct reverse_iterator 
#if !defined(_LIBCPP_ABI_NO_ITERATOR_BASES)
: public iterator<C> {};

#endif

_Pragma("GCC diagnostic pop")

#endif

//--- sys.h
#ifndef SYS_H
#define SYS_H

#include <reverse_iterator.h>

#pragma GCC system_header

template <class T>
class C {
public:
    void i() {
        reverse_iterator<T> i;
    }
};

#endif SYS_H

//--- use-header.cc
// expected-no-diagnostics
// However, we see unexpected warnings
#include <sys.h>

void use() {
    C<int>().i();
}

//--- a.cppm
module;
#include <sys.h>
export module a;
export using ::iterator;
export using ::C;

//--- use-module.cc
// expected-no-diagnostics
import a;

void use() {
    C<int>().i();
}

then the behavior of libc++ should be fine. It is the fault of clang didn't handle these _Pragma well. Yeah, I still think the behavior of

SourceLocation InstantiationLoc =
S.getTopMostPointOfInstantiation(ReferringDecl);
bool ShouldAllowWarningInSystemHeader =
InstantiationLoc != Loc &&
!S.getSourceManager().isInSystemHeader(InstantiationLoc);
struct AllowWarningInSystemHeaders {
AllowWarningInSystemHeaders(DiagnosticsEngine &E,
bool AllowWarningInSystemHeaders)
: Engine(E), Prev(E.getSuppressSystemWarnings()) {
E.setSuppressSystemWarnings(!AllowWarningInSystemHeaders);
}
~AllowWarningInSystemHeaders() { Engine.setSuppressSystemWarnings(Prev); }
is somewhat not perfect but this doesn't matter for this issue now.

@ChuanqiXu9
Copy link
Member

Oh, this turns out to be some "optimization" I did before, which get revealed by the above change. I'll fix this quickly. Sorry for wasting your time : (

ChuanqiXu9 added a commit that referenced this issue Apr 30, 2024
Close #75057

Previously, I thought the diagnostic mappings is not meaningful with
modules incorrectly. And this problem get revealed by another change
recently. So this patch tried to rever the previous "optimization"
partially.
@cor3ntin
Copy link
Contributor

@ChuanqiXu9 Sorry I wasn't of more help (modules confuse me)! Thanks for working on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules confirmed Verified by a second party libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
Status: Done
Development

No branches or pull requests

10 participants