• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify %s
4 
5 // C++03 [namespace.udecl]p12:
6 //   When a using-declaration brings names from a base class into a
7 //   derived class scope, member functions in the derived class
8 //   override and/or hide member functions with the same name and
9 //   parameter types in a base class (rather than conflicting).
10 
11 template <unsigned n> struct Opaque {};
expect(Opaque<n> _)12 template <unsigned n> void expect(Opaque<n> _) {}
13 
14 // PR5727
15 // This just shouldn't crash.
16 namespace test0 {
17   template<typename> struct RefPtr { };
18   template<typename> struct PtrHash {
ftest0::PtrHash19     static void f() { }
20   };
21   template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
22     using PtrHash<T*>::f;
ftest0::PtrHash23     static void f() { f(); }
24   };
25 }
26 
27 // Simple hiding.
28 namespace test1 {
29   struct Base {
30     Opaque<0> foo(Opaque<0>);
31     Opaque<0> foo(Opaque<1>);
32     Opaque<0> foo(Opaque<2>);
33   };
34 
35   // using before decls
36   struct Test0 : Base {
37     using Base::foo;
38     Opaque<1> foo(Opaque<1>);
39     Opaque<1> foo(Opaque<3>);
40 
test0test1::Test041     void test0() { Opaque<0> _ = foo(Opaque<0>()); }
test1test1::Test042     void test1() { Opaque<1> _ = foo(Opaque<1>()); }
test2test1::Test043     void test2() { Opaque<0> _ = foo(Opaque<2>()); }
test3test1::Test044     void test3() { Opaque<1> _ = foo(Opaque<3>()); }
45   };
46 
47   // using after decls
48   struct Test1 : Base {
49     Opaque<1> foo(Opaque<1>);
50     Opaque<1> foo(Opaque<3>);
51     using Base::foo;
52 
test0test1::Test153     void test0() { Opaque<0> _ = foo(Opaque<0>()); }
test1test1::Test154     void test1() { Opaque<1> _ = foo(Opaque<1>()); }
test2test1::Test155     void test2() { Opaque<0> _ = foo(Opaque<2>()); }
test3test1::Test156     void test3() { Opaque<1> _ = foo(Opaque<3>()); }
57   };
58 
59   // using between decls
60   struct Test2 : Base {
61     Opaque<1> foo(Opaque<0>);
62     using Base::foo;
63     Opaque<1> foo(Opaque<2>);
64     Opaque<1> foo(Opaque<3>);
65 
test0test1::Test266     void test0() { Opaque<1> _ = foo(Opaque<0>()); }
test1test1::Test267     void test1() { Opaque<0> _ = foo(Opaque<1>()); }
test2test1::Test268     void test2() { Opaque<1> _ = foo(Opaque<2>()); }
test3test1::Test269     void test3() { Opaque<1> _ = foo(Opaque<3>()); }
70   };
71 }
72 
73 // Crazy dependent hiding.
74 namespace test2 {
75   struct Base {
76     void foo(int);
77   };
78 
79   template <typename T> struct Derived1 : Base {
80     using Base::foo;
81     void foo(T);
82 
testUnresolvedtest2::Derived183     void testUnresolved(int i) { foo(i); }
84   };
85 
test0(int i)86   void test0(int i) {
87     Derived1<int> d1;
88     d1.foo(i);
89     d1.testUnresolved(i);
90   }
91 
92   // Same thing, except with the order of members reversed.
93   template <typename T> struct Derived2 : Base {
94     void foo(T);
95     using Base::foo;
96 
testUnresolvedtest2::Derived297     void testUnresolved(int i) { foo(i); }
98   };
99 
test1(int i)100   void test1(int i) {
101     Derived2<int> d2;
102     d2.foo(i);
103     d2.testUnresolved(i);
104   }
105 }
106 
107 // Hiding of member templates.
108 namespace test3 {
109   struct Base {
footest3::Base110     template <class T> Opaque<0> foo() { return Opaque<0>(); }
footest3::Base111     template <int n> Opaque<1> foo() { return Opaque<1>(); }
112   };
113 
114   struct Derived1 : Base {
115     using Base::foo;
footest3::Derived1116     template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
117   };
118 
119   struct Derived2 : Base {
footest3::Derived2120     template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
121     using Base::foo;
122   };
123 
124   struct Derived3 : Base {
125     using Base::foo;
footest3::Derived3126     template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
127   };
128 
129   struct Derived4 : Base {
footest3::Derived4130     template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
131     using Base::foo;
132   };
133 
test()134   void test() {
135     expect<0>(Base().foo<int>());
136     expect<1>(Base().foo<0>());
137     expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
138     expect<2>(Derived1().foo<0>());
139     expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
140     expect<2>(Derived2().foo<0>());
141     expect<3>(Derived3().foo<int>());
142     expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
143     expect<3>(Derived4().foo<int>());
144     expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
145   }
146 }
147 
148 // PR7384: access control for member templates.
149 namespace test4 {
150   class Base {
151   protected:
152     template<typename T> void foo(T);
153     template<typename T> void bar(T); // expected-note {{declared protected here}}
154   };
155 
156   struct Derived : Base {
157     using Base::foo;
158   };
159 
test()160   void test() {
161     Derived d;
162     d.foo<int>(3);
163     d.bar<int>(3); // expected-error {{'bar' is a protected member}}
164   }
165 }
166 
167 namespace test5 {
168   struct Derived;
169   struct Base {
170     void operator=(const Derived&);
171   };
172   struct Derived : Base {
173     // Hidden by implicit derived class operator.
174     using Base::operator=;
175   };
f(Derived d)176   void f(Derived d) {
177     d = d;
178   }
179 }
180 
181 #if __cplusplus >= 201103L
182 namespace test6 {
183   struct Derived;
184   struct Base {
185     void operator=(Derived&&);
186   };
187   struct Derived : Base {
188     // Hidden by implicit derived class operator.
189     using Base::operator=;
190   };
f(Derived d)191   void f(Derived d) {
192     d = Derived();
193   }
194 }
195 #endif
196