• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 // C++03 [namespace.udecl]p12:
4 //   When a using-declaration brings names from a base class into a
5 //   derived class scope, member functions in the derived class
6 //   override and/or hide member functions with the same name and
7 //   parameter types in a base class (rather than conflicting).
8 
9 template <unsigned n> struct Opaque {};
expect(Opaque<n> _)10 template <unsigned n> void expect(Opaque<n> _) {}
11 
12 // PR5727
13 // This just shouldn't crash.
14 namespace test0 {
15   template<typename> struct RefPtr { };
16   template<typename> struct PtrHash {
ftest0::PtrHash17     static void f() { }
18   };
19   template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
20     using PtrHash<T*>::f;
ftest0::PtrHash21     static void f() { f(); }
22   };
23 }
24 
25 // Simple hiding.
26 namespace test1 {
27   struct Base {
28     Opaque<0> foo(Opaque<0>);
29     Opaque<0> foo(Opaque<1>);
30     Opaque<0> foo(Opaque<2>);
31   };
32 
33   // using before decls
34   struct Test0 : Base {
35     using Base::foo;
36     Opaque<1> foo(Opaque<1>);
37     Opaque<1> foo(Opaque<3>);
38 
test0test1::Test039     void test0() { Opaque<0> _ = foo(Opaque<0>()); }
test1test1::Test040     void test1() { Opaque<1> _ = foo(Opaque<1>()); }
test2test1::Test041     void test2() { Opaque<0> _ = foo(Opaque<2>()); }
test3test1::Test042     void test3() { Opaque<1> _ = foo(Opaque<3>()); }
43   };
44 
45   // using after decls
46   struct Test1 : Base {
47     Opaque<1> foo(Opaque<1>);
48     Opaque<1> foo(Opaque<3>);
49     using Base::foo;
50 
test0test1::Test151     void test0() { Opaque<0> _ = foo(Opaque<0>()); }
test1test1::Test152     void test1() { Opaque<1> _ = foo(Opaque<1>()); }
test2test1::Test153     void test2() { Opaque<0> _ = foo(Opaque<2>()); }
test3test1::Test154     void test3() { Opaque<1> _ = foo(Opaque<3>()); }
55   };
56 
57   // using between decls
58   struct Test2 : Base {
59     Opaque<1> foo(Opaque<0>);
60     using Base::foo;
61     Opaque<1> foo(Opaque<2>);
62     Opaque<1> foo(Opaque<3>);
63 
test0test1::Test264     void test0() { Opaque<1> _ = foo(Opaque<0>()); }
test1test1::Test265     void test1() { Opaque<0> _ = foo(Opaque<1>()); }
test2test1::Test266     void test2() { Opaque<1> _ = foo(Opaque<2>()); }
test3test1::Test267     void test3() { Opaque<1> _ = foo(Opaque<3>()); }
68   };
69 }
70 
71 // Crazy dependent hiding.
72 namespace test2 {
73   struct Base {
74     void foo(int);
75   };
76 
77   template <typename T> struct Derived1 : Base {
78     using Base::foo;
79     void foo(T);
80 
testUnresolvedtest2::Derived181     void testUnresolved(int i) { foo(i); }
82   };
83 
test0(int i)84   void test0(int i) {
85     Derived1<int> d1;
86     d1.foo(i);
87     d1.testUnresolved(i);
88   }
89 
90   // Same thing, except with the order of members reversed.
91   template <typename T> struct Derived2 : Base {
92     void foo(T);
93     using Base::foo;
94 
testUnresolvedtest2::Derived295     void testUnresolved(int i) { foo(i); }
96   };
97 
test1(int i)98   void test1(int i) {
99     Derived2<int> d2;
100     d2.foo(i);
101     d2.testUnresolved(i);
102   }
103 }
104 
105 // Hiding of member templates.
106 namespace test3 {
107   struct Base {
footest3::Base108     template <class T> Opaque<0> foo() { return Opaque<0>(); }
footest3::Base109     template <int n> Opaque<1> foo() { return Opaque<1>(); }
110   };
111 
112   struct Derived1 : Base {
113     using Base::foo;
footest3::Derived1114     template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
115   };
116 
117   struct Derived2 : Base {
footest3::Derived2118     template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
119     using Base::foo;
120   };
121 
122   struct Derived3 : Base {
123     using Base::foo;
footest3::Derived3124     template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
125   };
126 
127   struct Derived4 : Base {
footest3::Derived4128     template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
129     using Base::foo;
130   };
131 
test()132   void test() {
133     expect<0>(Base().foo<int>());
134     expect<1>(Base().foo<0>());
135     expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
136     expect<2>(Derived1().foo<0>());
137     expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
138     expect<2>(Derived2().foo<0>());
139     expect<3>(Derived3().foo<int>());
140     expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
141     expect<3>(Derived4().foo<int>());
142     expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
143   }
144 }
145 
146 // PR7384: access control for member templates.
147 namespace test4 {
148   class Base {
149   protected:
150     template<typename T> void foo(T);
151     template<typename T> void bar(T); // expected-note {{declared protected here}}
152   };
153 
154   struct Derived : Base {
155     using Base::foo;
156   };
157 
test()158   void test() {
159     Derived d;
160     d.foo<int>(3);
161     d.bar<int>(3); // expected-error {{'bar' is a protected member}}
162   }
163 }
164