Clang Project

clang_source_code/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
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
11template <unsigned n> struct Opaque {};
12template <unsigned n> void expect(Opaque<n> _) {}
13
14// PR5727
15// This just shouldn't crash.
16namespace test0 {
17  template<typename> struct RefPtr { };
18  template<typename> struct PtrHash {
19    static void f() { }
20  };
21  template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
22    using PtrHash<T*>::f;
23    static void f() { f(); }
24  };
25}
26
27// Simple hiding.
28namespace 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
41    void test0() { Opaque<0> _ = foo(Opaque<0>()); }
42    void test1() { Opaque<1> _ = foo(Opaque<1>()); }
43    void test2() { Opaque<0> _ = foo(Opaque<2>()); }
44    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
53    void test0() { Opaque<0> _ = foo(Opaque<0>()); }
54    void test1() { Opaque<1> _ = foo(Opaque<1>()); }
55    void test2() { Opaque<0> _ = foo(Opaque<2>()); }
56    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
66    void test0() { Opaque<1> _ = foo(Opaque<0>()); }
67    void test1() { Opaque<0> _ = foo(Opaque<1>()); }
68    void test2() { Opaque<1> _ = foo(Opaque<2>()); }
69    void test3() { Opaque<1> _ = foo(Opaque<3>()); }
70  };
71}
72
73// Crazy dependent hiding.
74namespace 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
83    void testUnresolved(int i) { foo(i); }
84  };
85
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
97    void testUnresolved(int i) { foo(i); }
98  };
99
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.
108namespace test3 {
109  struct Base {
110    template <class T> Opaque<0> foo() { return Opaque<0>(); }
111    template <int n> Opaque<1> foo() { return Opaque<1>(); }
112  };
113
114  struct Derived1 : Base {
115    using Base::foo;
116    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 {
120    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;
126    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 {
130    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
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.
149namespace 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
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
167namespace 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  };
176  void f(Derived d) {
177    d = d;
178  }
179}
180
181#if __cplusplus >= 201103L
182namespace 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  };
191  void f(Derived d) {
192    d = Derived();
193  }
194}
195#endif
196