xref: /llvm-project/clang/test/SemaCXX/warn-shadow.cpp (revision 348c144d50fbb324821db19ba4beeb7d31c8d835)
1 // RUN: %clang_cc1 -verify -fsyntax-only -std=c++11 -Wshadow-all %s
2 
3 namespace {
4   int i; // expected-note {{previous declaration is here}}
5 }
6 
7 namespace one {
8 namespace two {
9   int j; // expected-note {{previous declaration is here}}
10   typedef int jj; // expected-note 2 {{previous declaration is here}}
11   using jjj=int; // expected-note 2 {{previous declaration is here}}
12 }
13 }
14 
15 namespace xx {
16   int m;
17   typedef int mm;
18   using mmm=int;
19 
20 }
21 namespace yy {
22   int m;
23   typedef char mm;
24   using mmm=char;
25 }
26 
27 using namespace one::two;
28 using namespace xx;
29 using namespace yy;
30 
31 void foo() {
32   int i; // expected-warning {{declaration shadows a variable in namespace '(anonymous)'}}
33   int j; // expected-warning {{declaration shadows a variable in namespace 'one::two'}}
34   int m;
35   int mm;
36   int mmm;
37 }
38 
39 class A {
40   static int data; // expected-note 1 {{previous declaration}}
41   // expected-note@+1 1 {{previous declaration}}
42   int field;
43   int f1, f2, f3, f4; // expected-note 8 {{previous declaration is here}}
44 
45   typedef int a1; // expected-note 2 {{previous declaration}}
46   using a2=int; // expected-note 2 {{previous declaration}}
47 
48   // The initialization is safe, but the modifications are not.
49   A(int f1, int f2, int f3, int f4) // expected-note-re 4 {{variable 'f{{[0-4]}}' is declared here}}
50 	  : f1(f1) {
51     f1 = 3; // expected-warning {{modifying constructor parameter 'f1' that shadows a field of 'A'}}
52     f1 = 4; // one warning per shadow
53     f2++; // expected-warning {{modifying constructor parameter 'f2' that shadows a field of 'A'}}
54     --f3; // expected-warning {{modifying constructor parameter 'f3' that shadows a field of 'A'}}
55     f4 += 2; // expected-warning {{modifying constructor parameter 'f4' that shadows a field of 'A'}}
56   }
57 
58   // The initialization is safe, but the modifications are not.
59   // expected-warning-re@+1 4 {{constructor parameter 'f{{[0-4]}}' shadows the field 'f{{[0-9]}}' of 'A'}}
60   A(int f1, int f2, int f3, int f4, double overload_dummy) {}
61 
62   void test() {
63     char *field; // expected-warning {{declaration shadows a field of 'A'}}
64     char *data; // expected-warning {{declaration shadows a static data member of 'A'}}
65     char *a1; // no warning
66     char *a2; // no warning
67     char *jj; // no warning
68     char *jjj; // no warning
69   }
70 
71   void test2() {
72     typedef char field; // no warning
73     typedef char data; // no warning
74     typedef char a1; // expected-warning {{declaration shadows a typedef in 'A'}}
75     typedef char a2; // expected-warning {{declaration shadows a type alias in 'A'}}
76     typedef char jj; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
77     typedef char jjj; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
78   }
79 
80   void test3() {
81     using field=char; // no warning
82     using data=char; // no warning
83     using a1=char; // expected-warning {{declaration shadows a typedef in 'A'}}
84     using a2=char; // expected-warning {{declaration shadows a type alias in 'A'}}
85     using jj=char; // expected-warning {{declaration shadows a typedef in namespace 'one::two'}}
86     using jjj=char; // expected-warning {{declaration shadows a type alias in namespace 'one::two'}}
87   }
88 };
89 
90 // TODO: this should warn, <rdar://problem/5018057>
91 class B : A {
92   int data;
93   static int field;
94 };
95 
96 // rdar://8900456
97 namespace rdar8900456 {
98 struct Foo {
99   static void Baz();
100   static void Baz1();
101   static void Baz2();
102 private:
103   int Bar;
104 };
105 
106 void Foo::Baz() {
107   double Bar = 12; // Don't warn.
108 }
109 
110 void Foo::Baz1() {
111   typedef int Bar; // Don't warn.
112 }
113 
114 void Foo::Baz2() {
115   using Bar=int; // Don't warn.
116 }
117 }
118 
119 // http://llvm.org/PR9160
120 namespace PR9160 {
121 struct V {
122   V(int);
123 };
124 struct S {
125   V v;
126   static void m() {
127     if (1) {
128       V v(0);
129     }
130   }
131 };
132 }
133 
134 extern int bob; // expected-note 1 {{previous declaration is here}}
135 typedef int bob1; // expected-note 2 {{previous declaration is here}}
136 using bob2=int; // expected-note 2 {{previous declaration is here}}
137 
138 // rdar://8883302
139 void rdar8883302() {
140   extern int bob; // don't warn for shadowing.
141 }
142 
143 void test8() {
144   int bob; // expected-warning {{declaration shadows a variable in the global namespace}}
145   int bob1; //no warning
146   int bob2; // no warning
147 }
148 
149 void test9() {
150   typedef int bob; // no warning
151   typedef int bob1; // expected-warning {{declaration shadows a typedef in the global namespace}}
152   typedef int bob2; // expected-warning {{declaration shadows a type alias in the global namespace}}
153 }
154 
155 void test10() {
156   using bob=int; // no warning
157   using bob1=int; // expected-warning {{declaration shadows a typedef in the global namespace}}
158   using bob2=int; // expected-warning {{declaration shadows a type alias in the global namespace}}
159 }
160 
161 namespace rdar29067894 {
162 
163 void avoidWarningWhenRedefining(int b) { // expected-note {{previous definition is here}}
164   int a = 0; // expected-note {{previous definition is here}}
165   int a = 1; // expected-error {{redefinition of 'a'}}
166   int b = 2; // expected-error {{redefinition of 'b'}}
167 
168   using c=char; // expected-note {{previous definition is here}}
169   using c=int; // expected-error {{type alias redefinition with different types ('int' vs 'char')}}
170 
171   typedef char d; // expected-note {{previous definition is here}}
172   typedef int d; // expected-error {{typedef redefinition with different types ('int' vs 'char')}}
173 
174   using e=char; // expected-note {{previous definition is here}}
175   typedef int e; // expected-error {{type alias redefinition with different types ('int' vs 'char')}}
176 
177   int f; // expected-note {{previous definition is here}}
178   using f=int; // expected-error {{redefinition of 'f'}}
179 
180   using g=int; // expected-note {{previous definition is here}}
181   int g; // expected-error {{redefinition of 'g'}}
182 
183   typedef int h; // expected-note {{previous definition is here}}
184   int h; // expected-error {{redefinition of 'h'}}
185 
186   int k; // expected-note {{previous definition is here}}
187   typedef int k; // expected-error {{redefinition of 'k'}}
188 
189   using l=char; // no warning or error.
190   using l=char; // no warning or error.
191   typedef char l; // no warning or error.
192 
193   typedef char n; // no warning or error.
194   typedef char n; // no warning or error.
195   using n=char; // no warning or error.
196 }
197 
198 }
199