diff options
author | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
---|---|---|
committer | Zancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au> | 2012-09-24 09:58:17 +1000 |
commit | 222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch) | |
tree | 7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp | |
parent | 3d206f03985b50beacae843d880bccdc91a9f424 (diff) |
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp')
-rw-r--r-- | clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp new file mode 100644 index 0000000..cc28bf6 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp @@ -0,0 +1,163 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// C++03 [namespace.udecl]p12: +// When a using-declaration brings names from a base class into a +// derived class scope, member functions in the derived class +// override and/or hide member functions with the same name and +// parameter types in a base class (rather than conflicting). + +template <unsigned n> struct Opaque {}; +template <unsigned n> void expect(Opaque<n> _) {} + +// PR5727 +// This just shouldn't crash. +namespace test0 { + template<typename> struct RefPtr { }; + template<typename> struct PtrHash { + static void f() { } + }; + template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> { + using PtrHash<T*>::f; + static void f() { f(); } + }; +} + +// Simple hiding. +namespace test1 { + struct Base { + Opaque<0> foo(Opaque<0>); + Opaque<0> foo(Opaque<1>); + Opaque<0> foo(Opaque<2>); + }; + + // using before decls + struct Test0 : Base { + using Base::foo; + Opaque<1> foo(Opaque<1>); + Opaque<1> foo(Opaque<3>); + + void test0() { Opaque<0> _ = foo(Opaque<0>()); } + void test1() { Opaque<1> _ = foo(Opaque<1>()); } + void test2() { Opaque<0> _ = foo(Opaque<2>()); } + void test3() { Opaque<1> _ = foo(Opaque<3>()); } + }; + + // using after decls + struct Test1 : Base { + Opaque<1> foo(Opaque<1>); + Opaque<1> foo(Opaque<3>); + using Base::foo; + + void test0() { Opaque<0> _ = foo(Opaque<0>()); } + void test1() { Opaque<1> _ = foo(Opaque<1>()); } + void test2() { Opaque<0> _ = foo(Opaque<2>()); } + void test3() { Opaque<1> _ = foo(Opaque<3>()); } + }; + + // using between decls + struct Test2 : Base { + Opaque<1> foo(Opaque<0>); + using Base::foo; + Opaque<1> foo(Opaque<2>); + Opaque<1> foo(Opaque<3>); + + void test0() { Opaque<1> _ = foo(Opaque<0>()); } + void test1() { Opaque<0> _ = foo(Opaque<1>()); } + void test2() { Opaque<1> _ = foo(Opaque<2>()); } + void test3() { Opaque<1> _ = foo(Opaque<3>()); } + }; +} + +// Crazy dependent hiding. +namespace test2 { + struct Base { + void foo(int); + }; + + template <typename T> struct Derived1 : Base { + using Base::foo; + void foo(T); + + void testUnresolved(int i) { foo(i); } + }; + + void test0(int i) { + Derived1<int> d1; + d1.foo(i); + d1.testUnresolved(i); + } + + // Same thing, except with the order of members reversed. + template <typename T> struct Derived2 : Base { + void foo(T); + using Base::foo; + + void testUnresolved(int i) { foo(i); } + }; + + void test1(int i) { + Derived2<int> d2; + d2.foo(i); + d2.testUnresolved(i); + } +} + +// Hiding of member templates. +namespace test3 { + struct Base { + template <class T> Opaque<0> foo() { return Opaque<0>(); } + template <int n> Opaque<1> foo() { return Opaque<1>(); } + }; + + struct Derived1 : Base { + using Base::foo; + template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} + }; + + struct Derived2 : Base { + template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}} + using Base::foo; + }; + + struct Derived3 : Base { + using Base::foo; + template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} + }; + + struct Derived4 : Base { + template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}} + using Base::foo; + }; + + void test() { + expect<0>(Base().foo<int>()); + expect<1>(Base().foo<0>()); + expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} + expect<2>(Derived1().foo<0>()); + expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} + expect<2>(Derived2().foo<0>()); + expect<3>(Derived3().foo<int>()); + expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + expect<3>(Derived4().foo<int>()); + expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + } +} + +// PR7384: access control for member templates. +namespace test4 { + class Base { + protected: + template<typename T> void foo(T); + template<typename T> void bar(T); // expected-note {{declared protected here}} + }; + + struct Derived : Base { + using Base::foo; + }; + + void test() { + Derived d; + d.foo<int>(3); + d.bar<int>(3); // expected-error {{'bar' is a protected member}} + } +} |