Make sure to use RequireCompleteType rather than testing for
incomplete types. RequireCompleteType is needed when the type may be
completed by instantiating a template.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67643 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/function.c b/test/Sema/function.c
index c240896..aec76a2 100644
--- a/test/Sema/function.c
+++ b/test/Sema/function.c
@@ -59,4 +59,5 @@
   register void f2register(int); // expected-error{{illegal storage class on function}}
 }
 
-struct incomplete_test a(void) {} // expected-error{{result type for function definition cannot be incomplete}}
+struct incomplete_test a(void) {} // expected-error{{incomplete result type 'struct incomplete_test' in function definition}} \
+    // expected-note{{forward declaration of 'struct incomplete_test'}}
diff --git a/test/Sema/typecheck-binop.c b/test/Sema/typecheck-binop.c
index 496bdd3..f5bdcbb 100644
--- a/test/Sema/typecheck-binop.c
+++ b/test/Sema/typecheck-binop.c
@@ -1,6 +1,6 @@
 /* RUN: clang-cc %s -fsyntax-only -pedantic -verify
  */
-struct incomplete;
+struct incomplete; // expected-note{{forward declaration of 'struct incomplete'}}
 
 int sub1(int *a, double *b) { 
   return a - b;    /* expected-error{{not pointers to compatible types}} */
@@ -18,6 +18,10 @@
   return P-Q;      /* expected-warning{{GNU void* extension}} */
 }
 
+int sub5(void *P, int *Q) {
+  return P-Q;      /* expected-error{{not pointers to compatible types}} */
+}
+
 int logicaland1(int a) {
   return a && (void)a; /* expected-error{{invalid operands}} */
 }
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index daee255..11993a1 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -80,7 +80,7 @@
   void (HasMembers::*pmd)() = &HasMembers::d;
 }
 
-struct Incomplete;
+struct Incomplete; // expected-note{{forward declaration}}
 
 void h() {
   HasMembers hm, *phm = &hm;
@@ -110,12 +110,12 @@
   (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct F'}}
   (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct F *'}}
 
-  (void)(hm.*i); // expected-error {{right hand operand to .* must be a pointer to member of a complete class but is 'int'}}
-  (void)(phm->*i); // expected-error {{right hand operand to ->* must be a pointer to member of a complete class but is 'int'}}
+  (void)(hm.*i); // expected-error {{pointer-to-member}}
+  (void)(phm->*i); // expected-error {{pointer-to-member}}
 
   Incomplete *inc;
   int Incomplete::*pii = 0;
-  (void)inc->*pii; // expected-error {{right hand operand to ->* must be a pointer to member of a complete class but is 'int struct Incomplete::*'}}
+  (void)inc->*pii; // expected-error {{right hand operand is a pointer to member of incomplete type 'struct Incomplete'}}
 }
 
 struct OverloadsPtrMem
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 5037a8d..6fbf2c1 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -41,6 +41,10 @@
   //V *pv = new (ps) V;
 }
 
+struct abstract {
+  virtual ~abstract() = 0;
+};
+
 void bad_news(int *ip)
 {
   int i = 1;
@@ -66,7 +70,6 @@
   (void)::new ((S*)0) U; // expected-error {{no matching function for call to 'operator new'}}
   (void)new (int[]); // expected-error {{array size must be specified in new expressions}}
   (void)new int&; // expected-error {{cannot allocate reference type 'int &' with new}}
-  (void)new (void ()); // expected-error {{cannot allocate function type 'void (void)' with new}}
   // Some lacking cases due to lack of sema support.
 }
 
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
new file mode 100644
index 0000000..7b43735
--- /dev/null
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -0,0 +1,47 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// Tests various places where requiring a complete type involves
+// instantiation of that type.
+
+template<typename T>
+struct X {
+  X(T);
+
+  T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
+       // expected-error{{data member instantiated with function type 'int (int)'}} \
+       // expected-error{{data member instantiated with function type 'char (char)'}} \
+       // expected-error{{data member instantiated with function type 'short (short)'}} \
+       // expected-error{{data member instantiated with function type 'float (float)'}} \
+       // expected-error{{data member instantiated with function type 'long (long)'}}
+};
+
+X<int> f() { return 0; }
+
+struct XField {
+  X<float(int)> xf; // expected-note{{in instantiation of template class 'struct X<float (int)>' requested here}}
+};
+
+void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
+  (void)ptr1[i];
+  (void)ptr2[i]; // expected-note{{in instantiation of template class 'struct X<int (int)>' requested here}}
+}
+
+void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
+                X<char(char)> *ptr3, X<short(short)> *ptr4) {
+  (void)(ptr1 + 5);
+  // FIXME: if I drop the ')' after void, below, it still parses (!)
+  (void)(5 + ptr2);
+  (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'struct X<char (char)>' requested here}}
+  (void)(5 + ptr4); // expected-note{{in instantiation of template class 'struct X<short (short)>' requested here}}
+}
+
+void test_new() {
+  (void)new X<float>(0);
+  (void)new X<float(float)>; // expected-note{{in instantiation of template class 'struct X<float (float)>' requested here}}
+}
+
+void test_memptr(X<long> *p1, long X<long>::*pm1,
+                 X<long(long)> *p2, long (X<long(long)>::*pm2)(long)) {
+  (void)(p1->*pm1);
+  (void)(p2->*pm2); // expected-note{{in instantiation of template class 'struct X<long (long)>' requested here}}
+}