Home | History | Annotate | Download | only in namespace.udecl
      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 {};
     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 {
     17     static void f() { }
     18   };
     19   template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
     20     using PtrHash<T*>::f;
     21     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 
     39     void test0() { Opaque<0> _ = foo(Opaque<0>()); }
     40     void test1() { Opaque<1> _ = foo(Opaque<1>()); }
     41     void test2() { Opaque<0> _ = foo(Opaque<2>()); }
     42     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 
     51     void test0() { Opaque<0> _ = foo(Opaque<0>()); }
     52     void test1() { Opaque<1> _ = foo(Opaque<1>()); }
     53     void test2() { Opaque<0> _ = foo(Opaque<2>()); }
     54     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 
     64     void test0() { Opaque<1> _ = foo(Opaque<0>()); }
     65     void test1() { Opaque<0> _ = foo(Opaque<1>()); }
     66     void test2() { Opaque<1> _ = foo(Opaque<2>()); }
     67     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 
     81     void testUnresolved(int i) { foo(i); }
     82   };
     83 
     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 
     95     void testUnresolved(int i) { foo(i); }
     96   };
     97 
     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 {
    108     template <class T> Opaque<0> foo() { return Opaque<0>(); }
    109     template <int n> Opaque<1> foo() { return Opaque<1>(); }
    110   };
    111 
    112   struct Derived1 : Base {
    113     using Base::foo;
    114     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 {
    118     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;
    124     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 {
    128     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 
    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 
    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