1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
// RUN: %check_clang_tidy %s google-runtime-references %t -- \
// RUN: -config="{CheckOptions: \
// RUN: [{key: google-runtime-references.IncludedTypes, \
// RUN: value: 'included::A; included::B'}]}"
int a;
int &b = a;
int *c;
void f1(int a);
void f2(int *b);
void f3(const int &c);
void f4(int const &d);
// Don't warn on implicit operator= in c++11 mode.
class A {
virtual void f() {}
};
// Don't warn on rvalue-references.
struct A2 {
A2(A2&&) = default;
void f(A2&&) {}
};
// Don't warn on iostream parameters.
namespace xxx {
class istream { };
class ostringstream { };
}
void g1(xxx::istream &istr);
void g1(xxx::ostringstream &istr);
void g1(int &a);
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: non-const reference parameter 'a', make it const or use a pointer [google-runtime-references]
struct s {};
void g2(int a, int b, s c, s &d);
// CHECK-MESSAGES: [[@LINE-1]]:31: warning: non-const reference parameter 'd', {{.*}}
typedef int &ref;
void g3(ref a);
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: non-const reference {{.*}}
void g4(int &a, int &b, int &);
// CHECK-MESSAGES: [[@LINE-1]]:14: warning: non-const reference parameter 'a', {{.*}}
// CHECK-MESSAGES: [[@LINE-2]]:22: warning: non-const reference parameter 'b', {{.*}}
// CHECK-MESSAGES: [[@LINE-3]]:30: warning: non-const reference parameter at index 2, {{.*}}
class B {
B(B& a) {}
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: non-const reference {{.*}}
virtual void f(int &a) {}
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: non-const reference {{.*}}
void g(int &b);
// CHECK-MESSAGES: [[@LINE-1]]:15: warning: non-const reference {{.*}}
// Don't warn on the parameter of stream extractors defined as members.
B& operator>>(int& val) { return *this; }
};
// Only warn on the first declaration of each function to reduce duplicate
// warnings.
void B::g(int &b) {}
// Don't warn on the first parameter of stream inserters.
A& operator<<(A& s, int&) { return s; }
// CHECK-MESSAGES: [[@LINE-1]]:25: warning: non-const reference parameter at index 1, {{.*}}
// Don't warn on either parameter of stream extractors. Both need to be
// non-const references by convention.
A& operator>>(A& input, int& val) { return input; }
// Don't warn on lambdas.
auto lambda = [] (int&) {};
// Don't warn on typedefs, as we'll warn on the function itself.
typedef int (*fp)(int &);
// Don't warn on function references.
typedef void F();
void g5(const F& func) {}
void g6(F& func) {}
template<typename T>
void g7(const T& t) {}
template<typename T>
void g8(T t) {}
void f5() {
g5(f5);
g6(f5);
g7(f5);
g7<F&>(f5);
g8(f5);
g8<F&>(f5);
}
// Don't warn on dependent types.
template<typename T>
void g9(T& t) {}
template<typename T>
void g10(T t) {}
void f6() {
int i;
float f;
g9<int>(i);
g9<const int>(i);
g9<int&>(i);
g10<int&>(i);
g10<float&>(f);
}
// Warn only on the overridden methods from the base class, as the child class
// only implements the interface.
class C : public B {
C();
virtual void f(int &a) {}
};
// Don't warn on operator<< with streams-like interface.
A& operator<<(A& s, int) { return s; }
// Don't warn on swap().
void swap(C& c1, C& c2) {}
// Don't warn on standalone operator++, operator--, operator+=, operator-=,
// operator*=, etc. that all need non-const references to be functional.
A& operator++(A& a) { return a; }
A operator++(A& a, int) { return a; }
A& operator--(A& a) { return a; }
A operator--(A& a, int) { return a; }
A& operator+=(A& a, const A& b) { return a; }
A& operator-=(A& a, const A& b) { return a; }
A& operator*=(A& a, const A& b) { return a; }
A& operator/=(A& a, const A& b) { return a; }
A& operator%=(A& a, const A& b) { return a; }
A& operator<<=(A& a, const A& b) { return a; }
A& operator>>=(A& a, const A& b) { return a; }
A& operator|=(A& a, const A& b) { return a; }
A& operator^=(A& a, const A& b) { return a; }
A& operator&=(A& a, const A& b) { return a; }
namespace included {
class A {};
class B {};
void f7(A &);
void f8(B &);
}
void f9(included::A &);
void f10(included::B &);
#define DEFINE_F(name) void name(int& a)
DEFINE_F(func) {}
|