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