Unify the end-of-class code paths used by the parser and template
instantiation, to ensure that we mark class template specilizations as
abstract when we need to and perform checking of abstract classes.

Also, move the checking that determines whether we are creating a
variable of abstract class type *after* we check whether the type is
complete. Otherwise, we won't see when we have an abstract class
template specialization that is implicitly instantiated by this
declaration. This is the "something else" that Sebastian had noted
earlier.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90467 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index cee6456..c18a77f 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -1,5 +1,4 @@
 // RUN: clang-cc -fsyntax-only -faccess-control -verify %s
-
 namespace T1 {
 
 class A {
@@ -122,8 +121,8 @@
 struct Base2 { };
 
 void test() {
-  Foo<Base1> f1;
-  Foo<Base2> f2; // expected-note{{instantiation}}
+  (void)sizeof(Foo<Base1>);
+  (void)sizeof(Foo<Base2>); // expected-note{{instantiation}}
 }
 
 template<typename Base>
@@ -137,3 +136,17 @@
   f1.f(17);
   f2.f(17);
 };
+
+struct Foo3 {
+  virtual void f(int) = 0; // expected-note{{pure virtual function}}
+};
+
+template<typename T>
+struct Bar3 : Foo3 {
+  void f(T);
+};
+
+void test3() {
+  Bar3<int> b3i; // okay
+  Bar3<float> b3f; // expected-error{{is an abstract class}}
+}