Home | History | Annotate | Download | only in namespace.udecl
      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 {};
     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 {
     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.
     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 
     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.
     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 
     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.
    108 namespace 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.
    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 
    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   };
    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   };
    191   void f(Derived d) {
    192     d = Derived();
    193   }
    194 }
    195 #endif
    196