brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 32bcbca Raw
284 lines · cpp
1// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-std-namespace-modification %t -- -- -I %clang_tidy_headers2 3#include "system-header-simulation.h"4 5namespace A {6  namespace B {7    int b;8  }9}10 11namespace A {12  namespace B {13    int c;14  }15}16 17namespace posix {18// CHECK-MESSAGES: :[[@LINE+2]]:11: warning: modification of 'posix' namespace can result in undefined behavior [bugprone-std-namespace-modification]19// CHECK-MESSAGES: :[[@LINE-2]]:11: note: 'posix' namespace opened here20namespace foo {21int foobar;22}23}24 25namespace std {26// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: modification of 'std' namespace27// CHECK-MESSAGES: :[[@LINE-2]]:11: note: 'std' namespace opened here28int stdInt;29// CHECK-MESSAGES: :[[@LINE+2]]:5: warning: modification of 'std' namespace30// CHECK-MESSAGES: :[[@LINE-5]]:11: note: 'std' namespace opened here31int stdInt1;32}33 34namespace foobar {35  namespace std {36    int bar;37  }38}39 40namespace posix {41// CHECK-MESSAGES: :[[@LINE+2]]:11: warning: modification of 'posix' namespace42// CHECK-MESSAGES: :[[@LINE-2]]:11: note: 'posix' namespace opened here43namespace std {44}45} // namespace posix46 47namespace posix::a {48// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: modification of 'posix' namespace49// CHECK-MESSAGES: :[[@LINE-2]]:11: note: 'posix' namespace opened here50}51 52namespace std {53// no-warning: empty54} // namespace std55 56namespace std {57// Warn for non-NamedDecls as well.58// CHECK-MESSAGES: :[[@LINE+2]]:1: warning: modification of 'std' namespace59// CHECK-MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here60static_assert(1 == 1, "non-NamedDecl");61} // namespace std62 63enum class MyError {64  ErrorA,65  ErrorB66};67 68namespace std {69// no-warning: Class template specialized by a program-defined type.70template <>71struct is_error_code_enum<MyError> : std::true_type {};72 73// no-warning: Function template specialized by a program-defined type.74template<>75void swap<MyError>(MyError &a, MyError &b);76}77 78using ConstBoolPtr = const bool *;79 80namespace std {81// class template, builtin type82// CHECK-MESSAGES: :[[@LINE+3]]:8: warning: modification of 'std' namespace83// CHECK-MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here84template <>85struct is_error_code_enum<bool> : std::true_type {};86// function template, builtin type87// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: modification of 'std' namespace88// CHECK-MESSAGES: :[[@LINE-8]]:11: note: 'std' namespace opened here89template <>90void swap<bool>(bool &, bool &);91// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: modification of 'std' namespace92// CHECK-MESSAGES: :[[@LINE-12]]:11: note: 'std' namespace opened here93template <>94void swap<ConstBoolPtr>(ConstBoolPtr &, ConstBoolPtr &);95} // namespace std96 97namespace std {98// class template, std type99// CHECK-MESSAGES: :[[@LINE+3]]:8: warning: modification of 'std' namespace100// CHECK-MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here101template <>102struct is_error_code_enum<std::io_errc> : std::true_type {};103// function template, std type104// CHECK-MESSAGES: :[[@LINE+3]]:6: warning: modification of 'std' namespace105// CHECK-MESSAGES: :[[@LINE-8]]:11: note: 'std' namespace opened here106template <>107void swap<std::io_errc>(std::io_errc &, std::io_errc &);108} // namespace std109 110// parameter pack, has program-defined type111namespace std {112// no-warning: there is one program-defined type.113template <>114class tuple<int, MyError, std::io_errc> {};115} // namespace std116 117// parameter pack, only builtin or std type118namespace std {119// Forbid variadic specializations over only `std::` or builtin types.120// CHECK-MESSAGES: :[[@LINE+3]]:7: warning: modification of 'std' namespace121// CHECK-MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here122template <>123class tuple<int, const std::io_errc, float> {};124} // namespace std125 126namespace std {127// Test nested standard declarations.128// CHECK-MESSAGES: :[[@LINE+3]]:8: warning: modification of 'std' namespace129// CHECK-MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here130template <>131struct is_error_code_enum<std::Outer::Inner> : std::true_type {};132} // namespace std133 134namespace std {135// Test nested namespace.136// CHECK-MESSAGES: :[[@LINE+3]]:8: warning: modification of 'std' namespace137// CHECK-MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here138template <>139struct is_error_code_enum<std::detail::X> : std::true_type {};140} // namespace std141 142// Test member function template specializations.143namespace std {144// CHECK-MESSAGES: :[[@LINE+3]]:18: warning: modification of 'std' namespace145// CHECK_MESSAGES: :[[@LINE-2]]:11: note: 'std' namespace opened here146template <>147bool less<void>::operator()<int &&, float &&>(int &&, float &&) const {148  return true;149}150// CHECK-MESSAGES: :[[@LINE+3]]:18: warning: modification of 'std' namespace151// CHECK_MESSAGES: :[[@LINE-8]]:11: note: 'std' namespace opened here152template <>153bool less<void>::operator()<MyError &&, MyError &&>(MyError &&, MyError &&) const {154  return true;155}156} // namespace std157 158// Test member class template specializations.159namespace std {160// CHECK-MESSAGES: :[[@LINE+3]]:20: warning: modification of 'std' namespace161// CHECK_MESSAGES: :[[@LINE-2]]:11: note: 'std' namespace opened here162template <>163struct less<void>::X<bool> {};164// CHECK-MESSAGES: :[[@LINE+3]]:20: warning: modification of 'std' namespace165// CHECK_MESSAGES: :[[@LINE-6]]:11: note: 'std' namespace opened here166template <>167struct less<void>::X<MyError> {};168// CHECK-MESSAGES: :[[@LINE+3]]:20: warning: modification of 'std' namespace169// CHECK_MESSAGES: :[[@LINE-10]]:11: note: 'std' namespace opened here170template <typename T>171struct less<void>::X<MyError, T> {};172} // namespace std173 174// We did not open the 'std' namespace, but still specialized the member175// function of 'std::less'.176// CHECK-MESSAGES: :[[@LINE+3]]:23: warning: modification of 'std' namespace177// no-note: There is no opening of 'std' namespace, hence no note emitted.178template <>179bool std::less<void>::operator()<int &&, int &&>(int &&, int &&) const {180  return true;181}182 183namespace SpaceA {184namespace SpaceB {185class MapKey {186  int Type = 0;187 188public:189  MapKey() = default;190  int getType() const { return Type; }191};192} // namespace SpaceB193} // namespace SpaceA194 195// no-warning: Specializing for 'std::hash' for a program-defined type.196template <>197struct std::hash<::SpaceA::SpaceB::MapKey> {198  // no-warning199  unsigned long operator()(const ::SpaceA::SpaceB::MapKey &K) const {200    return K.getType();201  }202  // no-warning203  bool operator()(const ::SpaceA::SpaceB::MapKey &K1,204                  const ::SpaceA::SpaceB::MapKey &K2) const {205    return K1.getType() < K2.getType();206  }207};208 209using myint = int;210 211// The type alias declaration is the same as typedef, does not introduce a212// program-defined type.213// CHECK-MESSAGES: :[[@LINE+2]]:13: warning: modification of 'std' namespace214template <>215struct std::hash<myint> {216  // no-warning: The warning was already reported for the struct itself.217  unsigned long operator()(const myint &K) const {218    return K;219  }220  // no-warning: The warning was already reported for the struct itself.221  bool operator()(const myint &K1,222                  const myint &K2) const {223    return K1 < K2;224  }225};226 227// CHECK-MESSAGES: :[[@LINE+2]]:15: warning: modification of 'std' namespace228template <>229struct ::std::hash<long> {230  unsigned long operator()(const long &K) const {231    return K;232  }233};234 235namespace ranges {236namespace detail {237struct diffmax_t {};238using LongT = long;239} // namespace detail240} // namespace ranges241 242namespace std {243// no-warning: specialization with an user-defined type244template <>245struct numeric_limits<::ranges::detail::diffmax_t> {246  static constexpr bool is_signed = true;247  static constexpr bool is_integer = true;248  static constexpr ::ranges::detail::diffmax_t max() noexcept {249    return {};250  }251};252inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_signed;253inline constexpr bool numeric_limits<::ranges::detail::diffmax_t>::is_integer;254} // namespace std255 256namespace std {257// specialization with type alias to non-program-defined-type258// CHECK-MESSAGES: :[[@LINE+3]]:8: warning: modification of 'std' namespace259// CHECK_MESSAGES: :[[@LINE-3]]:11: note: 'std' namespace opened here260template <>261struct numeric_limits<::ranges::detail::LongT> {262  static constexpr bool is_signed = true;263  static constexpr bool is_integer = true;264  static constexpr ::ranges::detail::LongT max() noexcept {265    return 1;266  }267};268inline constexpr bool numeric_limits<::ranges::detail::LongT>::is_signed;269inline constexpr bool numeric_limits<::ranges::detail::LongT>::is_integer;270} // namespace std271 272namespace no_crash {273struct A274{275  friend struct B;276};277 278struct B;279 280template<typename> struct T {};281 282T<B> b;283}284