Diagnose the use of incomplete types in C++ typeid expressions

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92045 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index d395673..afb5c54 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -37,7 +37,22 @@
     //   that is the operand of typeid are always ignored.
     // FIXME: Preserve type source info.
     // FIXME: Preserve the type before we stripped the cv-qualifiers?
-    TyOrExpr =GetTypeFromParser(TyOrExpr).getUnqualifiedType().getAsOpaquePtr();
+    QualType T = GetTypeFromParser(TyOrExpr);
+    if (T.isNull())
+      return ExprError();
+    
+    // C++ [expr.typeid]p4:
+    //   If the type of the type-id is a class type or a reference to a class 
+    //   type, the class shall be completely-defined.
+    QualType CheckT = T;
+    if (const ReferenceType *RefType = CheckT->getAs<ReferenceType>())
+      CheckT = RefType->getPointeeType();
+    
+    if (CheckT->getAs<RecordType>() &&
+        RequireCompleteType(OpLoc, CheckT, diag::err_incomplete_typeid))
+      return ExprError();
+    
+    TyOrExpr = T.getUnqualifiedType().getAsOpaquePtr();
   }
 
   IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
@@ -66,7 +81,8 @@
           // C++ [expr.typeid]p3:
           //   [...] If the type of the expression is a class type, the class
           //   shall be completely-defined.
-          // FIXME: implement this!
+          if (RequireCompleteType(OpLoc, T, diag::err_incomplete_typeid))
+            return ExprError();
         }
       }