diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-22 00:24:47 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-22 00:24:47 +0000 |
commit | d80b2d57cf24fb80c8ecc40b32ca10fdbeae0c85 (patch) | |
tree | 57f99c982707c8bbd59ffb8ec9634ea998f22abe /clang/test | |
parent | 56cb16dd927fa9304aa5b4474aa1d23ea8acc5c0 (diff) | |
download | bcm5719-llvm-d80b2d57cf24fb80c8ecc40b32ca10fdbeae0c85.tar.gz bcm5719-llvm-d80b2d57cf24fb80c8ecc40b32ca10fdbeae0c85.zip |
Fix CXXRecordDecl::forallBases to not look through bases which are dependent
and defined within the current instantiation, but which are not part of the
current instantiation. Previously, it would look at bases which could be
specialized separately from the current template.
llvm-svn: 168477
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CXX/class.derived/class.virtual/p3-0x.cpp | 30 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.res/temp.dep/p3.cpp | 38 |
2 files changed, 67 insertions, 1 deletions
diff --git a/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp b/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp index 16f98280ed8..6a02a867318 100644 --- a/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp +++ b/clang/test/CXX/class.derived/class.virtual/p3-0x.cpp @@ -100,3 +100,33 @@ namespace PR13499 { Y<X> y; Z<X> z; // expected-note {{in instantiation of}} } + +namespace MemberOfUnknownSpecialization { + template<typename T> struct A { + struct B {}; + struct C : B { + void f() override; + }; + }; + + template<> struct A<int>::B { + virtual void f(); + }; + // ok + A<int>::C c1; + + template<> struct A<char>::B { + void f(); + }; + // expected-error@-13 {{only virtual member functions can be marked 'override'}} + // expected-note@+1 {{in instantiation of}} + A<char>::C c2; + + template<> struct A<double>::B { + virtual void f() final; + }; + // expected-error@-20 {{declaration of 'f' overrides a 'final' function}} + // expected-note@-3 {{here}} + // expected-note@+1 {{in instantiation of}} + A<double>::C c3; +} diff --git a/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp b/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp index 88b4752e6b7..576e310985c 100644 --- a/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp +++ b/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp @@ -1,5 +1,4 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -// expected-no-diagnostics struct A0 { struct K { }; }; @@ -42,3 +41,40 @@ namespace E2 { Y<A> ya; } + +namespace PR14402 { + template<typename T> + struct A { + typedef int n; + int f(); + + struct B {}; + struct C : B { + // OK, can't be sure whether we derive from A yet. + using A::n; + int g() { return f(); } + }; + + struct D { + using A::n; // expected-error {{using declaration refers into 'A<T>::', which is not a base class of 'D'}} + int g() { return f(); } // expected-error {{call to non-static member function 'f' of 'A' from nested type 'D'}} + }; + + struct E { char &f(); }; + struct F : E { + // FIXME: Reject this prior to instantiation; f() is known to return int. + char &g() { return f(); } + // expected-error@-1 {{'PR14402::A<int>::f' is not a member of class 'PR14402::A<int>::F'}} + // expected-error@-2 {{non-const lvalue reference to type 'char' cannot bind to a temporary of type 'int'}} + }; + }; + + template<> struct A<int>::B : A<int> {}; + A<int>::C::n n = A<int>::C().g(); + + // 'not a member' + char &r = A<int>::F().g(); // expected-note {{in instantiation of}} + template<> struct A<char>::E : A<char> {}; + // 'cannot bind to a temporary' + char &s = A<char>::F().g(); // expected-note {{in instantiation of}} +} |