Fix rdar://6821047 - clang crashes on subscript of interface in 64-bit mode

Several changes here:
1. We change Type::isIncompleteType to realize that forward declared 
   interfaces are incomplete.  This eliminate special case code for this
   from the sizeof path, and starts us rejecting P[4] when P is a pointer
   to an incomplete interface.
2. Explicitly reject P[4] when P points to an interface in non-fragile ABI
   mode.
3. Switch the sizeof(interface) diagnostic back to an error instead of a 
   warning in non-fragile abi mode.




git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69943 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 89f834c..edf769b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1231,37 +1231,33 @@
 
   // C99 6.5.3.4p1:
   if (isa<FunctionType>(exprType)) {
-    // alignof(function) is allowed.
+    // alignof(function) is allowed as an extension.
     if (isSizeof)
       Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange;
     return false;
   }
   
+  // Allow sizeof(void)/alignof(void) as an extension.
   if (exprType->isVoidType()) {
     Diag(OpLoc, diag::ext_sizeof_void_type)
       << (isSizeof ? "sizeof" : "__alignof") << ExprRange;
     return false;
   }
   
-  // sizeof(interface) and sizeof(interface<proto>)
-  if (const ObjCInterfaceType *IIT = exprType->getAsObjCInterfaceType()) {
-    if (IIT->getDecl()->isForwardDecl()) {
-      Diag(OpLoc, diag::err_sizeof_forward_interface)
-        << IIT->getDecl()->getDeclName() << isSizeof;
-      return true;
-    }
-
-    if (LangOpts.ObjCNonFragileABI) {
-      Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
-        << IIT->getDecl()->getDeclName() << isSizeof;
-      //return false;
-    }
+  if (RequireCompleteType(OpLoc, exprType,
+                          isSizeof ? diag::err_sizeof_incomplete_type : 
+                          diag::err_alignof_incomplete_type,
+                          ExprRange))
+    return true;
+  
+  // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
+  if (exprType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    Diag(OpLoc, diag::err_sizeof_nonfragile_interface)
+      << exprType << isSizeof;
+    return true;
   }
     
-  return RequireCompleteType(OpLoc, exprType,
-                                isSizeof ? diag::err_sizeof_incomplete_type : 
-                                           diag::err_alignof_incomplete_type,
-                                ExprRange);
+  return false;
 }
 
 bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
@@ -1651,12 +1647,19 @@
       << ResultType << BaseExpr->getSourceRange();
     return ExprError();
   }
+  
   if (!ResultType->isDependentType() &&
-      RequireCompleteType(BaseExpr->getLocStart(), ResultType, 
-                          diag::err_subscript_incomplete_type,
+      RequireCompleteType(LLoc, ResultType, diag::err_subscript_incomplete_type,
                           BaseExpr->getSourceRange()))
     return ExprError();
-
+  
+  // Diagnose bad cases where we step over interface counts.
+  if (ResultType->isObjCInterfaceType() && LangOpts.ObjCNonFragileABI) {
+    Diag(LLoc, diag::err_subscript_nonfragile_interface)
+      << ResultType << BaseExpr->getSourceRange();
+    return ExprError();
+  }
+  
   Base.release();
   Idx.release();
   return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,