brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 7660e9c Raw
128 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++17 -analyzer-checker=core,deadcode -verify %s2 3typedef unsigned long size_t;4 5// Machinery required for custom structured bindings decomposition.6namespace std {7template <class T> class tuple_size;8template <class T>9 constexpr size_t tuple_size_v = tuple_size<T>::value;10template <size_t I, class T> class tuple_element;11 12template<class T, T v>13struct integral_constant {14    static constexpr T value = v;15    typedef T value_type;16    typedef integral_constant type;17    constexpr operator value_type() const noexcept { return value; }18};19}20 21struct S {22  int a;23  double b;24  S(int a, double b) : a(a), b(b) {};25};26 27S GetNumbers();28 29int used_binding() {30    const auto [a, b] = GetNumbers(); // no-warning31    return a + b; 32}33 34void no_warning_on_copy(S s) {35  // Copy constructor might have side effects.36  const auto [a, b] = s; // no-warning37}38 39 40int unused_binding_ignored() {41    const auto [a, b] = GetNumbers(); // expected-warning{{Value stored to '[a, b]' during its initialization is never read}}42    return 0;43}44 45int unused_binding_liveness_required() {46    auto [a2, b2] = GetNumbers(); // expected-warning{{Value stored to '[a2, b2]' during its initialization is never read}}47    a2 = 10;48    b2 = 20;49    return a2 + b2;50}51 52int kill_one_binding() {53  auto [a, b] = GetNumbers(); // no-warning54  a = 100;55  return a + b;56 57}58 59int kill_one_binding2() {60  auto [a, b] = GetNumbers(); // expected-warning{{Value stored to '[a, b]' during its initialization is never read}}61  a = 100;62  return a;63}64 65void use_const_reference_bindings() {66  const auto &[a, b] = GetNumbers(); // no-warning67}68 69void use_reference_bindings() {70  S s(0, 0);71  auto &[a, b] = s; // no-warning72  a = 200;73}74 75int read_through_pointer() {76  auto [a, b] = GetNumbers(); // no-warning77  int *z = &a;78  return *z;79}80 81auto [globalA, globalB] = GetNumbers(); // no-warning, globals82auto [globalC, globalD] = GetNumbers(); // no-warning, globals83 84void use_globals() {85  globalA = 300; // no-warning86  globalB = 200;87}88 89struct Mytuple {90  int a;91  int b;92 93  template <size_t N>94  int get() const {95    if      constexpr (N == 0) return a;96    else if constexpr (N == 1) return b;97  }98};99 100namespace std {101    template<>102    struct tuple_size<Mytuple>103        : std::integral_constant<size_t, 2> {};104 105    template<size_t N>106    struct tuple_element<N, Mytuple> {107        using type = int;108    };109}110 111void no_warning_on_tuple_types_copy(Mytuple t) {112  auto [a, b] = t; // no-warning113}114 115Mytuple getMytuple();116 117void deconstruct_tuple_types_warning() {118  // The initializers reference the decomposed region, so the warning is not reported119  // FIXME: ideally we want to ignore that the initializers reference the decomposed region, and report the warning,120  // though the first step towards that is to handle DeadCode if the initializer is CXXConstructExpr.121  auto [a, b] = getMytuple(); // no-warning122}123 124int deconstruct_tuple_types_no_warning() {125  auto [a, b] = getMytuple(); // no-warning126  return a + b;127}128